Skip to content

Commit 949cd8e

Browse files
docs: address 'date is one day off' issue (#1018)
- Add comprehensive section in timezone.md explaining the timezone offset issue - Provide 4 different solutions with code examples - Update README.md to prominently link to issue #1018 and the solution guide - Clarify this is expected JavaScript Date behavior, not a bug
1 parent dd3c5c2 commit 949cd8e

File tree

2 files changed

+89
-0
lines changed

2 files changed

+89
-0
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,8 @@ Locales can be changed in the following way:
125125

126126
React-datepicker uses native JavaScript Date objects which are timezone-aware. By default, dates are displayed in the user's local timezone. The library does not include built-in timezone conversion utilities.
127127

128+
**Common issue: "Date is one day off" ([#1018](https://github.com/Hacker0x01/react-datepicker/issues/1018))** - If you're seeing dates shift by one day when converting to ISO strings or sending to a server, this is due to timezone conversion, not a bug. See the [Timezone Handling Guide](https://github.com/Hacker0x01/react-datepicker/blob/main/docs/timezone.md#the-date-is-one-day-off-problem-issue-1018) for solutions.
129+
128130
For detailed information about working with timezones, UTC dates, and common timezone-related scenarios, see the [Timezone Handling Guide](https://github.com/Hacker0x01/react-datepicker/blob/main/docs/timezone.md).
129131

130132
For applications requiring timezone conversion, we recommend using [date-fns-tz](https://github.com/marnusw/date-fns-tz) alongside react-datepicker.

docs/timezone.md

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,93 @@
22

33
This guide explains how react-datepicker handles timezones and provides solutions for common timezone-related scenarios.
44

5+
## The "Date is One Day Off" Problem (Issue #1018)
6+
7+
One of the most commonly reported issues is that the selected date appears to be "one day off" when converted to a string or sent to a server. This is **not a bug** in react-datepicker—it's the expected behavior of JavaScript Date objects.
8+
9+
### Why This Happens
10+
11+
When you select a date in the datepicker (e.g., September 10th), the component returns a JavaScript `Date` object representing **midnight local time** on that day:
12+
13+
```js
14+
// User in UTC-3 timezone selects September 10th
15+
// The Date object represents: Sep 10, 2017 00:00:00 (local time)
16+
```
17+
18+
However, when you call `toISOString()` on this Date object, JavaScript converts it to UTC:
19+
20+
```js
21+
const selectedDate = /* Sep 10, 2017 00:00:00 local time (UTC-3) */;
22+
console.log(selectedDate.toISOString());
23+
// Output: "2017-09-09T21:00:00.000Z" ← Appears to be September 9th!
24+
```
25+
26+
The date looks "wrong" because midnight in UTC-3 is 9:00 PM the previous day in UTC.
27+
28+
### Solutions
29+
30+
#### Solution 1: Use Local Date String (Recommended for date-only fields)
31+
32+
If you only care about the date (not the time), extract just the date portion:
33+
34+
```jsx
35+
const handleChange = (date) => {
36+
// Get the date in YYYY-MM-DD format based on local time
37+
const year = date.getFullYear();
38+
const month = String(date.getMonth() + 1).padStart(2, "0");
39+
const day = String(date.getDate()).padStart(2, "0");
40+
const dateString = `${year}-${month}-${day}`; // "2017-09-10"
41+
42+
sendToServer(dateString);
43+
};
44+
45+
<DatePicker selected={date} onChange={handleChange} />;
46+
```
47+
48+
#### Solution 2: Adjust for Timezone Offset
49+
50+
If you need an ISO string that represents the local date at midnight UTC:
51+
52+
```jsx
53+
const handleChange = (date) => {
54+
// Adjust for timezone offset to get the "intended" UTC date
55+
const offsetDate = new Date(date.getTime() - date.getTimezoneOffset() * 60000);
56+
const isoString = offsetDate.toISOString(); // "2017-09-10T00:00:00.000Z"
57+
58+
sendToServer(isoString);
59+
};
60+
```
61+
62+
#### Solution 3: Use date-fns format function
63+
64+
```jsx
65+
import { format } from "date-fns";
66+
67+
const handleChange = (date) => {
68+
// Format the date in local time
69+
const dateString = format(date, "yyyy-MM-dd"); // "2017-09-10"
70+
sendToServer(dateString);
71+
};
72+
```
73+
74+
#### Solution 4: Use toLocaleDateString()
75+
76+
```jsx
77+
const handleChange = (date) => {
78+
// Get localized date string
79+
const dateString = date.toLocaleDateString("en-CA"); // "2017-09-10" (YYYY-MM-DD format)
80+
sendToServer(dateString);
81+
};
82+
```
83+
84+
### Important Notes
85+
86+
- **This is not a react-datepicker bug**: The datepicker correctly returns the date you selected in your local timezone
87+
- **The visual display is correct**: The datepicker shows the correct date; the "issue" only appears when converting to UTC
88+
- **Choose the right solution for your use case**: If you're storing dates without times (like birthdays), use Solution 1 or 3. If you need precise timestamps, be aware of timezone implications.
89+
90+
---
91+
592
## How react-datepicker Handles Dates
693

794
React-datepicker uses native JavaScript `Date` objects and the [date-fns](https://date-fns.org/) library for date manipulation. This means:

0 commit comments

Comments
 (0)