Reputation: 6373
The displayed date in Material UI Pickers is 1 day behind the selected date:
I selected 25th, the value in formik is 25th but the value displayed on the form is 24th.
"@date-io/date-fns": "^1.3.13",
"date-fns": "^2.9.0",
import DateFnsUtils from '@date-io/date-fns';
import { MuiPickersUtilsProvider, DatePicker } from '@material-ui/pickers';
import { format, addDays } from 'date-fns';
<MuiPickersUtilsProvider utils={DateFnsUtils}>
<FastField
as={DatePicker}
variant="inline"
disableToolbar
name="startTime"
format="PPP"
onChange={date => {
console.log(format(date, 'yyyy-MM-dd'));
setFieldValue('startTime', format(date, 'yyyy-MM-dd'));
}}
value={values.startTime}
/>
</MuiPickersUtilsProvider>
Upvotes: 24
Views: 21192
Reputation: 153
I fixed this easily with "string concatenation".
In the .component.html
<mat-form-field>
<input matInput readonly [matDatepicker]="picker" placeholder="Date of birth" formControlName="dob" (dateChange)="formatDate($event)">
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker></mat-datepicker>
<mat-error *ngIf="handleError('dob', 'required')">Date of birth is required</mat-error>
</mat-form-field>
In the .component.ts
/* format date */
formatDate(e: any) {
var d = new Date(e.target.value)
var convertDate = d.toISOString().substring(0, 10) + d.toISOString().substring(10,);
this.actorForm.get('dob')?.setValue(convertDate, { onlyself: true });
}
See my answer to this case at https://stackoverflow.com/a/73215526/15280648
Upvotes: 0
Reputation: 223
const handleDateAtOnChange = (e) => {
const date = moment(e.target.value).utcOffset(0, false).format("MM-DD-YYYY")
setDate(date)
}
<DatePicker
value={date}
onChange={handleDateAtOnChange}
format="MM/dd/yyyy"
/>
Upvotes: 0
Reputation: 2398
I've faced the same problem
After all, I added a parseISO
method on my date, you need to specify the timezone of the component.
// import parseISO
import { parseISO } from 'date-fns';
On value (property which is date)
<KeyboardDatePicker
format={'dd/MM/yyyy'}
label="Date"
value={parseISO(salesPage.dateAt)}
onChange={handleDateAtOnChange}
/>
On change
import { format } from 'date-fns';
import { convertToLocalTime } from 'date-fns-timezone';
export const DEFAULT_DATE_FORMAT = 'yyyy-MM-dd';
/**
* Format a date to a string
*
* @param date
*/
export const formatDate = (date) => {
if (!date) return new Date().toLocaleString();
// Get the timezone from browser using native methods
const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
const dateTmp = Date.parse(date.toLocaleString());
const localDate = convertToLocalTime(dateTmp, {
timeZone: timezone,
});
return format(localDate, DEFAULT_DATE_FORMAT);
};
const handleDateAtOnChange = (event) => {
formatDate(event.target.value)
}
Upvotes: 17
Reputation: 71
its because datepicker takes input date-time in UTC ISOformat Solution - Convert UTC to local to ISO format
because server only accepts ISO date-time so I converted UTC to local timezone and sent it to server in ISO format
declare this somewhere
function convertUTCDateToLocalDate(date) {
var newDate = new Date(date.getTime() - date.getTimezoneOffset()*60*1000);
return newDate;
}
and do this where you need local datetime in ISO format convertUTCDateToLocalDate(date).toISOString()
Upvotes: 6