学习前提
理解JavaScript数值、字符串和对象;了解本地时间与UTC的基本区别。
本课完成后你能做什么
区分时间点与日历日期,避免把显示格式当成可计算数据。
先理解机制
Date表示一个时间点,内部以距纪元的毫秒数表达;显示出的年月日受时区影响。同一时间点在上海与纽约可能属于不同日期。预约的具体时刻、生日这种日历日期、每天早上9点这种重复规则,是不同数据模型,不能全部塞成含糊的字符串。
交换时间点时使用明确包含偏移或Z的格式。不要依赖浏览器解析任意地区写法,例如03/04/2026到底是几月几日并不适合猜。纯日期YYYY-MM-DD与本地年月日构造也有不同解析语义;计算前先写清楚业务需要的是哪一种。
Intl.DateTimeFormat负责面向用户的格式化,可以显式指定locale与timeZone。toISOString适合规范化输出时间点,不代表用户当地时间。展示格式可以改变,底层值应保持不变,不能先格式化再重新解析来做比较。
两个时间戳相减可以得到经过的毫秒,但“明天同一当地时间”不总等于增加24小时,夏令时等规则可能影响间隔。Invalid Date也需要验证,getTime得到NaN时不能继续计算。示例只展示固定时间点,不实现复杂预约规则。
可运行示例
运行方式:在独立练习网页的开发者工具Console中运行JavaScript;不要在含有重要表单的页面练习。修改输入后重新运行完整示例。
const instant = new Date('2026-01-01T00:30:00Z');
if (!Number.isFinite(instant.getTime())) throw new Error('Invalid date');
for (const zone of ['Asia/Shanghai', 'America/New_York']) {
const format = new Intl.DateTimeFormat('en-GB', {
timeZone: zone, dateStyle: 'medium', timeStyle: 'short'
});
console.log(zone, format.format(instant));
}
console.log('Stored instant:', instant.toISOString());
console.log('Elapsed hours:', (new Date('2026-01-01T02:30:00Z') - instant) / 3600000);
推演与验证
预期上海是2026年1月1日08:30,纽约是2025年12月31日19:30,具体标点由格式器决定;经过时间为2小时。将locale改成zh-CN,观察显示改变但toISOString不变。把输入改成无效文字并验证错误路径。
常见错误与边界
月份数字在某些Date构造器中从0开始,用户界面月份从1开始;不要在转换中漏减或重复减1。前端时钟由用户设备控制,不能作为服务端权限过期判断的唯一依据。
动手练习
为课程发布日期提供中文和英文显示,输入始终保存完整UTC时间点;无效值显示“日期待确认”,不要显示Invalid Date。
参考解法与理由
先构造Date并检查getTime,再创建明确时区的格式器。大量记录可复用同一个格式器。失败回退属于显示层,不能偷偷把错误日期替换为今天。