Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# nightly-moon-phase-emoji\n\nA tiny TypeScript command‑line utility that tells you the lunar phase for any date and displays it as a moon‑phase emoji.\n\n## Features\n\n- Accepts an optional ISO‑8601 date argument (defaults to today)\n- Uses a simple astronomical approximation that is accurate enough for casual use\n- Outputs one of eight emojis: 🌑 🌒 🌓 🌔 🌕 🌖 🌗 🌘\n- Zero‑dependency, runs with `ts-node` or after compilation with `node`\n\n## Installation\n\n```bash\n# Clone the repo (or copy the folder into your project)\ngit clone https://github.com/polsala/ApocalypsAI.git\ncd utils/typescript-utils/nightly-moon-phase-emoji\n\n# Install TypeScript and ts-node globally if you don\'t have them\nnpm install -g typescript ts-node\n```\n\n## Usage\n\n```bash\n# Run directly with ts-node\nts-node src/main.ts # uses today\nts-node src/main.ts 2023-01-21 # specific date\n\n# Or compile and run\ntsc\nnode dist/main.js 2023-01-21\n```\n\nThe program prints only the emoji (and a newline).\n\n## Example\n\n```bash\n$ ts-node src/main.ts 2023-01-21\n🌕\n```\n\n## Testing\n\n```bash\nnpm install\nnpm test\n```\n\nThe test suite checks a handful of known dates against their expected emojis.\n
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import { exit } from "process";\n\n/**\n * Compute the moon phase for a given Date and return an index 0‑7.\n * 0 = New Moon, 1 = Waxing Crescent, 2 = First Quarter, 3 = Waxing Gibbous,\n * 4 = Full Moon, 5 = Waning Gibbous, 6 = Last Quarter, 7 = Waning Crescent\n */\nexport function moonPhaseIndex(date: Date): number {\n // Reference new moon: 2000‑01‑06 18:14 UTC (Julian Day 2451549.26042)\n const knownNewMoon = new Date(Date.UTC(2000, 0, 6, 18, 14, 0));\n const msPerDay = 1000 * 60 * 60 * 24;\n const daysSince = (date.getTime() - knownNewMoon.getTime()) / msPerDay;\n const synodicMonth = 29.530588853; // average length of lunar cycle in days\n const lunations = daysSince / synodicMonth;\n const phase = lunations - Math.floor(lunations); // fractional part [0,1)\n // Convert to 0‑7 index\n const index = Math.round(phase * 8) % 8;\n return index;\n}\n\nconst emojiMap = [\n "🌑", // New Moon\n "🌒", // Waxing Crescent\n "🌓", // First Quarter\n "🌔", // Waxing Gibbous\n "🌕", // Full Moon\n "🌖", // Waning Gibbous\n "🌗", // Last Quarter\n "🌘" // Waning Crescent\n];\n\n/**\n * Return the emoji for a given Date.\n */\nexport function getMoonPhaseEmoji(date: Date): string {\n const idx = moonPhaseIndex(date);\n return emojiMap[idx];\n}\n\n// ---------- CLI ----------\nfunction parseDateArg(arg?: string): Date {\n if (!arg) {\n return new Date(); // today\n }\n const parsed = new Date(arg);\n if (isNaN(parsed.getTime())) {\n console.error(`Invalid date: ${arg}`);\n exit(1);\n }\n return parsed;\n}\n\nif (require.main === module) {\n const dateArg = process.argv[2];\n const date = parseDateArg(dateArg);\n const emoji = getMoonPhaseEmoji(date);\n console.log(emoji);\n}\n
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import { strict as assert } from "assert";\nimport { getMoonPhaseEmoji } from "../src/main";\n\n// Mock rationale: using fixed dates that are known moon phases (UTC)\nconst testCases: Array<{date: string; expected: string}> = [\n { date: "2023-01-06", expected: "🌑" }, // New Moon\n { date: "2023-01-13", expected: "🌓" }, // First Quarter\n { date: "2023-01-21", expected: "🌕" }, // Full Moon\n { date: "2023-01-28", expected: "🌗" } // Last Quarter\n];\n\nfor (const {date, expected} of testCases) {\n const d = new Date(date + "T00:00:00Z");\n const emoji = getMoonPhaseEmoji(d);\n assert.equal(emoji, expected, `Moon phase for ${date} should be ${expected}`);\n}\n\nconsole.log("All moon‑phase tests passed.");\n
Loading