Reputation: 1505
I'm so confused what's going on. I just implemented react-native-datetimepicker/datetimepicker for a user to select their birthday.
If I select June 8, 2000 -> the date returned is 2000-06-09T00:00:00.000Z
, which means the users birthday is set for June 9, 2000.
here is the element:
<DateTimePicker
value={this.props.date}
mode={this.props.mode}
display="calendar"
onChange={(event, date) => {
this.handleDatePicked(event, date)
}}
/>
async handleDatePicked(event, date) {
console.log(new Date(date))
await this.props.onSelect(this.props.propName, date)
await this.changeState()
}
console.log(date)
logs 2000-06-09T00:00:00.000Z
console.log(new Date(date))
logs 2000-06-09T00:00:00.000Z
BUT! console.log(new Date(date).getDate())
logs 8
And when I reopen the calendar, it is set on June 8, 2000.
🤯
My mind is exploding -- what is going on here? June 8, 2000 is only for the example - it's constantly off by 1 day no matter what day, month or year is selected. My hypothesis is something to do with timezone maybe? Any help is greatly appreciated!
Upvotes: 3
Views: 6318
Reputation: 1
In your date time picker component add this line to resolve your issue.
<DateTimePicker
{ ... }
timeZoneOffsetInMinutes={new Date().getTimezoneOffset()}
/>
Due to default time zone effect you are getting different date and time than yours.
Upvotes: 0
Reputation: 4673
This is not a bug, but definitely confusing.
I have done my part of research and found out that this seems like a bug but it is actually not a bug.
The real issue is in how the javascript Date object parses date strings.
The best answer I have found is this stack-O answer. Check out its' excellent write-up.
Below is a very pertinent comment from the answer mentioned above. (credit: @Mizstik)
All of this is due to the behavior of the underlying Date.parse() trying to follow ISO 8601. When the date string follows the yyyy-mm-dd format, it's assumed to be ISO 8601 with implicit UTC 00:00. When the string deviates from the format (e.g. mm-dd-yyyy or slash instead of hyphen), it falls back to the looser parser according to RFC 2822 which uses local time when the timezone is absent. Admittedly, this will all be quite arcane to an average person.
Now I am thinking you installed react-datetime package attached it with your input. And then after setting your state you tried to print the date on your DOM.
But it throws an error because the react child could not be an object. So you did JSON.stringify and that is when you found out that the date is off by 1 day.
That might be happening because you are using something like this for onchange event
onChange={(date) => setDate(date)}
But that will just parse the date object as string. What you can do is use the Date object, to format the date as you would like. For instance :
onChange={(date) => {
const dateString = new Date(date).toLocaleDateString()
console.log(dateString)
}}
You will then get the date formatted to your locale time zone. However, if you specified a different format in your DatePicker from your local timezone format, then you can specify it as a parameter for toLocaleDateString for example:
new Date(date).toLocaleDateString("fr-FR")
Upvotes: 1
Reputation: 204
I also have this problem. I searched many documents but doesn't find a solution. So, I just implemented this in the onConfirm prop
const tempdate = new Date(seslectedDate);
setDate(new Date(tempdate.setDate(tempdate.getDate() + 1)));
Upvotes: -2
Reputation: 578
This is because Date.getDate()
returns the day and month according to local time. The date object you’ve provided is set to UTC time, which means when the date is converted to your local time zone it is actually the day before.
To fix this problem, set the timeZoneOffsetInMinutes
prop of your date picker.
Unfortunately, this prop has known implementation problems on Android. A good alternative may be to avoid the prop entirely, and instead use a date library like date-fns to manipulate the time zone of the outputted date object.
Upvotes: 4