Tomer Aberbach

The 1 Hour per Year Bug (But Only in Pacific Time!)

Updated Published ·

Note

This article was updated in response to some helpful comments on Hacker News. I originally incorrectly formatted the Pacific Time Zone daylight saving times relative to the Eastern Time Zone!

The date was November 8, 2021 and I was a bug triager on the Google Docs team. That day began like any other. I made myself some coffee and started looking through bug reports from the day before. But then something caught my eye.

The bug reports <span aria-label="bug" role="img">🐛</span> permalinkThe bug reports 🐛

There were an unusually large number of bugs reported and they all said the same thing. The user had created a reply or new comment in a Doc, but its timestamp in the UI said it had been created “tomorrow”.

The pattern <span aria-label="globe with meridians" role="img">🌐</span> permalinkThe pattern 🌐

A pattern quickly emerged. These bugs were all reported:

Normally I would have dismissed that as a coincidence, but daylight saving time also ended at 2:00am (PT) on November 7!

The investigation <span aria-label="detective" role="img">🕵️</span> permalinkThe investigation 🕵️

This bug piqued my interest so I decided to triage it to myself.

It didn’t take long to conclude that the bug must be in Closure Library’s relative date formatting logic, which Docs was using. The code started with trying to compute the number of days between the current time and the input time by:

  1. Getting the current time as a Date object (i.e. new Date()).
  2. Resetting the object’s hours, minutes, seconds, and milliseconds to zero so that it represented the current day’s start time.
  3. Computing the number of milliseconds between the current day’s start time and the input time, dividing it by the number of milliseconds in a day, and rounding down.

I stared at the code for a while and then it hit me! The input time, between 11:00pm and 11:59pm (PT) on November 7, was in the Pacific Standard Time Zone (PST), after daylight saving time ended, but the start of the current day (12:00am) was in the Pacific Daylight Time Zone (PDT), before daylight saving time ended.

The result? There weren’t 23 hours between 12:00am and 11:00pm that day. The two times were in two different time zones, 1 hour apart, so there were 24 hours between the two times; a whole day!

2 hours
0 hours (clock turns back an hour)
22 hours
12:00am
2:00am (PDT)
1:00am (PST)
11:00pm (PST)
24 hours

And what does the code do when the input time is 1 day later than the start of the current day? It formats the time as “tomorrow”… 🤡

The fix <span aria-label="wrench" role="img">🔧</span> permalinkThe fix 🔧

So how did I fix this?

Luckily, JavaScript’s Date class exposes a handy getTimezoneOffset() method, which returns the number of minutes between the Date object’s time zone and the UTC time zone.

I used that method to compute the difference in milliseconds between the time zone offsets of the current day’s start time and the current time, and subtracted that from the number of milliseconds between the current day’s start time and the input time (in step 3 before).

What this effectively does is remove any millisecond differences that are only due to the time zone changing between the current time and the current day’s start time. So now the number of hours between 12:00am and 11:00pm on that day is computed as 23!

Bonus bug! <span aria-label="beetle" role="img">🪲</span> permalinkBonus bug! 🪲

This bug actually also extended to when daylight saving time starts.

In 2021, daylight saving time started at 2:00am (PT) on March 14. So what would happen for an input time of 12:00am (PT) on March 15 when the current time was 11:00pm (PT) on March 14?

You would expect there to be 23 hours between 12:00am, the start of the day, and 11:00pm (PT) on March 14, but there are only 22 hours. Due to daylight saving time starting at 2:00am, which is actually the same time as 3:00am, there are only 23 hours between the start times of March 14 and 15!

2 hours
0 hours (clock turns forward an hour)
21 hours
12:00am
2:00am (PST)
3:00am (PDT)
12:00am (PDT)
23 hours

And what does the code do for that number of hours? It computes the number of days between the two times as zero due to rounding down, and formats the time as “today”…

Note

This bug never actually happened in Docs because you can’t create a comment or reply in the future and view it from the past.

Why 1 hour per year, but only in Pacific Time? <span aria-label="thinking face" role="img">🤔</span> permalinkWhy 1 hour per year, but only in Pacific Time? 🤔

I originally wrote an explanation here, but some comments on Hacker News made me realize that this bug could have theoretically happened in any time zone.

It’s possible that all the bug reports were coincidentally from users in the Pacific Time Zone. Or perhaps there’s some other factor at play that I haven’t thought of. Let me know if you have any ideas!

Conclusion <span aria-label="judge" role="img">🧑‍⚖️</span> permalinkConclusion 🧑‍⚖️

At the time of writing, August 2024, my bug fix has enjoyed two glorious hours of usefulness. Time well spent I guess? 😅

Here’s to hoping my bug fix becomes obsolete soon!