2

我正在使用 react DateTimePicker 小部件,并且希望将日期存储在 ISO 中,而不管时区和 DST。当前的本地化设置是 en-GB。

我已经尝试了以下帖子的建议,并浏览了 moment.js 的文档 转换日期 UTC 给出了错误的日期

moment.utc('Wed Sep 08 1999 00:00:00 GMT+0100').toJSON()

但最终结果是 1999-09-07T23:00:00.000Z 因此没有存储正确的输入日期。

我现在使用以下 formatDate 函数格式化日期,但是当我将机器上的时区更改为智利时,日期 1999-09-07 GMT-0200 变为 1999-09-08T00:00:00.000Z。

const formatDate = (v) => {
  console.log(v)
  const date = moment(v).format('YYYY-MM-DD')
  console.log(moment.utc(date).toJSON())
  return moment.utc(date).toJSON()
}

有什么我想念的吗?

4

1 回答 1

0

我尝试了这个问题的不同解决方法,但最后我创建的最可行的变体可以在下面找到。

此变体的主要思想是在输入字段中显示想要的 TZ,但在日历和 timeList 中显示本地 TZ。

我将不胜感激您的反馈。

另请参阅:https ://github.com/jquense/react-widgets/issues/467和https://github.com/jquense/react-widgets/issues/515

在此处输入图像描述

在此处输入图像描述

import React, { useState, useMemo, useCallback } from 'react';
import moment from 'moment-timezone';
import DateTimePickerOrigin from 'react-widgets/lib/DateTimePicker';

const monthShortNames = [
  'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
  'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec',
];

const dayShortNames = ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'];

const DateTimePicker = (props) => {
  const {
    tz, // <-- tz you want to display, eg 'Etc/UTC'
    min,
    max,
    value,
    onChange,
    ...tail
  } = props;

  const [localTz] = useState(moment.tz.guess());

  const fixedParse = useCallback(
    (dateStr) => (dateStr ? new Date(dateStr) : null),
    [],
  );

  const fixedFormat = 'MMM D, YYYY HH:mm z';

  const fixedTimeFormat = useCallback(
    (date) => {
      if (localTz !== tz) {
        return `${moment.tz(date, localTz).format('HH:mm z')} (${moment.tz(date, tz).format('HH:mm z')})`;
      }
      return moment.tz(date, localTz).format('HH:mm');
    },
    [tz, localTz, fixedFormat],
  );

  const fixedDateFormat = useCallback(
    (date) => String(date.getDate()),
    [],
  );

  const fixedYearFormat = useCallback(
    (date) => String(date.getFullYear()),
    [],
  );

  const fixedMonthFormat = useCallback(
    (date) => monthShortNames[date.getMonth()],
    [],
  );

  const fixedDayFormat = useCallback(
    (date) => dayShortNames[date.getDay()],
    [],
  );

  const fixedMin = useMemo(
    () => (min === null ? undefined : min),
    [min],
  );

  const fixedMax = useMemo(
    () => (max === null ? undefined : max),
    [max],
  );

  return (
    <DateTimePickerOrigin
      {...tail}
      parse={fixedParse}
      format={fixedFormat}
      timeFormat={fixedTimeFormat}
      dateFormat={fixedDateFormat}
      yearFormat={fixedYearFormat}
      monthFormat={fixedMonthFormat}
      dayFormat={fixedDayFormat}
      min={fixedMin}
      max={fixedMax}
      value={value}
      onChange={onChange}
    />
  );
};
于 2021-04-14T07:49:37.663 回答