Преобразовать в строку ISO со значениями по умолчанию - PullRequest
0 голосов
/ 09 июля 2020

Я хочу преобразовать дату, представленную строкой в ​​пользовательском формате, в формат ISO. Первый шаг довольно прост:

val parsed = DateTimeFormatter.ofPattern(pattern).parse(input)

Теперь я хочу представить это проанализированное значение в строке ISO, проблема в том, что входное значение может быть "13:35:23" с шаблоном "HH:mm:ss", и я хочу быть возможность преобразовать его в ISO, заполнив пропущенный год / месяц / день et c некоторыми значениями по умолчанию, например now(), поэтому результирующая строка будет, например, 2020-07-09T13:35:23.000Z

Аналогичное поведение имеет метод toIsoString() в JavaScript, если есть какие-то способы сделать это в Java?

PS Вход может содержать дату / зону / офсет, поэтому речь идет не только о шаблонах синтаксического анализа, таких как "ЧЧ : мм: сс "

Ответы [ 3 ]

2 голосов
/ 09 июля 2020

Используйте DateTimeFormatterBuilder, чтобы указать значения по умолчанию.

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.temporal.ChronoField;

class Main {


    public static void main(String[] args)  {
        LocalDateTime now = LocalDateTime.now();
        
        DateTimeFormatter formatter =
                // builder for formatters
                new DateTimeFormatterBuilder()

                // append both patterns inclosed by []
                .appendPattern("[yyyy-MM-dd HH:mm:ss][HH:mm:ss]")
                
                // provide defaults for year, month and day
                .parseDefaulting(ChronoField.YEAR_OF_ERA, now.getYear())
                .parseDefaulting(ChronoField.MONTH_OF_YEAR, now.getMonthValue())
                .parseDefaulting(ChronoField.DAY_OF_MONTH, now.getDayOfMonth())
                
                // build the formatter
                .toFormatter();
        
        String a = "13:35:23";
        String b = "1234-01-01 13:35:23";
        
        System.out.println(LocalDateTime.parse(a, formatter));
        System.out.println(LocalDateTime.parse(b, formatter));
        
        System.out.println(formatter.parse(a));
        System.out.println(formatter.parse(b));
    }
}

2 голосов
/ 09 июля 2020

tl; dr

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

Здесь мы получаем текущий момент, как показано в UT C. Затем мы переходим к желаемому времени суток.

OffsetDateTime.now( ZoneOffset.UTC ).with( LocalTime.parse( "13:35:23" ) ).toInstant().toString()         

Подробности

LocalTime

Анализируйте ваш ввод соответствующим образом.

LocalTime lt = LocalTime.parse( "13:35:23" ) ;

ZonedDateTime

Затем объедините с датой и часовым поясом, чтобы определить момент.

В любой данный момент дата меняется по всему земному шару в зависимости от часового пояса. Таким образом, здесь решающее значение имеет часовой пояс.

ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
LocalDate ld = LocalDate.now( z ) ;
ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z ) ;

Instant

Настройте на UT C, смещение нуля часов-минут-секунд, извлекая Instant.

Instant instant = zdt.toInstant() ;

Сгенерируйте строковый вывод в стандартном формате ISO 8691.

String output = instant.toString() ;

OffsetDateTime

Если вы хотите, чтобы были видны дата и введенное время для UT C, а не для другого часового пояса, используйте константу ZoneOffset.UTC. Используйте OffsetDateTime вместо ZonedDateTime. Используйте with, чтобы использовать альтернативную часть, например, здесь, где мы заменяем текущую часть времени дня введенным временем дня.

OffsetDateTime                      // Represent a moment as date,time, and offset -from-UTC (a number of hours-minutes-seconds).
.now( ZoneOffset.UTC )              // Capture current moment as seen in UTC.
.with( 
    LocalTime.parse( "13:35:23" )
)
.toInstant()                        // Extract the more basic `Instant` object, always in UTC by definition.
.toString()                         // Generate text representing the value of this date-time object. Use standard ISO 8601 format.

введите описание изображения здесь

2 голосов
/ 09 июля 2020

Если вы использовали LocalTime.parse вместо DateTimeFormatter.parse напрямую, вы получили бы объект «местного времени», который затем можно было бы добавить к «местной дате», давая вам дату и время:

LocalTime time = LocalTime.parse(input, DateTimeFormatter.ofPattern(pattern));
LocalDateTime dateTime = LocalDate.now().atTime(time)

Затем вы можете отформатировать dateTime в любом формате.

...