2015-07-01 7 views
3

До и во время прыжка, кажется, что вызов new Date() будет возвращен 23:59:59 дважды (один раз перед прыжком в секунду и один раз в секунду), а не 23:59:59 , и 23:59:60.Правильное занятие 0 секунд

Есть ли способ (за исключением внедрения клиента NTP в приложении или проверки того, чтобы часы возвращались назад или повторялись), чтобы определить, является ли данная секунда секундомой или нет, чтобы правильно на это 23:59:60 пользователю?

На самом деле, есть ли в операционных системах хоста какие-либо крючки, чтобы определить, является ли это предварительным или пост-прыжковым?

+0

Java SE 8 четко определяет поведение второго уровня здесь: https://docs.oracle.com/javase/8/docs/api/java/time/Instant.html –

+0

Я не думаю, что такой метод, как * leap smear * будет квалифицироваться как правильное представление секунды прыжка, но это определенно допустимый способ обработки секунд прыжка, по крайней мере, в контексте сервера/базы данных: http://stackoverflow.com/questions/19751115/leap-second-handling- in-database/19756183 # 19756183 – Sandman

ответ

2

Согласно Java8 documentation for the Date class, дата вызова во время прыжка второй будет/правильно вернется: 60 или: 61.

Так что вам не нужно ничего делать.

Как это немного напоминает тайну, поскольку базовый Instant class разворачивает второй шаг за последние 1000 секунд в день - так что каждая из этих последних секунд будет на самом деле равна 1.001 секунды - и ваше приложение не будет знайте, находится ли он в секунду или нет.

+0

Класс 'java.time.Instant' * не * лежит в основе' java.util.Date', насколько мне известно. Обратите внимание на имена пакетов. Первый из совершенно новых (как Java 8) java.time framework. Последний очень старый, из первой версии Java. У даты есть несколько методов преобразования удобства для Instant, но их базы кода полностью разделены. –

5

Давайте посмотрим на исходный код java.util.Date:

public Date() { 
    this(System.currentTimeMillis()); 
} 

Так что вопрос может быть прочитана как:

Will System.currentTimeMillis() дают скачок второе значение 60 или даже 61 (как спецификация делает вид)?

Ответ в строгом смысле: это зависит от базовой операционной системы. Но факт в том, что все известные операционные системы, такие как Windows, Linux, Apple, Android, не знают о секундах. Вместо этого эти операционные системы выполняют любые манипуляции с часами в любое время (настройка и т. Д., Синхронизация с NTP-сервером ...). Таким образом, вы не будете наблюдать скачок секунды, используя Date -API. Между прочим, значение 61 невозможно, потому что UTC-стандарт предусматривает, что UTC никогда не будет отклоняться от UT1 более чем на 0,9 секунды, вследствие чего не будет вставлен двойной прыжок.

Происхождение «61» - просто грубое недоразумение из ранних спецификаций POSIX (где эта ошибка была исправлена ​​сейчас). К сожалению, старая Java-спецификация еще не исправлена, вызвав недоразумения до сих пор.

О Java-8:

Да, так называемый "Java Time-Scale" формально определяется как UTC-SLS - на основе выдыхаемого предложение которого цель была скорее направлена ​​на внутренних реализаций NTP -servers. В реальном мире нет реализации UTC-SLS. Даже Java-8 не реализует UTC-SLS. Два факты доказывают это утверждение:

  • Java-8 не содержит второй прыжок таблицу (которая будет основой любых UTC-SLS-реализация). Первоначально проект Threeten был проведен таким образом, но был удален (теперь также removed from the backport).

  • Преобразование из java.util.Date в Instant составляет всего 1: 1 (см. Исходный код - оставляя в стороне различную точность миллисов против нано).Обратите внимание, что java.util.Date не упоминается в API Instant относительно так называемой «Шкалы времени Java».

Java-временная шкала используется для всех классов даты и времени. Это включает Мгновенный, LocalDate, LocalTime, OffsetDateTime, ZonedDateTime и Продолжительность.

Кроме того: происхождение java.util.Date происходит с 1995 года (когда была изобретена Java), но UTC-SLS был предложен несколько лет спустя.

Итак, что осталось в Java-8 как поддержка второго уровня? Пустые слова в spec вызывают много путаницы, больше ничего.

Что вы можете сделать еще? В рамках JDK просто ничего. Вам нужна внешняя сторонняя библиотека со встроенными данными второго уровня. Примером может служить моя библиотека Time4J - см. Это article. Другим вариантом может быть библиотека Threeten-Extra со своим классом UTCInstant. Но я не протестировал его преобразование в java.util.Date (кажется, подозревается?).