JavaScript 中的日期和时间处理:高级水平

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

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

开始课程

引言

\n

日期和时间处理是 Web 开发中最常见但也最棘手的任务之一。JavaScript 中的标准 Date 对象虽然通用,但存在一些限制:缺乏对时区的内置支持(除了 UTC 和本地时间)、格式化方法不便以及计算日期差异复杂。在本文中,我们将探讨在 Node.js 环境中处理日期的高级技巧,帮助您编写可靠且清晰的代码。

\n\n

1. Intl.DateTimeFormat:无需第三方库的强大格式化功能

\n

现代 JavaScript 提供了内置的 Intl.DateTimeFormat API,它允许您根据区域设置灵活地格式化日期和时间。如果您不需要第三方库的全部功能,这是一个理想的工具。

\n\n

基本用法

\n

创建一个格式化器实例,传入区域设置和包含选项的对象:

\n
const date = new Date('2024-12-25T10:30:00Z');\n\n// 为俄语区域设置进行格式化\nconst ruFormatter = 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\nconsole.log(ruFormatter.format(date));\n// 输出:"среда, 25 декабря 2024 г. в 13:30"
\n\n

处理时区

\n

Intl.DateTimeFormat 的关键优势在于通过 timeZone 选项支持时区。您可以在不同时区显示同一日期:

\n
const date = new Date();\n\nconst formatters = {\n  '纽约': new Intl.DateTimeFormat('en-US', { timeZone: 'America/New_York', dateStyle: 'full', timeStyle: 'long' }),\n  '东京': new Intl.DateTimeFormat('ja-JP', { timeZone: 'Asia/Tokyo', dateStyle: 'full', timeStyle: 'long' }),\n  '伦敦': new Intl.DateTimeFormat('en-GB', { timeZone: 'Europe/London', dateStyle: 'full', timeStyle: 'long' })\n};\n\nfor (const [city, fmt] of Object.entries(formatters)) {\n  console.log(`${city}: ${fmt.format(date)}`);\n}
\n\n

格式化日期范围

\n

该 API 还可以使用 formatRange 方法格式化日期范围:

\n
const start = new Date('2024-01-01');\nconst end = new Date('2024-01-05');\n\nconst rangeFormatter = new Intl.DateTimeFormat('ru-RU', {\n  month: 'long',\n  day: 'numeric'\n});\n\nconsole.log(rangeFormatter.formatRange(start, end));\n// 输出:"1–5 января"
\n\n

2. 日期操作:加法、减法和差异计算

\n

标准的 Date 对象不太适合算术运算。我们来看两种方法:纯 JavaScript 和流行的库。

\n\n

纯 JavaScript:使用毫秒数

\n

最简单的方法是将日期转换为 Unix 时间戳(自 1970 年 1 月 1 日以来的毫秒数)并执行操作:

\n
function addDays(date, days) {\n  const result = new Date(date);\n  result.setTime(result.getTime() + days * 24 * 60 * 60 * 1000);\n  return result;\n}\n\nfunction diffDays(date1, date2) {\n  const msDiff = Math.abs(date2.getTime() - date1.getTime());\n  return Math.floor(msDiff / (1000 * 60 * 60 * 24));\n}\n\nconst today = new Date('2024-10-01');\nconst future = addDays(today, 30);\nconsole.log(future); // 2024-10-31\nconsole.log(diffDays(today, future)); // 30
\n

缺点:未考虑夏令时、闰秒和不同月份的长度。

\n\n

date-fns 库:函数式且轻量级的方法

\n

date-fns 是一个模块化库,每个函数都是一个独立的模块。这有助于避免包体积膨胀:

\n
// 安装:npm install date-fns\nconst { addDays, subMonths, differenceInDays, format } = require('date-fns');\nconst { ru } = require('date-fns/locale');\n\nconst startDate = new Date(2024, 0, 15); // 2024 年 1 月 15 日\n\nconst plusWeek = addDays(startDa                

博客

书籍推荐