Как правильно создать временную метку в Java? - PullRequest
2 голосов
/ 21 декабря 2011

Для года, месяца, дня, часа, минуты и секунды, как правильно создать метку времени Java UTC (GMT)?

Варианты, которые я рассмотрел, но еще предстоит убедиться:

1 - использовать устаревшие конструкторы Date

java.util.Date date = new java.util.Date(year - 1900, month, dayOfMonth, hour, minute, second);
long timestamp = date.getTime();

2 - использовать календарь с часовым поясом, установленным в GMT

Calendar c = Calendar.getInstance(TimeZone.getTimeZone("GMT")); 
c.set(Calendar.YEAR, year);
c.set(Calendar.MONTH, month);
c.set(Calendar.DAY_OF_MONTH, dayOfMonth);
c.set(Calendar.HOUR_OF_DAY, hour);
c.set(Calendar.MINUTE, minute);
c.set(Calendar.SECOND, second);
c.set(Calendar.MILLISECOND, 0);
long timestamp = c.getTimeInMillis();

Одна из моих проблем с этим заключается в том, что мне очень трудно тестировать, не путаясь с другими проблемами TimeZone.

Есть ли определенный правильный способ сделать это со стандартными API?

Обновление: хотел бы получить ответ на этот вопрос, используя стандарт JavaSE. Я знаю, что Joda-Time прекрасна, но в данном случае это не вариант.

Ответы [ 4 ]

2 голосов
/ 21 декабря 2011

Нет, нет (если вы не можете использовать Joda-Time ), правильный способ - использовать Календарь , а API календаря - безобразно в данный момент никто ничего не может с этим поделать.

1 голос
/ 21 декабря 2011

Я думаю, что это будет работать очень хорошо

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ssZ");
Date date = sdf.parse("2011-12-21 12:00:00+0000");

Вы должны построить строку даты самостоятельно, но она короткая и должна работать нормально. И создайте SimpleDateFormat по своему вкусу, важной частью является Z, который соответствует "+0000".

Вот еще один альтернативный способ на тех же строках

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
Date date = sdf.parse("2011-12-21 12:00:00");

Это с явным часовым поясом, и Z удаляется.

1 голос
/ 21 декабря 2011

Стандартные API Java для дат довольно неудобны.Попробуйте использовать Joda-Time :

long timestamp = new LocalDateTime(year, month, day, hour, minute, second)
    .getLocalMillis();
0 голосов
/ 17 февраля 2018

ТЛ; др

OffsetDateTime.of( 2018 , 1 , 23 , 12 , 34 , 56 , 0, ZoneOffset.UTC )

java.time

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

В отличие от утомительных устаревших классов даты и времени, java.time классы используют вменяемую нумерацию:

  • 2018 означает 2018 год. (Без сумасшедшей математики с 1900 года.)
  • 1-12 по месяцам январь-декабрь. (Не глупо 0-11.)
  • 1-7 для понедельника-воскресенья для Стандартное определение недели ISO 8601 . (Не зависит от региона.)

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

Вы, если хотите, однострочник, если разбираете строку.

Instant instant = Instant.parse( "2018-01-23T12:34:56Z" ) ;

Хотя Instant является базовым классом строительных блоков для java.time , класс OffsetDateTime более гибок. Для вашего удобства смещение от UTC для UTC определено как константа .

OffsetDateTime odt = OffsetDateTime.of( 2018 , 1 , 23 , 12 , 34 , 56 , 0, ZoneOffset.UTC ) ;

Лично я предпочитаю использовать кусочки.

Вместо простого целого числа для месяца вы можете указать Month объект перечисления.

LocalDate ld = LocalDate.of( 2018 , Month.JANUARY , 23 ) ;  // Date-only, without time-of-day.
LocalTime lt = LocalTime.of( 12 , 34 , 56 ) ;  // Time-of-day, without date.
ZoneOffset offset = ZoneOffset.UTC ;
OffsetDateTime odt = OffsetDateTime.of( ld , lt , offset ) ;

О java.time

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

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

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

Используя драйвер JDBC , совместимый с JDBC 4.2 или более поздней версии, вы можете обмениваться java.time объектами непосредственно с вашей базой данных. Нет необходимости ни в строках, ни в java.sql. * Классах.

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

  • Java SE 8 , Java SE 9 и выше
    • Встроенный.
    • Часть стандартного Java API со встроенной реализацией.
    • Java 9 добавляет некоторые незначительные функции и исправления.
  • Java SE 6 и Java SE 7
    • Большая часть функциональности java.time перенесена в Java 6 & 7 в ThreeTen-Backport .
  • Android
    • Более поздние версии Android связывают реализации классов java.time.
    • Для более ранних версий Android проект ThreeTenABP адаптируется ThreeTen-Backport (упоминалось выше). См. Как использовать ThreeTenABP… .

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

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