TypeScript 中日期与时间的高级操作:方法与示例

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

TypeScript 中日期与时间的高级操作:从类型化到复杂运算

\n\n

处理日期和时间是 Web 开发中最常见也最棘手的任务之一。在高级层面,简单地使用 new Date() 已经不够了。TypeScript 提供了强大的类型系统,而现代库(Luxon、Date-fns)则允许编写安全、可预测且高性能的代码。本文将深入探讨高级技术:严格类型化、时区处理、复杂格式化与解析,以及创建自定义工具函数。

\n\n

1. 日期的严格类型化:自定义类型与 Branded Types

\n\n

TypeScript 中的 Date 类型无法防止传入无效值。例如,一个期望接收出生日期的函数可能接收到当前时间戳。解决方案是使用 Branded Types(品牌类型)或 Nominal Typing(名义类型化)。

\n\n
// 出生日期的 Branded Type\ntype BirthDate = Date & { __brand: 'BirthDate' };\n\nfunction createBirthDate(date: Date): BirthDate {\n  // 验证:日期不能是未来的\n  if (date.getTime() > Date.now()) {\n    throw new Error('出生日期不能是未来的');\n  }\n  return date as BirthDate;\n}\n\nfunction calculateAge(birthDate: BirthDate): number {\n  const diff = Date.now() - birthDate.getTime();\n  return Math.floor(diff / (1000 * 60 * 60 * 24 * 365.25));\n}\n\n// 使用\nconst rawDate = new Date('1990-05-15');\nconst birth = createBirthDate(rawDate);\nconsole.log(calculateAge(birth)); // 正常\n\n// 错误:类型 'Date' 的参数不能赋值给类型 'BirthDate' 的参数\n// console.log(calculateAge(new Date())); \n
\n\n

这种方法确保只有经过验证的出生日期才能传入 calculateAge 函数。对于更复杂的场景,可以创建时间戳(UnixTimestamp)、时间间隔(TimeInterval)等类型。

\n\n

2. 使用 Intl.DateTimeFormat 进行高级格式化与解析

\n\n

内置的 Intl.DateTimeFormat 对象允许在不使用第三方库的情况下灵活格式化日期。在高级层面,我们可以创建可复用的格式化器并处理复杂的区域设置。

\n\n
// 创建带选项的格式化器\nconst formatter = new Intl.DateTimeFormat('ru-RU', {\n  year: 'numeric',\n  month: 'long',\n  day: 'numeric',\n  weekday: 'long',\n  hour: '2-digit',\n  minute: '2-digit',\n  timeZone: 'Europe/Moscow',\n});\n\n// 格式化\nconsole.log(formatter.format(new Date())); \n// "пятница, 25 октября 2024 г., 14:30"\n\n// 解析(自定义工具函数)\nfunction parseLocalizedDate(dateStr: string, locale: string): Date | null {\n  const parts = dateStr.match(/(\\d{4})-(\\d{2})-(\\d{2})/);\n  if (!parts) return null;\n  \n  const [, year, month, day] = parts;\n  return new Date(parseInt(year), parseInt(month) - 1, parseInt(day));\n}\n
\n\n

提示: 为了性能,请一次性创建格式化器并重复使用。避免每次调用都创建新实例。

\n\n

3. 处理时区与 Luxon 库

\n\n

内置的 Date 在处理时区方面表现不佳。Luxon 是一个来自 Moment.js 创建者的现代库,与 TypeScript 完美集成。

\n\n
import { DateTime, Settings } from 'luxon';\n\n// 设置默认时区\nSettings.defaultZone = 'Europe/Moscow';\n\n// 显式指定时区创建日期\nconst meeting = DateTime.fromISO('2024-11-01T15:00:00', { zone: 'America/New_York' });\nconsole.log(meeting.toISO()); // 2024-11-01T15:00:00.000-04:00\n\n// 转换为其他时区\nconst moscowTime = meeting.setZone('Europe/Moscow');\nconsole.log(moscowTime.toFormat('dd.MM.yyyy HH:mm')); // 01.11.2024 22:00\n\n// 处理时间间隔\nconst start = DateTi                

博客

书籍推荐