'@mui/x-date-pickers UTC always, please

Using @mui/x-date-pickers I need to both display and edit in UTC. My stored data is also in UTC. I can wrap the value in a render function to force-display it in the format I need, but then upon edit the date is shown in my locale! I feel like there should be an option to say, "Just let me show and edit in UTC." Any help greatly appreciated. I can't believe this hasn't come up for scientific apps before.

import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns';
import { DateTimePicker } from '@mui/x-date-pickers/DateTimePicker';
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';

const dateFormat = 'yyyy-MM-dd HH:mm:ss';
const inputMask = '____-__-__ __:__:__';
const views = ['year', 'month', 'day', 'hours', 'minutes', 'seconds'];
const renderUTC = new Date(date).toISOString().replace('T', ' ').substring(0, 19);

...render returning:
      <LocalizationProvider dateAdapter={AdapterDateFns}>
        <DateTimePicker
            value={renderUTC(value)}
...


Solution 1:[1]

Ran into the same issue. My workaround was to use the getTimezoneOffset() to offset local to UTC before it goes into DateTimePicker as value and offset UTC to local after it comes out of DateTimePicker through onChange.

That way the dateTime in DateTimePicker widget appears same as the UTC dateTime even though it is in locale.

const offset = (utcTime) => {
    const tzoffset = utcTime.getTimezoneOffset() * 60000
    const localTime = new Date(utcTime.getTime() + tzoffset)
    return localTime
}

Solution 2:[2]

Using insight from @bikesh-rana here is a complete solution.

This is a <DateTimePicker using Formik as well. Helper functions:

const getTimezoneOffset = value => value.getTimezoneOffset() * 60000;

const makeLocalAppearUTC = value => {
  const dateTime = new Date(value);
  const utcFromLocal = new Date(dateTime.getTime() + getTimezoneOffset(dateTime));
  return utcFromLocal;
};

const localToUTC = dateTime => {
  const utcFromLocal = new Date(dateTime.getTime() - getTimezoneOffset(dateTime));
  return utcFromLocal;
};

And, in the <DateTimePicker:

value={makeLocalAppearUTC(field.value)}
onChange={value => field.onChange({ target: { value: localToUTC(value), id } })}

Thank you for the insight @bikesh-rana!

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Bikesh Rana
Solution 2