TGViewer
.NET Разработчик .NET Разработчик @netdeveloperdiary · 6.75K subscribers
Post #2466 2.4K
День 2039. #Оффтоп
Баг в Течение Часа в Год
Было 8 ноября 2021, я работал сортировщиком ошибок в команде Google Docs. День начался как любой другой. Я заварил кофе и начал просматривать отчёты об ошибках за предыдущий день. Кое-что привлекло моё внимание.

Было необычно много сообщений об ошибках, и все они говорили об одном и том же. Пользователь создал ответ или новый комментарий в документе, но его метка времени на странице говорила, что он был создан «завтра». Быстро выявилась закономерность. Все ошибки появлялись:
- У пользователей в тихоокеанском часовом поясе (PT)
- Между 23:00 и 23:59 (PT) 7 ноября
Я бы посчитал это совпадением, но перевод на зимнее время случился в 2:00 (PT) 7 ноября!

Расследование
Баг меня заинтересовал, поэтому я решил заняться его устранением самостоятельно. Не потребовалось много времени, чтобы прийти к выводу, что ошибка, должно быть, в логике форматирования относительной даты Closure Library, которую использовал Docs. Код начинался с попытки вычислить количество дней между текущим временем и временем ввода через:
1. Получение текущего времени (new Date()).
2. Сброс часов, минут, секунд и миллисекунд объекта до нуля, чтобы получить время начала текущего дня.
3. Вычисление количества миллисекунд между временем начала текущего дня и временем ввода, деления его на количество миллисекунд в дне и округления в меньшую сторону.

Я некоторое время смотрел на код, и тут меня осенило! Введенное время между 23:00 и 23:59 (PT) 7 ноября было в поясе тихоокеанского стандартного времени (PST) после окончания летнего времени, но начало текущего дня (00:00) было в поясе тихоокеанского летнего времени (PDT) до окончания летнего времени. Поэтому в тот день между 00:00 и 23:00 не было 23 часов. Два времени были в двух разных часовых поясах с разницей в час, поэтому между двумя временами было 24 часа (целый день)! А что делал код, когда время ввода на день позже начала текущего дня? Он форматировал время как «завтра»…

Исправление
К счастью, класс Date в JS предоставляет удобный метод getTimezoneOffset(), который возвращает количество минут между часовым поясом объекта Date и часовым поясом UTC. Я использовал его для вычисления разницы. По сути, это удаляло любые различия, возникавшие только из-за изменения летнего/зимнего времени между текущим временем и временем начала текущего дня. Так что теперь количество часов между 00:00 и 23:00 в этот день вычислялось как 23!

Бонусный баг
Эта ошибка фактически распространялась и на время начала летнего времени. В 2021 году летнее время началось в 2:00 (по тихоокеанскому времени) 14 марта. Что же произойдёт, если оставить комментарий в 00:00 15 марта, когда текущее время было 23:00 14 марта?

Можно было бы ожидать, что между 00:00 и 23:00 вечера 14 марта будет 23 часа, но их всего 22. Из-за того, что летнее время начинается в 2:00, что на самом деле 3:00, между временем начала дня 14 и 15 марта всего 23 часа!

И что делает код для этого количества часов? Он вычисляет количество дней между двумя временами как ноль из-за округления в меньшую сторону и форматирует время как «сегодня»…
На самом деле этот баг не проявлялся в Google Docs, поскольку нельзя написать комментарий в будущем, и посмотреть его в прошлом.

Почему 1 час в год только по тихоокеанскому времени?
На самом деле эта ошибка теоретически могла произойти в любом часовом поясе. Возможно, все отчёты об ошибках в тот день были случайно получены от пользователей в тихоокеанском часовом поясе. Или, возможно, есть какой-то другой фактор, о котором я не подумал.

Источник: https://tomeraberba.ch/the-1-hour-per-year-bug
Автор оригинала: Tomer Aberbach
  • 👍 9
  • 👎 2
More from @netdeveloperdiary
  1. Oct 6, 2026🦈 Открытое собеседование на Middle C# | 6 октября, 19:00 МСК Приглашаем на открытое собес…
  2. Oct 6, 2026День 2806. #ЗаметкиНаПолях Типы Коллекций в .NET, Которые Стоит Попробовать. Начало Больши…
  3. Oct 5, 2026День 2805. #ЧтоНовенького #NET11 Аргументы в Выражениях Коллекций в C#15 В C#15 реализован…
  4. Oct 4, 2026День 2804. #ВопросыНаСобеседовании Марк Прайс предложил свой набор из 60 вопросов (как тех…
  5. Oct 3, 2026Post #3360
  6. Oct 3, 2026День 2803. #Оффтоп Чем Заняться, Пока Работают Агенты? У VS Code Есть Ответ Сейчас большую…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →