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

如何让Next.js服务端组件使用客户端时区而非UTC?

解决Next.js 13.2.4服务端组件时区不一致问题

核心问题很明确:服务端组件运行在Vercel服务器上,默认使用UTC时区,无法直接获取客户端的本地时区信息。硬编码固定时区只能适配单一用户群体,没法覆盖所有用户的实际时区需求。下面是几种可行的解决方案:

方案1:客户端时区信息传递到服务端

先在客户端获取时区,通过Cookie、路由参数或API请求传给服务端,服务端组件读取该信息后格式化时间。

示例:用Cookie传递时区

  1. 客户端组件设置时区Cookie
'use client';
import { useEffect } from 'react';

export default function TimeZoneInitializer() {
  useEffect(() => {
    // 获取客户端时区
    const userTimeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
    // 设置Cookie,有效期1年
    document.cookie = `user_timezone=${userTimeZone}; path=/; max-age=31536000`;
  }, []);
  return null;
}
  1. 在根布局中引入这个初始化组件,确保用户首次访问时就设置Cookie
// app/layout.js
export default function RootLayout({ children }) {
  return (
    <html lang="zh-CN">
      <body>
        <TimeZoneInitializer />
        {children}
      </body>
    </html>
  );
}
  1. 服务端组件读取Cookie并格式化时间
// app/page.js
import { cookies } from 'next/headers';
import getLocalTime from './utils/getLocalTime';

export default function Home() {
  const cookieStore = cookies();
  // 读取Cookie中的时区,默认UTC
  const userTimeZone = cookieStore.get('user_timezone')?.value || 'UTC';
  const currentDate = new Date();
  const localTime = getLocalTime(currentDate, userTimeZone);

  return <div>当前本地时间:{localTime}</div>;
}

// utils/getLocalTime.js
export default function getLocalTime(date, timeZone) {
  return new Intl.DateTimeFormat('zh-CN', {
    year: 'numeric',
    month: '2-digit',
    day: '2-digit',
    hour: '2-digit',
    minute: '2-digit',
    second: '2-digit',
    timeZone: timeZone,
    timeZoneName: 'short'
  }).format(date);
}

方案2:将时间处理逻辑移至客户端组件

服务端只返回原始的ISO格式时间字符串,把时间格式化的工作交给客户端组件完成,天然使用客户端时区。

示例代码

  1. 服务端组件(仅传递原始日期)
// app/page.js
export default async function Home() {
  // 服务端生成日期,转成ISO字符串传给客户端
  const serverDate = new Date().toISOString();
  return <LocalTimeDisplay date={serverDate} />;
}
  1. 客户端组件(处理时间格式化)
// app/LocalTimeDisplay.jsx
'use client';

export default function LocalTimeDisplay({ date }) {
  const localTime = getLocalTime(new Date(date));
  return <div>当前本地时间:{localTime}</div>;
}

function getLocalTime(date) {
  return new Intl.DateTimeFormat('zh-CN', {
    year: 'numeric',
    month: '2-digit',
    day: '2-digit',
    hour: '2-digit',
    minute: '2-digit',
    second: '2-digit',
    timeZoneName: 'short'
  }).format(date);
}

方案3:使用客户端渲染模式

通过use client指令将需要处理时间的组件标记为客户端组件,或者用dynamic导入组件并关闭SSR,让组件直接在客户端运行,自然使用本地时区。

示例:标记为客户端组件

// app/TimeDisplay.jsx
'use client';

import getLocalTime from '../utils/getLocalTime';

export default function TimeDisplay() {
  const currentDate = new Date();
  const localTime = getLocalTime(currentDate);
  return <div>当前本地时间:{localTime}</div>;
}

然后在服务端组件中直接引入这个客户端组件即可。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 18:33:37