it-swarm.com.ru

Установите часы, минуты и секунды на 00 в ZonedDateTime или Instant

У меня есть строка даты в формате Utc -

    String dateStr = "2017-03-03T13:14:28.666Z";

И я хочу преобразовать его в формат ниже в представлении даты Java в ZonedDateTime .

Когда ZonedDateTime печатается, это должно показать 

    String dateStr = "2017-03-03T00:00:00.000Z";

Я пробовал следующий код -

    String timeZone = "America/Los_Angeles";
    DateTimeFormatter dtf1 = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSX");
    DateTimeFormatter dtf2 = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    ZoneId zoneId1 = ZoneId.of(timeZone);
    String dateStr = "2017-03-03T13:14:28.666Z";
    Instant inst = Instant.parse(dateStr, dtf2);


    ZonedDateTime dateTimeInTz = ZonedDateTime.ofInstant(inst, zoneId1);

    ZonedDateTime startTime = dateTimeInTz.with(LocalTime.of(0, 0, 0, 0));
    ZonedDateTime endTime = dateTimeInTz.with(LocalTime.MAX);

    System.out.println("Start:"+startTime+", End:"+endTime);
    System.out.println("Start:"+startTime.toString()+", End:"+endTime.toString());  

    ZonedDateTime nT = ZonedDateTime.of ( LocalDate.parse(dateStr, dtf1) , LocalTime.of (0,0,0,0) , ZoneId.of ( timeZone ) );

    System.out.println("Start:"+nT);

Результат:

Start:2017-03-03T00:00-08:00[America/Los_Angeles], End:2017-03-03T23:59:59.999999999-08:00[America/Los_Angeles]
Start:2017-03-03T00:00-08:00[America/Los_Angeles], End:2017-03-03T23:59:59.999999999-08:00[America/Los_Angeles]
Start:2017-03-03T00:00-08:00[America/Los_Angeles]

Я хочу, чтобы время начала было нормализовано в ZonedDateTime . Я хочу добиться этого, используя только библиотеки Java, а не сторонние библиотеки.

6
WitVault

тЛ; др

Вы слишком усердно работаете.

Instant.parse( "2017-03-03T13:14:28.666Z" )
       .truncatedTo( ChronoUnit.DAYS )
       .toString()

2017-03-03T00: 00.00Z

Подробности

Что означает «нормализовано в ZonedDateTime»? Пожалуйста, отредактируйте свой вопрос, чтобы уточнить.

Когда ZonedDateTime напечатан, он должен показать… "2017-03-03T00: 00: 00.000Z"

То, что вы спрашиваете, является противоречием. ZonedDateTime имеет назначенный часовой пояс для времени, когда вы хотите посмотреть момент времени по часам определенного региона. Поэтому просить ZonedDateTime генерировать строку в UTC, такую ​​как "2017-03-03T00:00:00.000Z", не имеет смысла. Z является сокращением от Zulu и означает UTC. 

Ваша входная строка в стандартном формате ISO 8601. Классы Java.time по умолчанию используют эти стандартные форматы. Поэтому нет необходимости указывать шаблон форматирования, нет необходимости в классе DateTimeFormatter.

Анализировать как Instant, точку на временной шкале в UTC с разрешением наносекунд. 

Instant instant = Instant.parse( "2017-03-03T13:14:28.666Z" );

Если вы хотите полночь в UTC, обрежьте. 

Instant instantMidnightUtc = instant.truncatedTo( ChronoUnit.DAYS );

instantMidnightUtc.toString (): 2017-03-03T00: 00.00Z

Нет необходимости в классе ZonedDateTime.

Если вы хотите работать только с датой без какого-либо времени суток и без часового пояса, используйте класс LocalDate.

Кстати, не думайте, что первый момент дня всегда 00:00:00. Это верно для UTC. Но различные часовые пояса могут иметь аномалии, такие как переход на летнее время (DST), когда день может начинаться в другое время суток, такое как 01:00:00.


О Java.time

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

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

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

Где взять классы Java.time? 

  • Java SE 8 и SE 9 и более поздние версии
    • Встроенный. 
    • Часть стандартного Java API со встроенной реализацией.
    • Java 9 добавляет некоторые незначительные функции и исправления.
  • Java SE 6 и SE 7
    • Большая часть функциональности Java.time перенесена в Java 6 & 7 в ThreeTen-Backport .
  • Android

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

17
Basil Bourque
   String timeZone = "America/Los_Angeles";
    DateTimeFormatter dtf1 = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSX");
    DateTimeFormatter dtf2 = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    ZoneId zoneId1 = ZoneId.of(timeZone);
    String dateStr = "2017-03-03T13:14:28.666Z";
    Instant inst = Instant.parse(dateStr, dtf2);


    ZonedDateTime dateTimeInTz = ZonedDateTime.ofInstant(inst, zoneId1);

    ZonedDateTime startTime = dateTimeInTz.with(LocalTime.of(0, 0, 0, 0));
    ZonedDateTime endTime = dateTimeInTz.with(LocalTime.MAX);

    String strStart = (startTime.toString().split("T"))[0] + "T00:00:00.000Z";
    String strEnd  =  (endTime.toString().split("T"))[0] + "T00:00:00.000Z";

    System.out.println("Start:"+strStart +", End:"+strEnd  );

РЕДАКТИРОВАТЬ новый метод:

TimeZone timeZone = TimeZone.getTimeZone("Europe/Copenhagen");
Calendar cal = Calendar.getInstance(timeZone);
Calendar defaut = new GregorianCalendar( cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH),0,0,0);

Вы просто должны получить все необходимые поля. С, например, dateFormat.

Надеюсь, это поможет вам

0
hartar