跳到主要内容

JavaScript 日期格式化

介绍

在JavaScript编程中,日期和时间的格式化是一项常见需求。无论是显示用户友好的日期、根据地区设置格式,还是创建自定义日期表示,了解如何格式化日期对于构建用户界面都至关重要。

本教程将介绍JavaScript中格式化日期和时间的各种方法,从内置方法到流行的第三方库,帮助你掌握日期格式化技能。

使用Date对象的内置方法

JavaScript的Date对象提供了几种基本的格式化方法,适合简单场景使用。

基础方法

javascript
const today = new Date();

// 转换为字符串
console.log(today.toString());
// 输出: Wed Jun 01 2023 12:30:45 GMT+0800 (中国标准时间)

// 转换为本地日期字符串
console.log(today.toDateString());
// 输出: Wed Jun 01 2023

// 转换为本地时间字符串
console.log(today.toTimeString());
// 输出: 12:30:45 GMT+0800 (中国标准时间)

// 转换为ISO格式
console.log(today.toISOString());
// 输出: 2023-06-01T04:30:45.000Z

// 使用本地设置格式化日期
console.log(today.toLocaleDateString());
// 输出: 2023/6/1 (取决于浏览器区域设置)

// 使用本地设置格式化时间
console.log(today.toLocaleTimeString());
// 输出: 12:30:45 (取决于浏览器区域设置)

// 同时格式化日期和时间
console.log(today.toLocaleString());
// 输出: 2023/6/1 12:30:45 (取决于浏览器区域设置)

使用Intl.DateTimeFormat API

对于更复杂的格式化需求,可以使用ECMAScript Internationalization API提供的Intl.DateTimeFormat

javascript
const date = new Date();

// 使用特定区域设置格式化
const usFormatter = new Intl.DateTimeFormat('en-US');
console.log(usFormatter.format(date));
// 输出: 6/1/2023

const cnFormatter = new Intl.DateTimeFormat('zh-CN');
console.log(cnFormatter.format(date));
// 输出: 2023/6/1

// 使用选项自定义格式
const options = {
weekday: 'long',
year: 'numeric',
month: 'long',
day: 'numeric',
hour: '2-digit',
minute: '2-digit',
second: '2-digit'
};

const formattedDate = new Intl.DateTimeFormat('zh-CN', options).format(date);
console.log(formattedDate);
// 输出: 2023年6月1日星期四 12:30:45
提示

Intl.DateTimeFormat是国际化日期格式化的推荐方式,它提供了对不同语言和区域设置的良好支持。

手动格式化日期

有时候,你可能需要完全控制日期的格式化方式。下面是一个自定义格式化函数的示例:

javascript
function formatDate(date, format) {
const map = {
MM: date.getMonth() + 1,
dd: date.getDate(),
yyyy: date.getFullYear(),
HH: date.getHours(),
mm: date.getMinutes(),
ss: date.getSeconds()
};

return format.replace(/MM|dd|yyyy|HH|mm|ss/g, matched => {
// 为单位数添加前导零
return map[matched].toString().padStart(2, '0');
});
}

const today = new Date();
console.log(formatDate(today, 'yyyy-MM-dd HH:mm:ss'));
// 输出: 2023-06-01 12:30:45
console.log(formatDate(today, 'dd/MM/yyyy'));
// 输出: 01/06/2023

这种手动方法允许你完全自定义日期格式,但实现复杂的格式可能需要更多代码。

使用第三方库

对于更强大的日期格式化功能,可以考虑使用第三方库。最流行的包括Day.js、Moment.js和date-fns。

警告

Moment.js虽然很受欢迎,但官方已不再建议用于新项目,推荐使用Day.js或date-fns替代。

Day.js示例

javascript
// 需要先引入Day.js
// npm install dayjs
// 或者在HTML中引入: <script src="https://unpkg.com/dayjs@1.8.21/dayjs.min.js"></script>

// 基本格式化
const now = dayjs();
console.log(now.format('YYYY-MM-DD HH:mm:ss'));
// 输出: 2023-06-01 12:30:45

// 相对时间
console.log(now.fromNow());
// 输出: 几秒前

// 自定义格式
console.log(now.format('dddd, MMMM D YYYY, h:mm:ss A'));
// 输出: 星期四, 六月 1 2023, 12:30:45 下午

date-fns示例

javascript
// 需要先引入date-fns
// npm install date-fns
// 然后在代码中导入:
// import { format, formatDistance } from 'date-fns'

const now = new Date();

// 基本格式化
console.log(format(now, 'yyyy-MM-dd HH:mm:ss'));
// 输出: 2023-06-01 12:30:45

// 相对时间
console.log(formatDistance(now, new Date(now - 5 * 60 * 1000), { addSuffix: true }));
// 输出: 5分钟前

// 使用不同区域设置
// 需要额外导入区域设置:import { zhCN } from 'date-fns/locale'
console.log(format(now, 'yyyy年MM月dd日 HH:mm:ss', { locale: zhCN }));
// 输出: 2023年06月01日 12:30:45

实际应用案例

案例1: 显示博客文章发布日期

