MUI日期选择器:在Azure上选定的日期提前了一天

huangapple go评论107阅读模式
英文:

MUI Datepicker: selected date out by one day on Azure

问题

以下是您提供的内容的翻译部分:

我已经基于Material UI和Formik创建了一个自定义日期选择器组件它将日期值传递给父表单组件如下所示

import React from 'react';
import { useField } from 'formik';
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns';
import { DatePicker } from '@mui/x-date-pickers/DatePicker';
import enGB from 'date-fns/locale/en-GB';
import { parseISO } from 'date-fns';

const CustomDateField = ({ name, label, error, helperText, ...props }) => {
  const [field, meta, helpers] = useField(name);
  const locale = enGB;

  const handleDateChange = (date) => {
    console.log('date before changes', date);

    //这个if/else逻辑是多余的,因为MUI始终将日期作为日期而不是字符串传递
    if (typeof date === 'string') {
      const parsedDate = parseISO(date);
      console.log('parsedDate', parsedDate);
      helpers.setValue(parsedDate);
    } else {
      helpers.setValue(date);
      console.log('setValueDate', date);
    }
  };

  return (
    <div className="pb-4">
      <LocalizationProvider dateAdapter={AdapterDateFns} adapterLocale={locale}>
        <DatePicker
          {...field}
          {...props}
          name={name}
          label={label}
          value={field.value || null}
          onChange={handleDateChange}
          sx={{
            width: '100%',
          }}
          slotProps={{
            textField: {
              variant: 'outlined',
              error: Boolean(meta.touched && meta.error), //错误处理
              helperText: meta.touched && meta.error ? meta.error : helperText,
            },
          }} //错误处理
        />
      </LocalizationProvider>
    </div>
  );
};

export default CustomDateField;

在我的开发环境中本地运行时,日期选择器组件中选择的日期会传递给父组件。然而,在Azure应用服务上运行时,传递给父组件的日期比组件中选择的日期早一天。

我已经进行了一些日志记录,例如,当我选择日期(英国日期格式) 05/08/2023 时,控制台日志标题为 date before changes 的输出是:

Date Sat Aug 05 2023 00:00:00 GMT+0100 (British Summer Time)

然而,当传递给父组件时,日期会提前一天:

"event_date":"2023-08-04T23:00:00.000Z"

我在Stack Overflow上进行了一些搜索,并找到了一些可能与时区有关的问题。我尝试使用Azure的 Application Setting 配置将我的(基于Linux的)Azure应用服务器的时区更改为英国时间,使用 TZ=Europe/London,我认为这与我的本地PC的时区匹配,即 (UTC+00:00) Dublin, Edinburgh, Lisbon, London,并启用了夏令时差异(+1小时)。但这并没有解决问题。

我还找到了一些帖子(例如链接),讨论了JavaScript的 date 对象可能导致我正在经历的类似症状,但是由于我在本地开发环境中的代码没有问题,而在Azure上有问题,这让我认为这可能不是问题的根本原因。

有什么想法吗?


<details>
<summary>英文:</summary>
I have created a custom date picker component based on Material UI and Formik, which passes a date value to a parent form component, as follows:

import React from 'react';
import { useField } from 'formik';
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns';
import { DatePicker } from '@mui/x-date-pickers/DatePicker';
import enGB from 'date-fns/locale/en-GB';
import { parseISO } from 'date-fns';

