为什么下午12:20解析到第二天0:20?

时间:2010-04-08 20:20:17

标签: java parsing date

我正在使用java.text.SimpleDateFormat来解析XML文档中日期/时间值的字符串表示。我看到所有时间都将12小时值转移到未来12小时,i。即中午20分钟被解析为第二天午夜过后20分钟。

我编写了一个单元测试,似乎确认在解析时发生了错误(我使用linux shell命令getTime()检查了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 个答案:

答案 0 :(得分:3)

如果在格式字符串中使用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 :(得分:3)

K中的SimpleDateFormat说明符为documented,使用从0开始的小时数。不确定如果要求它解析超出范围的值(如12),应该会发生什么......它可能就像你输入00:20 PM然后再增加12小时一样。

如果您想在第一个小时内使用12,请尝试使用h说明符。

为什么破坏的12小时时钟系统的恐怖不会消失?

答案 2 :(得分:1)

如果您使用K等等......(请阅读bobince的回答)

要强制执行预期的行为(并在使用12时抛出一个解析异常),请将解析器的lenient属性设置为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)

答案 3 :(得分:0)

作为旁注:我强烈建议改用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