Comments 11
Спасибо за исчерпывающую статью!
Насчет leap second: последний раз она добавлялась в полночь 30 июня 2015 года, в связи с чем утром лежало большое количество сервисов, в том числе и java. С чем могут быть связаны подобные сбои?
Насколько я понял по баг-репортам, проблема была косвенная — при выводе диагностического сообщения о появлении leap second ядром в лог. Потому как сам по себе сдвиг времени на секунду назад (вручную или через NTP) корректными системами должен обрабатываться без проблем.

Также я видел баг-репорт про ORACLE (подробностей не помню) где в функции разбора времени каким-то образом прокидывалась честная 60-я секунда, которую стандартная функция не могла обработать (валидный диапазон секунд был 0..59)

Вот еще статейка: www.slashroot.in/leap-second-bug-linux-kernel
ИМХО, проблема leap second кроется не в java (хотя может и в ней тоже), а в ОС, и в самом принципе високосных секунд: их вводят административно когда захотят, и эти секунды приходят по ntp. Это значит, что в будущем мы не можем точно прогнозировать временные интервалы.

Под убунтой все печательней. (наверное, под виндой тоже)
Дело в том, что System.currentTimemillis выдает время в миллисекундах, и оно не монотонно: в момент високосной секунды это время прыгает на 1000мс назад, но при этом запланированные с интервалом такси — выполняются с этим интервалом более-менее нормально — как будто время линейно. И получается этот прыжок назад надо как-то обрабатывать, если это важно.

Якобы в кернеле могут быть альтернативные time discipline при который часы ведут себя по другому, но есть ли они там и как их можно включить — я не разбирался.
Это стандартное поведение Unix-time — не учитывать leap-second, а просто скакать назад (или вперед) на одну секунду.

При желании локальную реализацию скачка в ядре можно отключить, а NTP (или другой внешний инициатор) может самостоятельно сглаживать момент перехода:
developerblog.redhat.com/2015/06/01/five-different-ways-handle-leap-seconds-ntp
googleblog.blogspot.ru/2011/09/time-technology-and-leaping-seconds.html
Хорошая статья.
Тоже в свое время пришлось заниматься интернационализацией web-приложений, и работа с календарями оказалась немаловажной её частью. Вот от меня 2 копейки.
1) site.icu-project.org — проект, включающий в себя, кроме прочего, классы для работы со временем за пределами григорианского календаря. Какие — можно посмотреть тут
2) В статье встречается Calendar.getInstance(). Данный метод теоретически может вернуть не григорианский календарь (хотя практически, на данный момент — нет). Поэтому в проектах, распределенных по разным странам, я бы избегал использования данного метода, заменяя на new GregorianCalendar(). Просто для того, чтобы быть уверенным, что и в будущем летоисчисление и манипуляции с датами во всех подсистемах будут одинаковыми.
Статья замечательная и очень подробная. Мне только кажеться, что вы зря обошли вниманием Java 8 — лучше было-бы все примеры пояснять на новых классах, чем объяснять кривизну старых.
Про Java 8 будет в следующей части, да и эта статья больше про необходимость уделять внимание временным зонам, чем про недостатки текущей реализации
Должен заметить, что SimpleDateFormat непотокобезопасный от слова «совсем».
Да, лучше уберу этот пассаж. Это MessageFormat можно считать таким, я спутал
А не проще в случае той же базы данных просто хранить все даты как long? Мне кажется, так намного меньше головной боли. Сохранять, естественно, по UTC+0, и пусть уже дальше бизнес-логика разбирается при вводе-выводе.
Only those users with full accounts are able to leave comments. Log in, please.