【问题标题】:Force react-datepicker to use UTC强制反应日期选择器使用 UTC
【发布时间】:2023-02-10 07:28:51
【问题描述】:

如果选择开始为空。

当我选择日期 20/04/2022

日期选择器显示 20/04/2022

Console.log 显示 Wed Apr 20 2022 00:00:00 GMT+0200(中欧夏令时)

但我在表格上的有效负载显示 2022-04-19T22:00:00.000Z

我可以将格式锁定为 UTC 吗?

【问题讨论】:

  • UTC 不是一种格式,它是一个时区。这两个字符串实际上代表同一个Date 对象,并且可能是由同一个对象创建的——一个是人类可读的形式,另一个是可互操作的 ISO861 形式。
  • 您使用的是什么日期选择器? input type='date'value 始终采用 ISO8601 格式,无论显示格式如何。
  • 我正在使用 reactdatepicker.com,自定义输入只是 type="text"
  • react-datepicker 返回本地时间的 Date 对象。那是......不幸的是,当你只想要约会时。尽管 JavaScript 没有仅限日期的对象,并且一个时区中的 YYYY-MM-DDT00:00:00 很可能代表另一个时区中的不同日期。在 JSON 中,日期以 UTZ(Z 后缀)或特定偏移量序列化为 ISO8601。所选的Date 将在每个时区有不同的解释。您可以尝试通过utcOffset参数告诉datepicker使用0作为偏移量,以确保在序列化时不修改该值
  • 也许您应该使用 Date.UTC 函数从日期选择器值创建 UTC 日期。如果您查看 Github 存储库,您会看到这个问题以不同的形式反复出现,例如like this issue。它也看起来像utcOffset doesn't work any more。支持不同偏移量的请求已关闭,因为无法修复

标签: react-datepicker


【解决方案1】:

这是众所周知的issue for react-datepicker

您有 2 种可能的解决方案 -

  1. 您可以在从表单发送数据之前转换日期, 或者
  2. 您可以将它从 UTC 转换为本地,也可以将本地转换为 UTC 用户的日期选择。

    你可以看到第二个解决方案herehere的问题和代码实现。

【讨论】:

  • 不是真正的解决方案。选择器本身仍然是本地时间,因此如果您选择一个在偏移范围内的日期和时间,那么当您转换为 UTC 时,您实际上是在选择一个完全不同的日期。例如你选择2022-09-14T23:00:00.000-05:00转换成2022-09-15T04:00:00.000Z所以如果你使用日期选择器进行过滤会变得有点乱
【解决方案2】:

我只想完全忽略用户的本地时区,甚至不将其用于显示或发送到 API。为了做到这一点,我使用他们的时区来从我的目标 api 时区 (utc) 来回解析日期。这对我有用:

它在 momentjs b/c 中,我们的代码很旧,可以在较新的库中复制

  const { timeZone: localTZ } = Intl.DateTimeFormat().resolvedOptions()
  // The TZ format I want everything to be displayed and submitted as
  const apiTZ = 'utc'
  const [apiTime, setApiTime] = useState(moment.utc())

  <DatePicker
    onChange={date => {
      const apiTimeFromPickerLocalDate = moment(date)
        .tz(localTZ)
        // change TZ without changing date/time
        .tz(apiTZ, true)
        .format()        
      setApiTime(apiTimeFromPickerLocalDate)
    }}
    selected={
      moment(apiTime)
        .tz(apiTZ)
        // Display picker time in local TZ without changing date/time
        .tz(localTZ, true)
        .toDate()
    }
  </DatePicker>

游乐场版(link

const localDate = moment(new Date()).format();
const { timeZone: localTZ } = Intl.DateTimeFormat().resolvedOptions();
const apiTZ = "utc";
const apiTimeFromPickerLocalDate = moment(localDate)
  .tz(localTZ)
  // change TZ without changing date/time
  .tz(apiTZ, true)
  .format();

const pickerTimeFromApiTime = moment(apiTimeFromPickerLocalDate)
  .tz(apiTZ)
  .tz(localTZ, true)
  .toDate();

console.log("local time", localDate);
console.log("api time", apiTimeFromPickerLocalDate);
console.log("picker time", pickerTimeFromApiTime);
local time 2023-02-09T13:12:39-10:00 
api time 2023-02-09T13:12:39Z 
picker time Thu Feb 09 2023 13:12:39 GMT-1000 (Hawaii-Aleutian Standard Time)

【讨论】:

    猜你喜欢
    • 2019-11-27
    • 1970-01-01
    • 2017-10-26
    • 2021-03-27
    • 2020-10-12
    • 2021-07-16
    • 1970-01-01
    • 1970-01-01
    • 2021-01-11
    相关资源
    最近更新 更多