Почему 12:20 вечера разбираются на 0:20 на следующий день? - PullRequest
4 голосов
/ 09 апреля 2010

Я использую java.text.SimpleDateFormat для анализа строковых представлений значений даты / времени внутри XML-документа. Я вижу все времена, в которых значение часа 12 смещено на 12 часов в будущее, т.е. е. Анализ 20 минут после полудня означает 20 минут после полуночи следующего дня.

Я написал модульный тест, который, кажется, подтверждает, что ошибка произошла при разборе (я проверял возвращаемые значения из getTime() с помощью команды оболочки linux date). Теперь мне интересно:

  • есть ли ошибка в методе parse()?
  • что-то не так с входной строкой?
  • Я использую неверную строку формата для ввода?

Входные данные взяты из сервиса Yahoo YWeather. Вот тест и его вывод:

public class YWeatherReaderTest
{
    public static final String[] rgDateSamples = {
        "Thu, 08 Apr 2010 12:20 PM CEST",
        "Thu, 08 Apr 2010 12:20 AM CEST"
    };

    public void dateParsing() throws ParseException
    {
        DateFormat formatter = new SimpleDateFormat("EEE, dd MMM yyyy K:m a z",
                                                    Locale.US);
        for (String dtsSrc : YWeatherReaderTest.rgDateSamples) {
            Date dt = formatter.parse(dtsSrc);
            String dtsDst = formatter.format(dt);
            System.out.println(dtsSrc);
            System.out.println(dtsDst);
            System.out.println();
        }
    }
}
Thu, 08 Apr 2010 12:20 PM CEST
Fri, 09 Apr 2010 0:20 AM CEST

Thu, 08 Apr 2010 12:20 AM CEST
Thu, 08 Apr 2010 0:20 PM CEST

Вторая строка вывода второй итерации немного странная, потому что 00:20 не PM. Однако значение в миллисекундах объекта Date соответствует (неправильному) времени 20 минут после полудня.

Ответы [ 4 ]

3 голосов
/ 09 апреля 2010

Спецификатор K в SimpleDateFormat задокументирован для использования часов, начиная с 0. Не уверен, что должно произойти, если вы попросите его проанализировать значение вне диапазона, например 12 .. Это, вероятно, действует так, как будто вы вводите 00:20 PM, а затем добавляете дополнительные 12 часов.

Если вы хотите использовать 12 в течение первого часа, попробуйте вместо этого спецификатор h.

Почему ужас уже сломанной 12-часовой системы часов не умирает?

3 голосов
/ 09 апреля 2010

Если вы используете K в строке формата, она идет от 0 до 11 (поэтому 12:20 действительно должно быть 00:20). Вместо этого вы можете попробовать использовать h, то есть от 1 до 12, что вы и ожидали.

http://java.sun.com/j2se/1.4.2/docs/api/java/text/SimpleDateFormat.html

1 голос
/ 09 апреля 2010

Если вы используете K .... и т. Д. И т. Д. ... (прочитайте ответ Бобинса)

Чтобы вызвать ожидаемое поведение (и выдать исключение синтаксического анализа при использовании 12), установите для свойства анализатора значение false:

....
DateFormat formatter = new SimpleDateFormat("EEE, dd MMM yyyy K:m a z",
                                                Locale.US);
formatter.setLenient( false );
for (String dtsSrc : YWeatherReaderTest.rgDateSamples) {
....

Выход:

java YWeatherReaderTest
Exception in thread "main" java.text.ParseException: Unparseable date: "Thu, 08 Apr 2010 12:20 PM CEST"
at java.text.DateFormat.parse(DateFormat.java:335)
at YWeatherReaderTest.dateParsing(YWeatherReaderTest.java:17)
at YWeatherReaderTest.main(YWeatherReaderTest.java:25)
0 голосов
/ 09 апреля 2010

В качестве дополнительной отметки: я настоятельно рекомендую перейти на Joda Time.

Функции java.util.date имеют тенденцию просто угадывать (что в вашем случае оказалось не тем, что вы ожидали). Joda Time выдает исключение, если оно не соответствует спецификации.

Это близко к тому, что у вас есть:

String s = "Thu, 08 Apr 2010 12:20 PM";
String format = "EEE, dd MMM yyyy h:m a";
DateTimeFormatter fmt = DateTimeFormat.forPattern(format).withLocale(Locale.US);
System.out.println(fmt.parseDateTime(s));

Хотя Joda Time, похоже, еще не поддерживает разбор часового пояса (см. http://joda -time.sourceforge.net / api-release / org / joda / time / format / DateTimeFormat.html )

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