На корпоративном портале одного нашего заказчика у некоторых пользователей в их профиле неправильно отображалась дата рождения – вместо необходимого дня показывался предыдущий. Наши разработчики выяснили, что причина этой ошибки скрывалась глубоко в истории.
Сначала команда проверила бэкенд и убедилась, что данные приходят корректно. Проанализировали логи взаимодействия пользовательских браузеров с сайтом – выяснилось, что баг воспроизводится только в Safari на устройствах Apple. А когда пользователи говорят, что дата рождения отображается правильно, они заходят на портал с другого устройства и браузера, например, с Google Chrome на компьютере.
Далее, команда стала перебирать разные периоды, постепенно сокращая временные отрезки, чтобы понять, с какой датой связан наш баг. Выяснилось, что проблема крутится вокруг июня 1930 года – именно там происходит сбой по времени, причем только в Safari. Стали разбираться дальше, что особенного произошло 21 июня 1930 года, и откопали, что в этот день в Советском Союзе перевели время на час вперёд. Google Chrome обрабатывает эту ситуацию корректно, а Safari – нет.
Еще одна особенность в формате переменной, которая передает это время. Формат отсчитывает количество миллисекунд от нулевого времени – отметка стоит на 1 января 1970 года. Google Chrome обрабатывает дату 21 июня следующим образом: с 23:59 до часа ночи стоит 1000 миллисекунд (что равно 1 секунде), то есть это время «пропадает». Safari же считает, что это время там есть, так как не знает, что в СССР переводили часы.
Команда зарепортила этот баг в Apple Feedback Assistant и ожидает ответа. А портал получит собственную заплатку со следующим релизом.
P.S. В процессе расследования разработчики обратили внимание ещё на один интересный факт. У пользователей есть фича, которая позволяет отображать на портале только день и месяц рождения без года. И оказалось, что если пользователь выбирает такую настройку, то с бэкенда передаётся значение «4 год нашей эры». Установить, почему создатели портала выбрали эту дату, удалось только в самом финале.
Оказалось, что сначала выставлялась единица как самое простое значение по умолчанию. Но тогда появился баг в поиске – он не находил людей с днями рождения 29 февраля. Создать инстанс с 29 февраля в невисокосном году не позволяет используемая структура хранения времени. Поэтому в коде прописали первый в нашей эре високосный год, и все заработало.