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

如何在JavaScript/Dayjs中正确实现含自然语言解析的跨时区时间转换

自然语言时间解析与时区双向转换问题

初始代码与问题

使用chrono-node(自然语言时间解析)、Dayjs及timezone插件实现时区转换,初始代码如下:

import * as chrono from 'chrono-node'
import dayjs from 'dayjs'
import utc from 'dayjs/plugin/utc'
import timezone from 'dayjs/plugin/timezone'

dayjs.extend(utc)
dayjs.extend(timezone)

let selectedInput = 'pst'
let selectedOutput = 'est'
let inputDateString = '10pm'

// 设置默认时区为PST
dayjs.tz.setDefault(selectedInput)
const inputDate = chrono.parseDate(inputDateString)
const utc = inputDate?.toISOString().replace(/Z$/, '')
const computedInputDate = utc
  ? dayjs(utc).tz(selectedInput)
  : undefined
const outputDateString = computedInputDate
  ? dayjs(computedInputDate)
      .tz(selectedOutput)
      .format('h:mma on MMM D, YYYY')
  : undefined
dayjs.tz.setDefault() // 重置默认时区
console.log('output:', outputDateString)

在2024年1月31日,输入10pm(表示该日晚上10点PST),预期输出应为1:00am on Feb 1, 2024,但实际输出却是9:00am on Feb 1, 2024。

移除UTC转换后的单向有效、双向失效

移除UTC转换部分后,代码如下:

import * as chrono from 'chrono-node'
import dayjs from 'dayjs'
import utc from 'dayjs/plugin/utc'
import timezone from 'dayjs/plugin/timezone'

dayjs.extend(utc)
dayjs.extend(timezone)

let selectedInput = 'pst'
let selectedOutput = 'est'
let inputDateString = '10pm'

// 设置默认时区为PST
dayjs.tz.setDefault(selectedInput)
const inputDate = chrono.parseDate(inputDateString)
const computedInputDate = inputDate
  ? dayjs(inputDate).tz(selectedInput)
  : undefined;
const outputDateString = computedInputDate
  ? dayjs(computedInputDate).tz(selectedOutput).format("h:mma on MMM D, YYYY")
  : undefined;
dayjs.tz.setDefault() // 重置默认时区
console.log('output:', outputDateString)

此时得到了正确的1:00am on Feb 1, 2024,但反转时区(EST→PST)时出现错误。反转时区的代码如下:

import * as chrono from 'chrono-node'
import dayjs from 'dayjs'
import utc from 'dayjs/plugin/utc'
import timezone from 'dayjs/plugin/timezone'

dayjs.extend(utc)
dayjs.extend(timezone)

let selectedInput = 'est'
let selectedOutput = 'pst'
let inputDateString = '10pm'

// 设置默认时区为EST
dayjs.tz.setDefault(selectedInput)
const inputDate = chrono.parseDate(inputDateString)
const computedInputDate = inputDate
  ? dayjs(inputDate).tz(selectedInput)
  : undefined;
const outputDateString = computedInputDate
  ? dayjs(computedInputDate).tz(selectedOutput).format("h:mma on MMM D, YYYY")
  : undefined;
dayjs.tz.setDefault() // 重置默认时区
console.log('output:', outputDateString)

输入10pm(EST),预期应显示7:00pm on Jan 31, 2024(PST),但实际显示10:00pm on Jan 31, 2024,双向转换均存在问题。

尝试Luxon后的同样问题

尝试使用Luxon库,结果仍存在相同问题,代码如下:

const time = '10pm'
const selectedInput = 'EST'
const selectedOutput = 'PST'

const inputDate = chrono.parseDate(time, { timezone: selectedInput })
const outputDate = inputDate
  ? DateTime.fromJSDate(inputDate, { zone: selectedInput }).setZone(
      selectedOutput,
    )
  : undefined
const outputDateString = outputDate
  ? `${outputDate.toFormat('h:mm')}${outputDate
      .toFormat('a')
      .toLowerCase()} on ${outputDate.toFormat('MMM d, yyyy')}`
  : undefined
// 输出10pm而非预期的7pm

即使使用IANA基于位置的时区,问题依旧:

const inputDate = chrono.parseDate(time, {
  timezone: 'America/Cancun',
})
const outputDate = inputDate
  ? DateTime.fromJSDate(inputDate, {
      zone: 'America/Cancun',
    }).setZone('America/Los_Angeles')
  : undefined
const outputDateString = outputDate
  ? `${outputDate.toFormat('h:mm')}${outputDate
      .toFormat('a')
      .toLowerCase()} on ${outputDate.toFormat('MMM d, yyyy')}`
  : undefined
// 输出10pm而非预期的7pm

核心疑问

给定输入时区、输出时区和自然语言输入时间,如何实现正确的双向时区转换?

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 23:49:53