Vlad SD
Vlad SD

Reputation: 261

MUI X DatePicker formatting and setting default value issue

I am having a bit of an issue, and I've had not much luck finding a solution to it. The MUI X DatePicker (with Material UI) seems to have a format that it has as a default, for displaying the dates as

Fri Oct dd yyyy HH:MM:SS GMT+HHMM (name of timezone here)

However, I need to be able to pass a date in the format of

yyyy-MM-ddThh:MM:ss+HH:mm which is (Date)T(Time)+(Timezone)

to the component, and then back to be submitted in the same format.

In some cases, the value for this date-time-picker is not set, in some cases it is. And I'm not sure how to get the format to what I need it, since I have no control of the date-format I am receiving.

It seems the component can parse the data I give it, and set the proper value, but the new data (if the value changes) does is in a different format.

edit: Just a quick example for above.

Data I get: 2020-10-11T15:56:28+11:00

Data the component outputs: { "$L": "en", "$u": undefined, "$d": Date Sun Oct 11 2020 15:56:28 GMT+1100 (Australian Eastern Daylight Time), "$x": {}, "$y": 2020, "$M": 9, "$D": 11, "$W": 0, "$H": 15, "$m": 56, … }

Relevant code for DateTimePicker:

import React from 'react';
import TextField from '@mui/material/TextField';
import DateTimePicker from '@mui/lab/DateTimePicker';

export default function DateTimePickerComponent(props) {
    const [value, setValue] = React.useState(null);
    const onDatePicked = (event) => {
        setValue(event);
        let onlyDate = event.$d;
        props.onChange(onlyDate);
        console.log("Date Changed", event, onlyDate);
    };

    React.useEffect(() => {
        if (props.initialValue !== 0 && value === null) {
            setValue(props.initialValue);
            console.log("Initial Date is", props.initialValue);
        }
    }, [props.initialValue, value, setValue]);

    return (
        <DateTimePicker
            label={props.label}
            value={value}
            onChange={onDatePicked}
            renderInput={(params) => <TextField {...params} />}
        />
    );
}

Upvotes: 7

Views: 55596

Answers (4)

Reda El Ouahabi
Reda El Ouahabi

Reputation: 91

The error could happen both on the client's local machine if they have a different time zone, so when selecting a date, the system automatically picks a "translated date to UTC," which is incorrect if their time zone is not GMT+00.

Similarly, on a hosted client server, if the server's time zone differs from the user's, the selected date will be correct locally, but when sent to the server, it will be converted to UTC. This can result in a date that is one day earlier (23:00:00Z) for users in GMT+01 time zones.

The solution that works for me in both scenarios is:

setDate(moment(date).utc(true).toDate());

Another potential solution for the second scenario is:

setDate(moment(date).utc().set({ hours: 12, minutes: 0, seconds: 0, milliseconds: 0 }).toDate());

Upvotes: 0

Assy
Assy

Reputation: 191

I resolved a similar issue by setting value to mui MUI Datepicker using dayjs library

import dayjs from 'dayjs'; 
 
<DateTimePicker
label={props.label}
value={dayjs(value)}
onChange={onDatePicked}
renderInput={(params) => <TextField {...params} />}
/>

Upvotes: 2

Vlad SD
Vlad SD

Reputation: 261

After doing some research, I was pointed to the fact that MUI's DatePicker/DateTimePicker uses a basic date format (as it formulated it in the event call). However, MUI parses and displays it differently, so all I had to do was simply the following:

let onlyDate = event.$d.toISOString();

this returned the date-time string I needed in the proper format.

If anyone comes across this in the future, look at this page I had ended up at:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date

It has multiple ways of parsing the data and functions to manipulate the date/time

Upvotes: 8

NearHuscarl
NearHuscarl

Reputation: 81270

To format the date, use inputFormat prop. If you're using date-fns, you can see the this table to know how to customize the format string:

<DateTimePicker
  label={props.label}
  value={value}
  inputFormat="E MMM dd yyyy HH:MM:SS O"
  onChange={setValue}
  renderInput={(params) => <TextField {...params} fullWidth />}
/>

If you want to set the initial value in a component that uses controlled mode, you must initialize the it in useState:

const [value, setValue] = React.useState(initialDate);

Codesandbox Demo

Upvotes: 6

Related Questions