2015-06-29 1 views
4

Я искал это некоторое время, пока не добился успеха. Знаете ли вы, есть ли класс «DateFormat» ish, который позволит мне использовать «00:00:00» и «24:00:00» в качестве входных параметров (они оба полночь), но при вызове «getHour() «В результате я получу 0 или 24?(Простой) DateFormat, который позволяет 24:00:00 и 00:00:00 в качестве входных данных

Использование «кк» только позволит мне иметь < 1:24> диапазон, тем временем я ищу < 0:24> Диапазон форматирования

+1

Формат <0:24> не имеет никакого смысла. Или, если это так, <0:25>, или <0:26>, или <0:29293> и т. Д., Потому что все они перевернуты на 24-часовой лимит, так что все они одинаково «легальны». В формате 24-часовой синхронизации первая минута 00:00, а в последнюю минуту 23:59 Через минуту после 23:59 снова 00:00. 24:00 не существует – deyur

+0

@ deyur ваше мышление hh, в котором часы 1-23, часы в kk 1-24. – UnknownOctopus

+1

@UnknownOctopus Я думая о hh, потому что OP хочет, чтобы час начался в 0. Я согласен с вами в том, что kk часов 1-24, но это все равно не делает 0-24 законным (в любом формате). – deyur

ответ

4

Прежде всего, давайте ясно, что время 24:00 действительный ISO-8601-время. Цитирование из ISO-8601:

4.2 Time of day 
4.2.1 General 
    This International Standard is based on the 24-hour timekeeping System 
    that is now in common use. In expressions of time of day 
    hour is represented by two digits from [00] to [24]. The representation 
    of the hour by [24] is only allowed to indicate the end of a calendar 
    day, see 4.2.3. 

сам Java не поддерживает 24:00, если не используется режим снисходительны парсинга из SimpleDateFormat. Но даже тогда поддержка недоступна, потому что если вы спросите результат (пример java.util.Date) за час, когда вы получите нуль, как вы уже заметили. Подобные мысли действительны для java.util.GregorianCalendar. После разбора нет возможности определить, был ли вход 24:00 или нет (не зная, какой исходный вход был).

Java-8 также не имеет реальной поддержки для этого специального часа. Лучшее, что вы можете здесь сделать, это использовать parseExcessDays(), применяемый к сырым разобранным данным DateTimeFormatter. Вы можете использовать обходной путь, как это:

String input = "24:00:00"; 
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("HH:mm:ss"); 
TemporalAccessor raw = dtf.parse(input); 
int hour = raw.query(LocalTime::from).getHour(); 
Period period = raw.query(DateTimeFormatter.parsedExcessDays()); 
if (period.equals(Period.ofDays(1))) { 
    hour = 24; 
} 
System.out.println("iso-hour=" + hour); // output: iso-hour=24 

Популярная третья сторона библиотека Joda времени не имеет поддержки 24:00. Ситуация аналогична SimpleDateFormat.

Единственная библиотека со встроенной поддержкой, о которой я знаю, это Time4J, которую я написал сам. Полная поддержка ограничена PlainTime (аналогичный кулон LocalTime), недействительный для полных дат-представлений (где это было бы двойственным, временные метки, содержащие 24:00, будут автоматически нормализованы до следующего дня в 00:00):

PlainTime time = Iso8601Format.EXTENDED_WALL_TIME.parse("24:00:00"); 
System.out.println(time.get(PlainTime.ISO_HOUR)); // 24 

Обратите внимание, что пространство состояний класса PlainTime немного расширено, так что оно может удерживать это специальное значение времени ISO. Поэтому прямой доступ как записать программное это возможно:

PlainTime time24 = PlainTime.midnightAtEndOfDay(); // or: PlainTime.of(24, 0); 
System.out.println(time24); // T24 
+0

Вероятно, я рассмотрю введение [нового типа шаблонов для следующей версии Time4J] (https://github.com/MenoData/Time4J/issues/314) на основе CLDR с отклонением H = iso-hour в диапазоне 0-24. –

7

Значение 24:00 не представлен в LocalTime, потому что это строго часть следующего дня. Были рассмотрены модели, где 24:00 мог быть представлен как часть LocalTime, но было заключено, что это было бы очень запутанным во многих случаях использования и создавало больше ошибок, чем оно решает.


Существует поддержка 24:00 в java.time однако. Это вполне возможно для его анализа с использованием стандартных методов форматирования, однако необходимо использовать режим SMART или LENIENT, см. ResolverStyle. Режим по умолчанию - SMART, но константы форматирования на DateTimeFormatter, такие как DateTimeFormatter.ISO_LOCAL_DATE_TIME, находятся в режиме STRICT.Таким образом, ofPattern() по умолчанию SMART режим:

static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm"); 

LocalDateTime ldt = LocalDateTime.parse("2012-12-03T24:00", FORMATTER); 
System.out.println(ldt); // 2012-12-04T00:00 

Обратите внимание, что это также работает для OffsetDateTime и ZonedDateTime. Стандартный анализатор для Instant поддерживает 24:00 без специального форматера:

Instant instant = Instant.parse("2015-01-01T24:00:00Z"); 
System.out.println(instant); // 2015-01-02T00:00:00Z 

Любого форматер может быть преобразован в SMART или снисходителен режим с использованием withResolverStyle() следующим образом:

DateTimeFormatter f = ... // obtain a formatter somehow 
DateTimeFormatter smartMode = f.withResolverStyle(ResolverStyle.SMART); 

// for example 
f = DateTimeFormatter.ISO_LOCAL_DATE_TIME.withResolverStyle(ResolverStyle.SMART); 

вторым элементом поддержки является parseExcessDays(). Это позволяет лишний день можно получить, когда только время разбираемый:

static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("HH:mm"); 

TemporalAccessor parsed = TIME_FORMATTER.parse("24:00"); 
LocalTime lt = LocalTime.from(parsed); 
Period excessDays = parsed.query(DateTimeFormatter.parsedExcessDays()); 
System.out.println(lt + " + " + excessDays); // 00:00 + P1D 

Наконец, записка для продвинутых пользователей. Теоретически можно написать собственную версию Temporal, которая является копией LocalTime, но с поддержкой 24:00 в качестве действительного значения. Такой класс, скажем, LocalTimeWithEndOfDay, мог бы без проблем работать с форматированием/парсером (и может сделать хорошее дополнение к ThreeTen-Extra.

+0

Ну, я думаю, что реальная проблема OP - это не о снисхождении (умный, строгий и т. Д., См. Также «SimpleDateFormat» в режиме снисходительности), но о том, как достичь функции 'getHour() == 24' в анализируемом результате, если вход «24:00:00». Таким образом, единственный элемент поддержки в Java-8 ограничен «parseExcessDays()» (и абстрактный вариант для реализации нового «Temporal'-класса). Вы согласны? –