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

为何moment.js与date-fns转换UTC到本地时区输出不一致?

解决date-fns转换UTC时间到本地时区的问题

你的问题出在两个关键地方:UTC时间解析错误,以及格式字符串使用不当,下面是修正方案:

问题1:UTC时间解析错误

原字符串"2023-03-07 06:27:06"没有时区标识,parseISO默认会将其解析为本地时区时间,而非UTC时间,这直接导致后续转换全部错误。

问题2:格式字符串符号错误

date-fns中dd代表星期几的缩写(如Mon),而你需要的是两位日期,应该用DD;hh是12小时制搭配a(上午/下午)的用法是对的,但日期符号必须修正。

修正后的代码

import { parse, format, utcToZonedTime } from 'date-fns';
import { useEffect } from 'react';

const time = "2023-03-07 06:27:06"; // UTC time

// 正确解析UTC时间:指定格式并明确时区为UTC
const parsedTime = parse(time, "yyyy-MM-dd HH:mm:ss", new Date(0), { timeZone: 'UTC' });

const formatInTimeZone = (date, fmt, tz) =>
  format(utcToZonedTime(date, tz), fmt, { timeZone: tz });

export default function App() {
  useEffect(() => {
    const localTimeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;

    const formattedTime = formatInTimeZone(
      parsedTime,
      "DD-MMM-yyyy hh:mm a", // 修正格式字符串
      localTimeZone
    );
    console.log(formattedTime);
  }, []);
  
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
    </div>
  );
}

另一种简化写法

如果可以修改原时间字符串,直接在末尾加Z标记为UTC,parseISO就能正确识别:

const time = "2023-03-07 06:27:06Z"; // 加上Z表示UTC
const parsedTime = parseISO(time);

后续格式转换部分保持修正后的格式字符串即可。

这样修改后,date-fns就能像moment一样正确将UTC时间转换为你所在的亚洲本地时区格式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 09:25:25