const CustomDateField = ({ name, label, error, helperText, ...props }) => {
const [field, meta, helpers] = useField(name);
const locale = enGB;

const handleDateChange = (date) => {
console.log('date before changes',date)

//this if/else logic is redundant as MUI always passes the data as a date, not a string
if (typeof date === &#39;string&#39;) {
const parsedDate = parseISO(date);
console.log(&#39;parsedDate&#39;,parsedDate)
helpers.setValue(parsedDate);
} else {
helpers.setValue(date);
console.log(&#39;setValueDate&#39;,date)
}

};

return (
<div className="pb-4">
<LocalizationProvider dateAdapter={AdapterDateFns} adapterLocale={locale}>
<DatePicker
{...field}
{...props}
name={name}
label={label}
value={field.value || null}
onChange={handleDateChange}
sx={{
width: '100%',
}}
slotProps={{
textField: {
variant: 'outlined',
error: Boolean(meta.touched && meta.error), //error handling
helperText: meta.touched && meta.error ? meta.error : helperText,
},
}} //error handling
/>
</LocalizationProvider>
</div>
);
};

export default CustomDateField;


Running locally in my dev environment, the date selected in the date picker component is the date value that is passed to the parent component.  However, when running this on an Azure app service the date passed to the parent component is one day earlier than the day selected in the component.
I&#39;ve done some logging, and, as an example, when I selected the date (UK date format) `05/08/2023`, the output from the console log titled `&#39;date before changes&#39;` is:
`Date Sat Aug 05 2023 00:00:00 GMT+0100 (British Summer Time)`
However, by the time that is passed to the parent component, the date is one day prior:
`&quot;event_date&quot;:&quot;2023-08-04T23:00:00.000Z&quot;`.
I&#39;ve done some searching on S.O. and found potentially related issues with time zones.  I&#39;ve tried changing the time-zone of my (Linux-based) Azure app server to UK time using the Azure `Application Setting` config to `TZ=Europe/London` which I believe matches my local PC&#39;s timezone of `(UTC+00:00) Dublin, Edinburgh, Lisbon, London` and with (+1hr) summer-time difference enabled.  This did not resolve the issue.
I also found some posts (e.g. 
[1]) about the JavaScript `date` object causing the same symptom I&#39;m experiencing, but whilst that symptom is similar, the fact that I have no issue when my code runs locally on my dev environment, but is an issue on Azure, suggested to me that this was probably not the cause of my issue. Any ideas? [1]: https://stackoverflow.com/questions/7556591/is-the-javascript-date-object-always-one-day-off </details> # 答案1 **得分**: 0 我明白了,以下是翻译好的部分: "The MUI date picker defaults a time of 00:00:00 whenever a date is selected. In my case, on a user's PC, it was being set as 00:00:00 GMT+1. But the server (somewhere, I'm not sure where) is set to GMT/UTC, so when the date was passed to the backend and database, 1 hour was being subtracted. Subtracting 1 hour from 00:00:00 moved the date into the previous day. There are probably more elegant ways to fix this at a server timezone level, but as all my users are UK based, I just coded it to set a default time of 5am, so subtracting 1 hour will never result in a date change. New code for anyone interested:

import React from 'react';
import { useField } from 'formik';
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns';
import { DatePicker } from '@mui/x-date-pickers/DatePicker';
import enGB from 'date-fns/locale/en-GB';
import { setHours, setMinutes } from 'date-fns';

const CustomDateField = ({ name, label, error, helperText, ...props }) => {
const [field, meta, helpers] = useField(name);
const locale = enGB;

const handleDateChange = (date) => {
// Set the time to 5am, otherwise it defaults the time to 00:00:00, meaning during BST it will subtract 1 hour, which will result in a date change too.
const dateWithDefaultTime = setMinutes(setHours(date, 5), 0);
helpers.setValue(dateWithDefaultTime);
};

return (


<DatePicker
{...field}
{...props}
name={name}
label={label}
value={field.value || null}
onChange={handleDateChange}
sx={{
width: '100%',
}}
slotProps={{
textField: {
variant: 'outlined',
error: Boolean(meta.touched && meta.error),
helperText: meta.touched && meta.error ? meta.error : helperText,
},
}}
/>

);
};

export default CustomDateField;


<details>
<summary>英文:</summary>
OK, worked this out.  The issue is to do with timezones differing across local user PCs and the server - which is irritating, as time is an irrelevance in a date-picker...
The MUI date picker defaults a time of 00:00:00 whenever a date is selected.  In my case, on a user&#39;s PC, it was being set as 00:00:00 GMT+1,  But the server (somewhere, I&#39;m not sure where) is set to GMT/UTC, so when the date was passed to the backend and database, 1 hour was being subtracted.  Subtracting 1 hour from 00:00:00 moved the date into the previous day.
There are probably more elegant ways to fix this at a server timezone level, but as all my users are UK based, I just coded it to set a default time of 5am, so subtracting 1 hour will never result in a date change.
New code for anyone interested:

import React from 'react';
import { useField } from 'formik';
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns';
import { DatePicker } from '@mui/x-date-pickers/DatePicker';
import enGB from 'date-fns/locale/en-GB';
import { setHours, setMinutes } from 'date-fns';

const CustomDateField = ({ name, label, error, helperText, ...props }) => {
const [field, meta, helpers] = useField(name);
const locale = enGB;

const handleDateChange = (date) => {
// Set the time to 5am, otherwise it defaults the time to 00:00:00, meaning during BST it will subtract 1 hour, which will result in a date change too.
const dateWithDefaultTime = setMinutes(setHours(date, 5), 0);
helpers.setValue(dateWithDefaultTime);
};

return (
<div className="pb-4">
<LocalizationProvider dateAdapter={AdapterDateFns} adapterLocale={locale}>
<DatePicker
{...field}
{...props}
name={name}
label={label}
value={field.value || null}
onChange={handleDateChange}
sx={{
width: '100%',
}}
slotProps={{
textField: {
variant: 'outlined',
error: Boolean(meta.touched && meta.error),
helperText: meta.touched && meta.error ? meta.error : helperText,
},
}}
/>
</LocalizationProvider>
</div>
);
};

export default CustomDateField;
///

huangapple
  • 本文由 发表于 2023年8月5日 16:36:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/76840792.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定