Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wrong timezone used for implicit year/month/day #807

Closed
murrayju opened this issue Jan 1, 2020 · 6 comments
Closed

Wrong timezone used for implicit year/month/day #807

murrayju opened this issue Jan 1, 2020 · 6 comments
Labels

Comments

@murrayju
Copy link

murrayju commented Jan 1, 2020

This is probably only an issue around new year's day. If I parse a date like the following:

moment.tz('December 31 5:00PM', 'MMMM D h:mmA', 'America/Denver')

My expectation is that it will implicitly use the current year in the America/Denver timezone (which is currently 2019). Instead, it seems to be assuming the year that it is in GMT, resulting in the date being parsed as 2021-01-01T00:00:00.000Z which is a year in the future, instead of today.

@murrayju
Copy link
Author

murrayju commented Jan 1, 2020

Month and day have the same problem. I'm intending to use this to parse times (e.g. 5:00PM) that implicitly have "today's" date in the given time zone.

Fortunately,

moment.tz('America/Denver').format('YYYY-MM-DD')

gives the correct/expected result (2019-12-31), so I'm able to use this as a dirty workaround:

moment.tz(
  `${moment.tz('America/Denver').format('YYYY-MM-DD')} 5:00PM`,
  'YYYY-MM-DD h:mmA',
  'America/Denver',
)

@murrayju murrayju changed the title Implicit year uses wrong timezone Wrong timezone used for implicit year/month/day Jan 1, 2020
@ellenaua
Copy link
Contributor

@murrayju how did you get 2021-01-01T00:00:00.000Z? Did you use .toISOString() method?

See my results:

const moment = require('moment-timezone');
const date = moment.tz('December 31 5:00PM', 'MMMM D h:mmA', 'America/Denver')

console.log(date.toISOString()); // 2021-01-01T00:00:00.000Z -- correct, 00:00 UTC
console.log(date.format()); // 2020-12-31T17:00:00-07:00 -- correct, 17:00 in Denver
console.log(date.toString());  // Thu Dec 31 2020 17:00:00 GMT-0700 - correct, 17:00 in Denver

@ellenaua
Copy link
Contributor

ellenaua commented Feb 23, 2020

or you used methods like '.getDate()', '.getFullYear()', '.getDate()' which resulted to this:

const date = moment.tz('December 31 5:00PM', 'MMMM D h:mmA', 'America/Denver').toDate()
console.log(date.getFullYear()) // 2021
console.log(date.getMonth()) // 0
console.log(date.getDate()) // 1

You should use .format() to get correct values:

const date = moment.tz('December 31 5:00PM', 'MMMM D h:mmA', 'America/Denver');
console.log(date.format('YYYY')) // 2020
console.log(date.format('M')) // 12
console.log(date.format('D')) // 31

@murrayju
Copy link
Author

I used toISOString(). The point is that I got the value that you currently say is correct, when the local time was last year (2019). The point of the code is to interpret a given time with today's date in a given time zone. It usually works, but there is a window of time on new year's eve that incorrectly gives a date one year in the future instead.

This is a bug report, not a question.

@ellenaua
Copy link
Contributor

ellenaua commented Mar 14, 2020

I finally succeeded to reproduce it, thanks for reporting. This is how it can be reproduced:

const sinon = require('sinon');

sinon.useFakeTimers(new Date('2019-12-31T19:00:00-07:00'));

const date1 = moment.tz('December 31 9:00PM', 'MMMM D h:mmA', 'America/Denver');
const date2 = moment.tz('2019 December 31 9:00PM', 'YYYY MMMM D h:mmA', 'America/Denver');

console.log(date1.toISOString()); // 2021-01-01T04:00:00.000Z
console.log(date2.toISOString()); // 2020-01-01T04:00:00.000Z

@ichernev
Copy link
Contributor

This is a duplicate of #874, closing this for now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants