Closed matt-d-webb closed 3 months ago
Closing issue, this is due to the subtle difference between calling .toString()
and .toISOString()
, locale vs UTC, as such I have switched to the former in the ShadCn DatePicker.tsx
conform implementation.
MDN ref note:
This is what I needed to do for fixing the timezone issue:
import { format, parseISO } from "date-fns";
import { Calendar as CalendarIcon } from "lucide-react";
import * as React from "react";
import { Button } from "@/components/ui/button";
import { Calendar } from "@/components/ui/calendar";
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "@/components/ui/popover";
import { cn } from "@/lib/utils";
import {
FieldMetadata,
unstable_useControl as useControl,
} from "@conform-to/react";
export function DatePickerConform({ meta }: { meta: FieldMetadata<Date> }) {
const triggerRef = React.useRef<HTMLButtonElement>(null);
const control = useControl(meta);
// Function to convert date to ISO string while preserving local time
const dateToLocalISOString = (date: Date) => {
const offset = date.getTimezoneOffset();
const localDate = new Date(date.getTime() - offset * 60 * 1000);
return localDate.toISOString().split("T")[0];
};
// Function to parse ISO string to local date
const parseLocalISOString = (isoString: string) => {
const date = parseISO(isoString);
return new Date(date.getTime() + date.getTimezoneOffset() * 60 * 1000);
};
return (
<div>
<input
className="sr-only"
aria-hidden
tabIndex={-1}
ref={control.register}
name={meta.name}
defaultValue={
meta.initialValue
? dateToLocalISOString(new Date(meta.initialValue))
: ""
}
onFocus={() => {
triggerRef.current?.focus();
}}
/>
<Popover>
<PopoverTrigger asChild>
<Button
ref={triggerRef}
variant={"outline"}
className={cn(
"w-64 justify-start text-left font-normal focus:ring-2 focus:ring-stone-950 focus:ring-offset-2",
!control.value && "text-muted-foreground",
)}
>
<CalendarIcon className="mr-2 h-4 w-4" />
{control.value ? (
format(parseLocalISOString(control.value), "PPP")
) : (
<span>Pick a date</span>
)}
</Button>
</PopoverTrigger>
<PopoverContent className="w-auto p-0">
<Calendar
mode="single"
selected={
control.value ? parseLocalISOString(control.value) : undefined
}
onSelect={(value) =>
control.change(value ? dateToLocalISOString(value) : "")
}
/>
</PopoverContent>
</Popover>
</div>
);
}
Thank you for coming back with the solution you got, saved me loads of time.
Describe the bug and the expected behavior
Using the Shadcn
Calendar
via the Conform DatePicker , I am getting the incorrect date on select, this is consistently day -1 of the selected value.Attached video.
Conform version
v1.1.4
Steps to Reproduce the Bug or Issue
Referencing the Conform Datepicker: https://github.com/edmundhung/conform/blob/main/examples/shadcn-ui/src/components/conform/DatePicker.tsx
My code: