Преобразование даты в миллисекунды в Java

Мне нужно преобразовать дату в соответствующий формат миллисекунд. Для этого я использую метод getTime() класса Date в Java. Но сгенерированная миллисекунда не соответствует моей фактической дате. Это на один день меньше моей даты. Например,

У меня 3_. Если я конвертирую эту дату в формат миллисекунд, то генерируется 1,416,594,600,000. На самом деле это значение соответствует 21-Nov-2014.

Пожалуйста, помогите мне получить точное значение миллисекунд, соответствующее Date в java.


person Ajith    schedule 18.07.2014    source источник
comment
Не могли бы вы показать нам фактический код, который вы используете для преобразования, а также какой результат вы ожидаете и какой результат вы на самом деле получаете? Кроме того, в каком часовом поясе вы находитесь.   -  person Dawood ibn Kareem    schedule 18.07.2014


Ответы (2)


1416594600000 соответствует 2014-11-21T18:30:00Z. Другими словами, 18:30 21 ноября 2014 года по Гринвичу. Конвертер эпох — отличный ресурс для проверки подобных вещей.

Теперь объект Date не имеет никакой информации о часовом поясе. Он просто представляет момент времени. Похоже, что ваше значение "22-Nov-2014" скорее всего соответствует полуночи по местному часовому поясу (Индия?). Если вы генерируете значения из множества разных часовых поясов и не сохраняете, какой часовой пояс соответствует какому значению, вы, по сути, потеряли здесь некоторую информацию.

Если вы пытаетесь просто представить дату (а не момент времени), но вам нужно сохранить ее как значение миллисекунд с начала эпохи unix, вероятно, имеет смысл хранить полночь этой даты в формате UTC, хотя вы также должны четко указать, что именно это вы и делаете. Если вы можете, вы должны сохранить значение таким образом, чтобы сделать его более очевидным, что это дата, например, используя поле DATE в базе данных. Работа с датами и временем часто на самом деле не так сложна, как мы опасаемся, если вы точно знаете, какие данные вы моделируете, и четко указываете это везде в своем коде.

Один из способов прояснить ситуацию — использовать хороший API даты/времени, который позволяет вам представлять больше типов данных, чем java.util.Date и java.util.Calendar. Для этого хорошо подходит Joda Time, а в Java 8 есть новый API java.time.*. Я настоятельно рекомендую вам перейти на один из них как можно скорее.

person Jon Skeet    schedule 18.07.2014

tl;dr

LocalDate.of( 2014 , Month.NOVEMBER , 22 )
         .atStartOfDay( ZoneId.of ( "Asia/Kolkata" ) )
         .toInstant()
         .toEpochMilli()

Подробности

Ответ Джона Скита правильный и мудрый.

Вот пример кода с использованием классов java.time.

LocalDate

Класс LocalDate представляет значение без времени суток и без часового пояса.

Часовой пояс имеет решающее значение при определении даты. В любой момент дата варьируется по всему земному шару в зависимости от зоны. Например, через несколько минут после полуночи в Париже, Франция наступает новый день, хотя " вчера» в Монреаль, Квебек.

ZoneId z = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( z );

Вы можете указать LocalDate.

LocalDate ld = LocalDate.of( 2014 , Month.NOVEMBER , 22 );

ld.toString (): 22 ноября 2014 г.

ZonedDateTime

Вам нужно количество миллисекунд с начала эпохи. Я не рекомендую использовать счетчик от эпохи для обработки даты и времени. Но если вы настаиваете, поехали.

Отсчет от эпохи в миллисекундах означает, что нам нужна дата и время дня. У нас свидание. Я предполагаю, что вы хотите, чтобы первый момент дня был временем суток. Не не предполагайте, что это время 00:00:00. Аномалии, такие как переход на летнее время (DST), могут означать, что день начинается в другое время, например 01:00:00. Пусть java.time определит этот первый момент, сгенерировав объект ZonedDateTime из объекта LocalDate.

LocalDate ld = LocalDate.of ( 2014 , Month.NOVEMBER , 22 );
ZoneId z = ZoneId.of ( "Asia/Kolkata" );
ZonedDateTime zdt = ld.atStartOfDay ( z );

zdt.toString(): 2014-11-22T00:00+05:30[Азия/Калькутта]

Instant

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

Instant instant = zdt.toInstant ();

Instant.toString(): 2014-11-21T18:30:00Z

С момента мы можем запросить количество миллисекунд с эпохи. Имейте в виду, что это влечет за собой потерю данных, так как любые наносекунды будут сокращены до миллисекунд.

long epochMillis = instant.toEpochMilli();

java.util.Date

Я предлагаю избегать устаревших классов даты и времени. Но если вы должны, вы можете конвертировать. Обратите внимание на новые методы, добавленные к старым классам, такие как java.util.Date< /а>.

java.util.Date utilDate = java.util.Date.from( instant );

О java.time

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

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

Чтобы узнать больше, см. учебник по Oracle. И поищите множество примеров и пояснений в Stack Overflow. Спецификация: JSR 310.

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

  • Java SE 8 and SE 9 and later
    • Built-in.
    • Часть стандартного Java API со встроенной реализацией.
    • Java 9 добавляет некоторые незначительные функции и исправления.
  • Java SE 6 and SE 7
    • Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
  • Android

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

person Basil Bourque    schedule 12.10.2016