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

React中使用date-fns的differenceInDays返回NaN问题求助

问题原因

你用formatInTimeZone将日期格式化为dd/MM/yyyy字符串后,再通过new Date()解析该字符串时,不同JS环境对这种格式的解析逻辑不统一——多数浏览器会把dd/MM/yyyy误识别为MM/dd/yyyy,甚至直接返回Invalid Date。differenceInDays处理无效日期时,自然会返回NaN。

解决方案

直接操作时区对应的Date对象,跳过字符串格式化再解析的冗余步骤:

import { zonedTimeToUtc } from 'date-fns-tz'
import { differenceInDays } from 'date-fns'

const DifferenceInDays = ({ target, user }) => {
    // 将过期日期转换为用户时区对应的UTC Date对象
    const expiryDateInTz = zonedTimeToUtc(target.expiry_date, user.timezone);
    // 获取当前时间在用户时区下的UTC Date对象
    const currentDateInTz = zonedTimeToUtc(new Date(), user.timezone);

    const daysDifference = differenceInDays(expiryDateInTz, currentDateInTz);

    return (
        <>
            {daysDifference}
        </>
    )
}

export default DifferenceInDays

如果需要确保基于用户时区的"自然日"计算(忽略时间部分,只算日期差),可以配合startOfDay处理:

import { zonedTimeToUtc } from 'date-fns-tz'
import { differenceInDays, startOfDay } from 'date-fns'

const DifferenceInDays = ({ target, user }) => {
    const expiryDate = zonedTimeToUtc(target.expiry_date, user.timezone);
    const currentDate = zonedTimeToUtc(new Date(), user.timezone);

    // 取用户时区当天的起始时间,避免时分秒影响天数计算
    const expiryStartOfDay = startOfDay(expiryDate);
    const currentStartOfDay = startOfDay(currentDate);

    const daysDifference = differenceInDays(expiryStartOfDay, currentStartOfDay);

    return (
        <>
            {daysDifference}
        </>
    )
}

export default DifferenceInDays
关键提示
  • formatInTimeZone仅用于日期显示格式化,绝对不能用于日期计算,因为字符串解析存在兼容性风险。
  • zonedTimeToUtc可将指定时区的日期转换为UTC标准的Date对象,确保date-fns的计算函数能正确处理时区差异。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 20:57:52