freeCodeCamp 每日编程挑战解析:Challenge 239 What Day Is It——毫秒级 Unix 时间戳到星期的转换

freeCodeCamp 每日编程挑战解析:Challenge 239 What Day Is It——毫秒级 Unix 时间戳到星期的转换 freeCodeCamp 每日编程挑战解析Challenge 239 What Day Is It——毫秒级 Unix 时间戳到星期的转换【免费下载链接】freeCodeCampfreeCodeCamp.orgs open-source codebase and curriculum. Learn math, programming, and computer science for free.项目地址: https://gitcode.com/GitHub_Trending/fr/freeCodeCamp本文以 freeCodeCamp 开源仓库 daily-coding-challenges-javascript 板块 中的第 239 题 What Day Is It? 为核心完整解析题目约束、五组验收测试用例、官方解法原理并沿源码线索揭示这类每日编程挑战在 freeCodeCamp 中的存储结构、JS/Python 双语言校验机制与配套 API。读完你将掌握忽略时区的日期格式化技巧也能看懂一道 DCCDaily Coding Challenge题目从 Markdown 到在线判题的全链路。挑战概览任务陈述与验收标准挑战的原始描述非常精简见 69b559d2903b9e4afe9075f9.md给定一个以毫秒为单位的 Unix 时间戳返回对应的星期几。返回值必须是以下七个字符串之一SundayMondayTuesdayWednesdayThursdayFridaySaturday题目还附加了一条关键约束Be sure to ignore time zones.务必忽略时区。这一句是整个题目的核心陷阱JavaScript 中所有依赖本地时区如getDay()、getHours()的 API 都会导致结果随运行环境所在时区漂移而判题环境与解题环境往往不在同一时区。因此以 UTC 视角解读时间戳是本挑战唯一正确的解题方向。值得注意的是同一道题在仓库中存在 JavaScript 与 Python 两个版本JavaScript 版challengeType: 28Python 版challengeType: 29见 daily-coding-challenges-python/69b559d2903b9e4afe9075f9.md且两者共用同一个挑战 ID69b559d2903b9e4afe9075f9这正是下文将要介绍的双语言配对设计。五组测试用例逐一拆解原文档的--hints--段给出了 5 个assert.equal测试它们不仅是验收标准也覆盖了普通、大数、边界三类输入。下表逐一说明其预期输出与背后的星期计算依据输入时间戳毫秒预期输出说明1775492249000Monday常规近期时间戳1766246400000Saturday常规近期时间戳33791256000000Tuesday远超 32 位整数上限约公元 3040 年考验大数处理1773576000000Sunday常规近期时间戳0ThursdayUnix 纪元起点 1970-01-01本身就是经典边界0号用例是整个题组最有教学价值的用例Unix 纪元Epoch对应 UTC 时间 1970 年 1 月 1 日而那一天恰好是星期四所以任何正确的实现都必须对getDayOfWeek(0)返回Thursday。这也意味着算法实际上是在已知 1970-01-01 为星期四这一基准上进行天数偏移或借助 Date 对象完成同样语义的计算。从种子代码到完整实现原文档的种子代码如下函数体只有一行占位实现function getDayOfWeek(timestamp) { return timestamp; }这个骨架函数直接return timestamp显然无法通过任何测试解题者需要自行填充实现。思路一直接查表计算一种不依赖任何日期 API 的纯数学思路先算出Math.floor(timestamp / 86400000)得到自纪元以来的整天天数一天 24 × 60 × 60 × 1000 8,640,000 毫秒再对 7 取模用[Thursday,Friday,Saturday,Sunday,Monday,Tuesday,Wednesday]查表。该方法天然忽略时区因为时间戳本身就是相对纪元的绝对瞬间与本地时区无关。思路二官方解法Date toLocaleDateString UTC原文档的--solutions--段给出的官方解法如下function getDayOfWeek(timestamp) { return new Date(timestamp).toLocaleDateString(en-US, { weekday: long, timeZone: UTC }); }该实现由三个环节组成new Date(timestamp)将毫秒时间戳构造成 Date 对象。JavaScript 的Date构造器接收的正是毫秒数与题目输入单位完全吻合timeZone: UTC关键选项。它要求格式化时按 UTC即零时区解读日期从而满足忽略时区的硬性约束weekday: long localeen-US输出英文全称星期名Sunday~Saturday与题目要求的七个返回值一一对应无需自行维护映射表。为什么不能用getDay()或本地化 API 裸用date.getDay()返回 0–6 的数字且基于运行环境的本地时区toLocaleDateString若省略timeZone选项同样按本地时区输出。当本地时区落后于 UTC如 UTC-5时靠近午夜的 UTC 时间戳会被翻到前一天导致星期结果错位。官方解法显式传入timeZone: UTC正是为了屏蔽这一不确定因素这也是题目ignore time zones约束在实现层面的落点。另一种等价写法是用Intl.DateTimeFormat(en-US, { weekday: long, timeZone: UTC }).format(new Date(timestamp))或date.toLocaleDateString(en-US, { weekday: long, timeZone: UTC })的getUTCDay()版本配合数组查表三者语义一致均满足判题要求。从题解看 DCC 板块的双语言配对机制这道题并非孤立存在而是 freeCodeCamp每日编程挑战Daily Coding Challenges体系的一环。板块元数据定义在 daily-coding-challenges-javascript.jsonisUpcomingChange: true标记为即将上线的新内容helpCategory: JavaScript归入 JavaScript 帮助分类usesMultifileEditor: true使用多文件编辑器blockLayout: legacy-challenge-list以挑战列表形式组织challengeOrder按 ID 列出从 Challenge 1: Vowel Balance 起的上百道题本文的 Challenge 239 位于其中。挑战类型常量定义在 packages/shared/src/config/challenge-types.ts其中dailyChallengeJs28与dailyChallengePy29被归入dailyCodingChallengeTypes并提供两个工具函数getIsDailyCodingChallenge(challengeType)判断某挑战类型是否为每日编程挑战getDailyCodingChallengeLanguage(challengeType)将类型号映射为javascript或python。该文件还显示dailyChallengeJs与dailyChallengePy都使用tests作为挑战文件的传输键见 challenge-types.ts说明两类题目共用同一套测试即文件的加载通道。JS 与 Python 版本的严格配对由测试保障。在 curriculum/src/test/daily-challenges.test.js 中测试会同时拉取daily-coding-challenges-javascript与daily-coding-challenges-python两个板块并断言两者挑战数量相等、同一顺序下挑战 ID 必须一致、标题与描述必须一致、测试用例数量必须一致。这也解释了为什么两个语言的.md文件共享同一个 ID69b559d2903b9e4afe9075f9——它们本质上是同一道题在不同语言下的双胞胎。判题与访问链路客户端语言切换与 API 路由客户端JS/Python 语言切换在 client/src/templates/Challenges/classic/action-row.tsx 中挑战动作栏会根据isDailyCodingChallenge属性渲染一个语言切换控件将dailyCodingChallengeLanguage在javascript与python之间切换并通过store.set(dailyCodingChallengeLanguage, language)持久化到本地存储。对应测试 action-row.test.tsx 验证了切换到 Python 后存储值同步更新的行为。服务端公开 GET 路由每日编程挑战的题目元数据而非提交判题由 API 侧提供。路由实现在 api/src/daily-coding-challenge/routes/daily-coding-challenge.ts共 6 个公开端点端点用途关键行为/daily-coding-challenge/today获取今日挑战取美国中部时间US Central的 UTC 零点作为基准日期/daily-coding-challenge/date/:date按YYYY-MM-DD获取超过今日US Central的日期返回 404/daily-coding-challenge/day/:day按MM-DD获取不指定年份自动映射到最近的对应日期/daily-coding-challenge/month/:month按YYYY-MM列表获取仅返回不晚于今天的题目按日期倒序/daily-coding-challenge/all获取全部题目摘要仅返回id/challengeNumber/date/title/daily-coding-challenge/newest获取最新一题的日期供客户端判断题库是否更新参数校验由 TypeBox 模式定义在 api/src/daily-coding-challenge/schemas/daily-coding-challenge.ts如day参数须匹配^\d{2}-\d{2}$month参数须匹配^\d{4}-\d{2}$非法格式返回 400。单题响应结构包含id、date、challengeNumber、title、description以及javascript/python两个语言块每个语言块内是tests与challengeFiles数组——即前文提到的tests键的落点。值得一提的还有路由注释Will stop returning challenges if param is after aug 10, 2026 - the last challenge date超过最后一题日期后将不再返回说明题库存在明确的截止日期设计。在本地快速验证与扩展练习本文的解题代码无需任何构建工具即可验证直接在浏览器开发者工具控制台粘贴即可function getDayOfWeek(timestamp) { return new Date(timestamp).toLocaleDateString(en-US, { weekday: long, timeZone: UTC }); } // 逐条对照原文档 hints console.log(getDayOfWeek(1775492249000)); // Monday console.log(getDayOfWeek(1766246400000)); // Saturday console.log(getDayOfWeek(33791256000000)); // Tuesday console.log(getDayOfWeek(1773576000000)); // Sunday console.log(getDayOfWeek(0)); // Thursday作为延伸练习可以尝试在 Node.js 中通过TZAmerica/Los_Angeles node运行同一函数观察结果不变——这正是timeZone: UTC生效的实证再对比去掉该选项后的输出差异即可直观理解忽略时区这一约束的意义。若想深入仓库内部可分别阅读 challenge 的 JS 版本 与其 Python 配对版本对照双语言测试的写法差异进一步掌握 DCC 题目的编写范式。【免费下载链接】freeCodeCampfreeCodeCamp.orgs open-source codebase and curriculum. Learn math, programming, and computer science for free.项目地址: https://gitcode.com/GitHub_Trending/fr/freeCodeCamp创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考