You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Moment与date-fns格式化Zulu日期时日期偏移一天的问题及解决

Zulu日期格式化后日期莫名加1天的问题及解决办法

问题描述

将Zulu格式日期(如2022-11-03T19:48:24Z)格式化为MM/dd/yyyy格式时,期望得到11/03/2022,但使用date-fns的format函数(代码如下)却得到11/04/2022,日期莫名加了一天。同时尝试Moment工具也存在同样问题。

使用的date-fns代码:

export function fDate(
  date: Date | string | number,
  template: string = 'MM/dd/yyyy'
) {
  return format(new Date(date), template);
}

调用示例:

fDate('2022-11-03T19:48:24Z')

预期结果:11/03/2022,实际结果:11/04/2022

原因分析

核心问题是时区差异:

  • Zulu格式的日期是UTC+0时区的时间,比如2022-11-03T19:48:24Z代表UTC时间11月3日19点48分。
  • 当你用new Date()解析这个字符串时,JavaScript会自动将其转换为本地时区的时间。如果你的本地时区是东八区(UTC+8),那么这个时间加上8小时后就是本地时间11月4日3点48分。
  • date-fns的format函数和Moment的默认格式化都是基于本地时区的,所以最终输出的日期就变成了11/04/2022。

解决办法

方法1:使用date-fns的utcFormat函数(推荐)

date-fns提供了utcFormat函数,可以直接基于UTC时区格式化日期,避免本地时区转换:

import { utcFormat } from 'date-fns';

export function fDate(
  date: Date | string | number,
  template: string = 'MM/dd/yyyy'
) {
  return utcFormat(new Date(date), template);
}

调用后会直接输出UTC时区的日期11/03/2022。

方法2:使用Moment的UTC解析方法

如果用Moment处理,需要用moment.utc()来解析日期,确保基于UTC时区格式化:

import moment from 'moment';

export function fDate(date: string | Date, template: string = 'MM/dd/yyyy') {
  return moment.utc(date).format(template);
}

方法3:手动提取UTC日期字段拼接

不想依赖工具库的话,可以直接提取UTC时区的年、月、日字段,手动拼接成目标格式:

export function fDate(dateStr: string, template: string = 'MM/dd/yyyy') {
  const date = new Date(dateStr);
  // 注意月份是从0开始的,所以要+1
  const month = String(date.getUTCMonth() + 1).padStart(2, '0');
  const day = String(date.getUTCDate()).padStart(2, '0');
  const year = date.getUTCFullYear();
  
  return template.replace('MM', month).replace('dd', day).replace('yyyy', year.toString());
}

内容的提问来源于stack exchange,提问作者Yash

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 06:01:44