javascript
function formatBlogDate(publishDate) {
const now = new Date();
const published = new Date(publishDate);

// 如果是今天发布的
if (published.toDateString() === now.toDateString()) {
return '今天 ' + published.toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' });
}

// 如果是昨天发布的
const yesterday = new Date(now);
yesterday.setDate(now.getDate() - 1);
if (published.toDateString() === yesterday.toDateString()) {
return '昨天 ' + published.toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' });
}

// 如果是今年发布的
if (published.getFullYear() === now.getFullYear()) {
return published.toLocaleDateString('zh-CN', { month: 'long', day: 'numeric' });
}

// 更早的日期
return published.toLocaleDateString('zh-CN');
}

// 使用示例
console.log(formatBlogDate(new Date())); // 今天 12:30
console.log(formatBlogDate(new Date(Date.now() - 24 * 60 * 60 * 1000))); // 昨天 12:30
console.log(formatBlogDate('2023-01-15')); // 1月15日
console.log(formatBlogDate('2022-06-01')); // 2022/6/1

案例2: 倒计时器

javascript
function createCountdown(targetDate) {
const target = new Date(targetDate);

function updateCountdown() {
const now = new Date();
const difference = target - now;

if (difference <= 0) {
return "活动已开始!";
}

// 计算剩余时间
const days = Math.floor(difference / (1000 * 60 * 60 * 24));
const hours = Math.floor((difference % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
const minutes = Math.floor((difference % (1000 * 60 * 60)) / (1000 * 60));
const seconds = Math.floor((difference % (1000 * 60)) / 1000);

return `${days}${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
}

return updateCountdown;
}

// 使用示例
const newYearCountdown = createCountdown('2024-01-01T00:00:00');
console.log(newYearCountdown()); // 输出剩余时间,如: 214天 11:26:55

案例3: 日期选择器格式化

javascript
// 假设这是一个从日期选择器获取的日期
function formatDateForServer(userSelectedDate) {
const date = new Date(userSelectedDate);

// 为API请求格式化日期 (ISO格式)
const isoFormat = date.toISOString();

// 为数据库格式化日期 (YYYY-MM-DD)
const dbFormat = date.toISOString().split('T')[0];

// 为用户界面格式化日期
const uiFormat = date.toLocaleDateString('zh-CN', {
year: 'numeric',
month: 'long',
day: 'numeric',
weekday: 'long'
});

return {
forApi: isoFormat,
forDatabase: dbFormat,
forDisplay: uiFormat
};
}

// 使用示例
const formats = formatDateForServer('2023-06-01');
console.log(formats);
// 输出:
// {
// forApi: "2023-06-01T00:00:00.000Z",
// forDatabase: "2023-06-01",
// forDisplay: "2023年6月1日星期四"
// }

日期格式化中的常见问题

时区问题

注意

在JavaScript中处理日期时,时区经常会引起混淆。用户和服务器可能位于不同的时区,从而导致显示问题。

javascript
// 显示带有明确时区的日期时间
const options = {
timeZone: 'Asia/Shanghai',
timeZoneName: 'short',
year: 'numeric',
month: 'long',
day: 'numeric',
hour: '2-digit',
minute: '2-digit'
};

const date = new Date();
console.log(new Intl.DateTimeFormat('zh-CN', options).format(date));
// 输出: 2023年6月1日 12:30 GMT+8

夏令时处理

夏令时也可能导致日期计算出现意外结果。使用Intl.DateTimeFormat或现代日期库可以正确处理这些情况。

javascript
// 夏令时期间的日期格式化
const summerDate = new Date('2023-07-15T12:00:00');
const winterDate = new Date('2023-01-15T12:00:00');

const options = {
timeZone: 'America/New_York',
timeZoneName: 'long',
hour: '2-digit',
minute: '2-digit'
};

console.log(new Intl.DateTimeFormat('en-US', options).format(summerDate));
// 可能输出: 12:00 PM Eastern Daylight Time

console.log(new Intl.DateTimeFormat('en-US', options).format(winterDate));
// 可能输出: 12:00 PM Eastern Standard Time

总结

JavaScript提供了多种格式化日期的方式,从内置方法到强大的第三方库,可以满足不同的需求:

  1. 内置Date方法:适合基本格式化需求,如toLocaleDateString()toLocaleTimeString()
  2. Intl.DateTimeFormat:提供了国际化支持和更多格式化选项。
  3. 手动格式化:通过自定义函数提供完全的格式化控制。
  4. 第三方库:Day.js和date-fns等提供了更丰富的功能和更简洁的API。

选择哪种方法取决于项目需求、复杂性和对国际化支持的需求。

练习与挑战

  1. 创建一个函数,将输入的日期格式化为"X天X小时X分钟前"的形式。
  2. 实现一个日期格式化函数,支持以下占位符:{YYYY}(年)、{MM}(月)、{DD}(日)、{HH}(时)、{mm}(分)、{ss}(秒)。
  3. 创建一个世界时钟应用,显示不同时区的当前时间。
  4. 实现一个函数,根据用户浏览器的语言设置自动格式化日期。

附加资源