Дата Javascript и аргумент конструктора java.util.Date - PullRequest
8 голосов
/ 18 января 2012

Да, еще один вопрос о дате в Java и Javascript.

Часовой пояс GMT + 4 (Москва) как в Java, так и в браузере (Chrome).

<script language="javascript">
  var d = new Date(170798400000);
  document.write(d);
</script>

Дает: вс 01 июня 1975 00:00:00 по Гринвичу + 0400 (по российскому стандартному времени)

public class Test {
    public static void main(String[] args) {
        java.util.Date d = new java.util.Date(170798400000L); // the same epoch value!
        System.out.println(d);
    }
}

Дает: сб 31 мая 23:00:00 МСК 1975

Если я изменю значение эпохи на что-то вроде 2011-2012 года (после отмены перехода на летнее время в России), вывод в порядке. Средство обновления часового пояса работает нормально.

Это ошибка или документированная функция? Есть ли способ справиться с этим, кроме форматирования и повторного анализа, например, ГГГГ-ММ-дд ЧЧ: мм: СС или около того?

от Javadoc:

Дата (длинная дата)

Выделяет объект Date и инициализирует его для представления указанного количества миллисекунд со стандартного базового времени, известного как «эпоха», а именно 1 января 1970 года, 00:00:00 по Гринвичу.

из ссылки на JavaScript:

новая дата (миллисекунды)

миллисекунды - целочисленное значение, представляющее количество миллисекунд с 1 января 1970 года 00:00:00 UTC (эпоха Unix).

Ответы [ 3 ]

1 голос
/ 17 мая 2014

Строковое представление времени (например, "Sun Jun 01 1975 00:00:00 GMT+0400") используется для человека. Значение времени (миллисекунды с 1 января 1970 года по Гринвичу) используется для хранения и расчета.

Там нет ошибки. В JavaScript, согласно спецификации, содержание строкового представления зависит от реализации. В Java согласно документации летнее время может отражать .

С Спецификация JavaScript :

15.9.5.2 Date.prototype.toString ( )

Эта функция возвращает строковое значение. Содержимое строки зависит от реализации, но предназначено для представления даты в текущем часовом поясе в удобной для человека форме.

С Документация Java :

java.util.Date, public String toString()

Converts this Date object to a String of the form: dow mon dd hh:mm:ss zzz yyyy

where:
...
zzz is the time zone (and may reflect daylight saving time).`
1 голос
/ 20 января 2012

Это ошибка или документированная функция?

Это не ошибка в Javascript. По крайней мере, я не вижу, как я могу это утверждать.

Движок Javascript браузера возвращает время, преобразованное в «GMT + 4». Очевидно, что вы хотите MSK, который отличается от GMT + 4 (как отмечено в вашем комментарии). Javascript, который не знает о MSK, не считается ошибкой, но является недостатком функции. Возможно, js «не прав» из-за отсутствия подробного знания часовых поясов, но это не ошибка.

Есть ли способ справиться с этим, кроме форматирования и повторного анализа, например, ГГГГ-ММ-дд ЧЧ: мм: СС или около того?

Отслеживание всех произвольных деталей часовых поясов требует большой работы. Я не знаю ни одной такой кодовой базы, у которой есть вся эта работа, доступная для JavaScript. Поэтому я считаю, что да, вам придется вручную кодировать это преобразование самостоятельно, если вы хотите использовать настоящий MSK.

0 голосов
/ 17 июня 2017

tl; др

Instant.ofEpochMilli( 170_798_400_000L )

1975-05-31T20: 00: 00Z

… и…

Instant.ofEpochMilli( 170_798_400_000L )
       .atZone( ZoneId.of( "Europe/Moscow" ) )

1975-05-31T23: 00 + 03: 00 [Европа / Москва]

См. живой код .

Использование java.time

Современный подход использует классы java.time в Java 8 и более поздних версиях.

Вы используете проблемные старые классы даты и времени в Java, которые теперь унаследованы.Среди множества проблем в этих классах была благие намерения, но запутанная особенность метода Date::toString, применяющего текущий часовой пояс по умолчанию при генерации строки.Внутреннее значение на самом деле всегда в UTC, но toString создает иллюзию, что Date имеет часовой пояс, а на самом деле его нет.Это объясняет вашу MSK тайну.

[Еще более запутанно, что на самом деле - это часовой пояс, глубоко закопанный в Date, но не имеющий отношения к этому обсуждению.Эти старые Date / Calendar классы ужасны.К счастью, в Java теперь есть лучшая в своем классе структура даты и времени на любой платформе: java.time.]

Видимо, ваш ввод представляет количество миллисекунд с начала Unix 1970-01-01T00: 00:00Z.

Класс Instant представляет момент на временной шкале в UTC с разрешением наносекунд (до девяти (9) цифр)десятичной дроби).Этот класс может непосредственно анализировать ваш входной номер.

Instant instant = Instant.ofEpochMilli( 170_798_400_000L ) ;

instant.toString (): 1975-05-31T20: 00: 00Z

Если вы хотите увидетьв тот же момент через линзу часового пояса определенного региона примените часовой пояс.Примените ZoneId, чтобы получить ZonedDateTime объект.

ZoneId z = ZoneId.of( "Europe/Moscow" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;

1975-05-31T23: 00 + 03: 00 [Европа / Москва]

Неверная библиотека JavaScript

Результаты вашего вызова библиотеки JavaScript неверны с ее смещением +04: 00 . Согласно Википедии , московское время с 1930 по 1981 год было на три часа вперед, +03: 00.Среда java.time дает правильные результаты +03: 00 на протяжении 1975 года. Для получения дополнительной информации см. Время в России .Предостережение: я не эксперт в России / советское время.


О java.time

Фреймворк java.time встроен в Java 8 и более поздние версии.Эти классы вытесняют проблемные старые устаревшие классы даты и времени, такие как java.util.Date, Calendar и & SimpleDateFormat.

Проект Joda-Time , теперь в режиме обслуживания , рекомендует перейти на классы java.time .

Чтобы узнать больше, см. Oracle Tutorial .И поиск переполнения стека для многих примеров и объяснений.Спецификация: JSR 310 .

Где получить классы java.time?

Проект ThreeTen-Extra расширяет Java.время с дополнительными занятиями.Этот проект является полигоном для возможных будущих дополнений к java.time.Здесь вы можете найти несколько полезных классов, таких как Interval, YearWeek, YearQuarter и more .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...