Несовместимый разбор дат с использованием SimpleDateFormat - PullRequest
10 голосов
/ 21 августа 2009

Я действительно почесал голову от этого. Я использовал SimpleDateFormat s без проблем некоторое время, но теперь, использование SimpleDateFormat для анализа дат (только иногда) просто неправильно.

В частности:

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
Date date = sdf.parse("2009-08-19 12:00:00");
System.out.print(date.toString());

печатает строку Wed Aug 19 00:00:00 EDT 2009. Какого черта? - он даже не разбирает неправильную дату все время!


Обновление: Это прекрасно исправлено. Разве вы не знаете, это неправильно использовалось и в нескольких других местах. Должен любить отладку чужого кода:)

Ответы [ 4 ]

25 голосов
/ 21 августа 2009

Я думаю, что вы хотите использовать формат HH, а не 'hh', чтобы использовать часы между 00-23. «чч» принимает формат с шагом 12 часов, поэтому он предполагает, что он находится в AM.

Итак, это

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = sdf.parse("2009-08-19 12:00:00");
System.out.print(date.toString());

Следует распечатать

Ср 19 августа, 12:00:00 ПО ВОСТОЧНОМУ ВРЕМЕНИ 2009

3 голосов
/ 21 августа 2009

Час должен быть указан как ЧЧ, а не ЧЧ. Ознакомьтесь с разделом «Шаблоны даты и времени» в http://java.sun.com/javase/6/docs/api/java/text/SimpleDateFormat.html

2 голосов
/ 21 августа 2009

Вы печатаете представление даты toString (), а не представление формата. Вы также можете проверить представление часов. Н и ч означают что-то другое. H - для 24-часовых часов (0-23), h - для 12-часовых часов (1-12), (также есть k и K для значений времени 1-24 и 0-11 соответственно)

Вам нужно сделать что-то вроде:

//in reality obtain the date from elsewhere, e.g. new Date()
Date date = sdf.parse("2009-08-19 12:00:00"); 

//this format uses 12 hours for time
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
//this format uses 24 hours for time
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

System.out.print(sdf.format(date));
System.out.print(sdf2.format(date));
1 голос
/ 20 августа 2016

ТЛ; др

LocalDateTime ldt = LocalDateTime.parse( "2009-08-19 12:00:00".replace( " " , "T" ) );

java.time

Другие ответы верны, но используют устаревшие классы даты и времени. Эти неприятные старые классы были вытеснены классами java.time.

Ваша строка ввода близка к стандартному ISO 8601 формату. Твик, заменив пространство в середине с T. Затем его можно проанализировать без указания шаблона форматирования. Классы java.time по умолчанию используют ISO 8601 при разборе / генерации строк.

String input = "2009-08-19 12:00:00".replace( " " , "T" );

Входные данные не содержат информации о смещение от UTC или часовом поясе. Таким образом, мы разбираем как LocalDateTime.

LocalDateTime ldt = LocalDateTime.parse( input );

Если по контексту вы знаете предполагаемое смещение, примените его. Возможно, он был предназначен для UTC (смещение нуля), где мы можем использовать константу ZoneOffset.UTC.

OffsetDateTime odt = ldt.atOffset( ZoneOffset.UTC );

Или, возможно, вы знаете, что он предназначен для определенного часового пояса. Часовой пояс - это смещение плюс набор правил для обработки аномалий, таких как летнее время (DST).

ZonedDateTime zdt = ldt.atZone( ZoneId.of( "America/Montreal" ) );

О java.time

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

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

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

Большая часть функциональности java.time перенесена на Java 6 & 7 в ThreeTen-Backport и дополнительно адаптирована для Android в ThreeTenABP (см. Как использовать… ).

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

...