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

如何用Moment.js根据地区动态显示本地化格式的日期时间?

问题

我根据访客选择的locale和timezone显示其日期时间,目前功能正常,但代码输出的格式始终固定。我希望根据所选地区的格式,动态显示包含日、月、年和时间的本地化日期时间,请问是否可行?

以下是我编写的自定义Hook:

import {useState, useEffect} from "react";
import moment from "moment";
import IntlStorage from "../helpers/IntlStorage";

export const useLocaleTime = () => {
    const [formattedTime, setFormattedTime] = useState<string | null>(null);

    const locale = IntlStorage.getLocale(); // 示例值:en-US
    const timezone = IntlStorage.getTimezone(); // 示例值:US/Alaska

    useEffect(() => {
        const updateTime = () => {
            moment.locale(locale);
            moment.tz.setDefault(timezone);

            const currentTime = moment().format("D MMMM YYYY LTS");

            setFormattedTime(currentTime);
        };

        const interval = setInterval(updateTime, 1000);

        return () => clearInterval(interval);
    }, [locale, timezone]);

    return formattedTime;
};

我还做了另一种尝试,但输出格式仍未改变:

useEffect(() => {
        const updateTime = () => {
            const options: any = {
                day: "numeric",
                month: "long",
                year: "numeric",
                hour: "numeric",
                minute: "numeric",
                second: "numeric",
                timeZone: timezone,
            };

            const currentDate = new Date();
            const formattedTime = currentDate.toLocaleString(locale, options);

            setFormattedTime(formattedTime);
        };
解决方案

当然可行,问题出在你要么指定了固定格式规则,要么没有正确利用本地化API的自动适配能力。下面给你两种修复方案:

方案一:使用原生Intl.DateTimeFormat(推荐)

你之前的原生API尝试已经接近正确,调整选项让格式完全跟随地区习惯,补全完整Hook代码如下:

import { useState, useEffect } from "react";
import IntlStorage from "../helpers/IntlStorage";

export const useLocaleTime = () => {
    const [formattedTime, setFormattedTime] = useState<string | null>(null);

    const locale = IntlStorage.getLocale();
    const timezone = IntlStorage.getTimezone();

    useEffect(() => {
        const updateTime = () => {
            // 不强制指定格式细节,让API根据locale自动适配组合格式
            const options: Intl.DateTimeFormatOptions = {
                timeZone: timezone,
                dateStyle: "long",
                timeStyle: "medium"
            };

            const formatter = new Intl.DateTimeFormat(locale, options);
            const formattedTime = formatter.format(new Date());

            setFormattedTime(formattedTime);
        };

        const interval = setInterval(updateTime, 1000);
        updateTime(); // 初始化立即执行一次

        return () => clearInterval(interval);
    }, [locale, timezone]);

    return formattedTime;
};
  • 说明:dateStyle和timeStyle参数会根据locale自动生成符合当地习惯的格式,比如en-US会输出October 5, 2024 3:45:23 PM,zh-CN会输出2024年10月5日 15:45:23。

方案二:修复moment.js的用法

你之前的moment代码用了固定格式字符串"D MMMM YYYY LTS",这会覆盖本地化自动格式,改成使用moment的本地化格式令牌即可:

import { useState, useEffect } from "react";
import moment from "moment";
import "moment-timezone";
import IntlStorage from "../helpers/IntlStorage";

export const useLocaleTime = () => {
    const [formattedTime, setFormattedTime] = useState<string | null>(null);

    const locale = IntlStorage.getLocale();
    const timezone = IntlStorage.getTimezone();

    useEffect(() => {
        const updateTime = () => {
            moment.locale(locale);
            const currentTime = moment.tz(timezone).format("LLL");

            setFormattedTime(currentTime);
        };

        const interval = setInterval(updateTime, 1000);
        updateTime();

        return () => clearInterval(interval);
    }, [locale, timezone]);

    return formattedTime;
};
  • 说明:moment的LLL令牌是本地化的长格式日期时间,会根据设置的locale自动调整格式,比如en-US输出October 5, 2024 3:45 PM,fr-FR输出5 octobre 2024 15:45。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 14:55:25