question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

DateTime.hour is not in a 24-hour format after setting the time zone

See original GitHub issue

Describe the bug The documentation states that the hour property of DateTime is always in a 24-hour format, but that doesn’t appear to be true in React Native using Expo. If you use Settings.default or DateTime.setZone() to change the time zone, the hour property is returned in a 12-hour format.

To Reproduce console.log(‘5:00 PM EST hour:’, DateTime.fromISO(‘2021-11-05T17:00:00-04:00’).setZone(‘America/New_York’).hour);

Actual vs Expected behavior The code above should log out “5:00 PM EST hour: 17” but instead logs out “5:00 PM EST hour: 5”.

Desktop (please complete the following information):

  • OS: iOS and Android
  • Browser: this is happening outside of a browser
  • Luxon version: 2.0.2
  • Your timezone: America/New_York

Additional context Updated my initial post to make it clear that the issue seems to be specific to mobile devices and/or React Native using Expo.

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:12 (6 by maintainers)

github_iconTop GitHub Comments

1reaction
ian-yoder-creditgeniecommented, Nov 9, 2021

@icambron I just updated to version 2.1.1 and the hour for 5:00 PM is now showing as 17. Seems like it worked! Thank you so much!

1reaction
icambroncommented, Nov 8, 2021

Ok, I’m now pretty confident this is what’s happening. Here’s the full backstory:

  1. Luxon computes offsets for arbitrary zones by passing the zone and the time into the Intl API and using formatToParts to extract the local time. It can then use that time to compute the zone’s offset at that time.
  2. For that to work reliably, Luxon always uses 24 hour time so that it knows the “real” hour
  3. Before the Intl spec added hourCycle, there was another option called hour12. You set it if you wanted to override the locale settings and use 24-hour time instead
  4. At some point, hourCycle was introduced with values like h11, h23, and h24 and the spec explained how to map hour12 to these new values. The gist of the conversion was that hour12: true turned into h24
  5. The semantics of h24 are somewhat insane: it uses 24:00 to mean 00:00 (no change in day). h23 is what people mean by “24-hour time”. When browsers updated to implement this behavior, they broke Luxon. Here’s a discussion: https://bugs.chromium.org/p/chromium/issues/detail?id=1025564&can=2&q=“24%3A00” datetimeformat
  6. For the purposes of computing offsets, this is easy to work around, so Luxon did: it just checks if the hour is 24 and, if so, uses 0 instead
  7. However, it also seriously broke Luxon’s 24-hour-flavored formatting presets, which supplied hour12 arguments to Intl. This was harder to fix, because not all browsers supported hourCycle yet, so Luxon couldn’t use it
  8. So for Luxon 2.0, I decided that hourCycle was now strong enough, and flipped everything to use hourCycle: 'h23'
  9. But it’s still apparently not supported everywhere, which means that hourCycle is ignored and we sometimes interpret PM times as AM times.

So here’s the deal:

  • I’m going to revert the switch to hourCycle in the offset calculator, and use the old workaround there. That will fix this bug without changing any other behavior. (There are several ways to fix it, including simply changing the locale used, but this one is simplest)
  • I’m not going to revert the use hourCycle in the formatting presets like TIME_24_SIMPLE, which are used in toLocaleString() and similar methods. That means that for these older environments, the 24-hour part will continue to be ignored for those presets. You can always specify your own using hour12 instead of hourCycle. This is needed because most callers would get incorrect results for midnight.
Read more comments on GitHub >

github_iconTop Results From Across the Web

Does DateTime.Now always return a 24 hour format by default?
DateTime.Now returns time without formatting. Format applied in the ToString("HH:mm") method. And yes, this format is 24-hour.
Read more >
Set 12 vs 24 hour with the new date formatting API in iOS 15
The problem that I'm having is figuring out how to force the new API to display 12 vs 24h times. So, for example,...
Read more >
Time Format, How to convert 12 hour time to 24 hour time? How
I am converting as below, gmt(local(now(),"EST")). Time is changing fine, but the timezone is not changing. Still its displaying CST ...
Read more >
Change the date and time on your Galaxy phone or tablet
Navigate to and open Settings. Tap General management, and then tap Date and time. · Tap the switch next to Use 24-hour format....
Read more >
Ability to Choose Time Formats - AM/PM or 24 Hour
24 hour time can often cause confusion when setting appointments resulting in the wrong time being set. Having a choice on date and...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found