Other answers didn't work as I'd hoped, and sometimes the dates were off by 1 day because of time zone differences.
This is what I needed:
import DatePicker from 'react-datepicker';
import 'react-datepicker/dist/react-datepicker.css';
import { getEndOfDayUtc, treatLocalDateAsUtcMidnight, treatUtcMidnightAsLocalDate } from '../../../shared/helpers/datetime';
type DatePickerUtcProps = {
selected: Date | string;
onChange: any;
isEndOfDay: boolean;
};
function getSelectedAsLocal(selected: Date | string): Date {
const selectedDate = typeof selected === 'string' ? new Date(selected) : selected;
return treatUtcMidnightAsLocalDate(selectedDate);
}
export function DatePickerUtc({ selected, onChange, isEndOfDay, ...datePickerProps }: DatePickerUtcProps): JSX.Element {
function onChangeAsUtc(local: Date) {
const utc = treatLocalDateAsUtcMidnight(local);
const adjusted = isEndOfDay ? getEndOfDayUtc(utc) : utc;
console.log('onChangeAsUtc', { local, utc, adjusted, isEndOfDay });
onChange(adjusted);
}
return <DatePicker onChange={onChangeAsUtc} selected={getSelectedAsLocal(selected)} {...datePickerProps} />;
}
export function treatLocalDateAsUtcMidnight(localDate: Date): Date {
const moment = dayjs(localDate).tz('UTC', true); // https://day.js.org/docs/en/plugin/timezone
const utcMidnight = getStartOfDayUtc(moment.toDate());
console.log({ localDate, utcMidnight });
return utcMidnight;
}
export function treatUtcMidnightAsLocalDate(utcMidnight: Date): Date {
const sliceOfJustTheDatePart = utcMidnight.toISOString().slice(0, 10);
const localDate = dayjs(sliceOfJustTheDatePart).toDate();
console.log({ localDate, sliceOfJustTheDatePart, utcMidnight });
return localDate;
}
From: <DatePickerUtc selected={startDate} onChange={(utcDate: Date) => setStartDate(utcDate)} {...datePickerProps} />
To: <DatePickerUtc selected={endDate} onChange={(utcDate: Date) => setEndDate(utcDate)} {...datePickerPropsEndOfDay} />