vascofg / react-admin-date-inputs

Date Inputs for react-admin
MIT License
67 stars 81 forks source link

DateInput stores wrong date if timezone is +2 #28

Open jheiska opened 5 years ago

jheiska commented 5 years ago

When storing a date with dateinput, while local time is ahead of UTC, the time storing is a bit "funny". As it is converted to datetime and to utc, the actual date stored is the day before the selected one, since the time on the date is 0:00 and decreasing it by 2 hours will take it to the previous day. This causes some serious problems if the date is converted to a date in backend, simply throwing away the time part. I did find some ways to get around this from react-admin issues, but shouldn't this be something that is resolved in the component itself, maybe as an optional "switch"?

EDIT: Actually, why dateinput doesn't just send a date (like the react-admin basic dateinput), why is the "time" included? EDIT2: By "switch" I mean for example having an option to choose what timezone the date(or time in datetime) is entered in. If this kind of option exists, I was unable to find it.

MoonSupport commented 4 years ago

If DateInput will not include 'time', it would have same issue yet.

we can reference react admin doc for this problem. https://github.com/marmelab/react-admin/blob/master/docs/Inputs.md

Below code, It would work for you

const tzOffset = new Date().getTimezoneOffset() / 60
const dateParser = v => {
  const regexp = /(\d{4})-(\d{2})-(\d{2})(T|\s)(\d{2}):(\d{2})/
  let match = regexp.exec(v)
  if (match === null) return

  let year = match[1]
  let month = match[2]
  let day = match[3]
  let hour = match[5]
  let min = match[6]

  if (tzOffset < 0) {
    const date = new Date(v)
    match = regexp.exec(date.toISOString())
    if (!match) return null
    year = match[1]
    month = match[2]
    day = match[3]
    hour = match[4]
    min = match[5]
  }
  const date = [year, month, day].join('-')
  const time = [hour, min].join(':')
  const result = date + 'T' + time + 'Z'
  return result
}
<DateTimeInput
    source="test"
    parse={dateParser}
    {...rest}
 />