LocalTime.tsx 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. 'use client';
  2. import { useEffect, useState } from 'react';
  3. import { useLanguage } from '@/lib/i18n/LanguageContext';
  4. interface LocalTimeProps {
  5. date: string | Date; // 接收 UTC 时间
  6. className?: string;
  7. options?: Intl.DateTimeFormatOptions;
  8. }
  9. export default function LocalTime({ date, className, options }: LocalTimeProps) {
  10. const { lang } = useLanguage();
  11. const [localTimeString, setLocalTimeString] = useState<string>('');
  12. useEffect(() => {
  13. if (!date) return;
  14. let dateObj: Date;
  15. // === 核心修复逻辑 ===
  16. if (typeof date === 'string') {
  17. // 1. 兼容 "YYYY-MM-DD HH:mm:ss" 格式,将空格替换为 T
  18. let normalizedDate = date.replace(' ', 'T');
  19. // 2. 如果字符串末尾没有 'Z' 且没有时区偏移(如 +08:00),强制追加 'Z'
  20. // 这告诉浏览器:“这个时间字符串是 UTC 时间”
  21. if (!normalizedDate.endsWith('Z') && !normalizedDate.includes('+')) {
  22. normalizedDate += 'Z';
  23. }
  24. dateObj = new Date(normalizedDate);
  25. } else {
  26. dateObj = date;
  27. }
  28. // 检查日期是否有效
  29. if (isNaN(dateObj.getTime())) {
  30. setLocalTimeString('Invalid Date');
  31. return;
  32. }
  33. const locale = lang === 'zh' ? 'zh-CN' : 'en-US';
  34. const defaultOptions: Intl.DateTimeFormatOptions = {
  35. year: 'numeric',
  36. month: '2-digit',
  37. day: '2-digit',
  38. hour: '2-digit',
  39. minute: '2-digit',
  40. second: '2-digit',
  41. hour12: false,
  42. };
  43. const finalOptions = { ...defaultOptions, ...options };
  44. // 使用浏览器的 Intl API 进行本地化格式化 (会自动转换为用户时区)
  45. const formatter = new Intl.DateTimeFormat(locale, finalOptions);
  46. setLocalTimeString(formatter.format(dateObj));
  47. }, [date, lang, options]);
  48. if (!localTimeString) {
  49. return <span className={`opacity-0 ${className}`}>--:--</span>;
  50. }
  51. return <span className={className}>{localTimeString}</span>;
  52. }