我正在使用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分钟的(错误)时间。
答案 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)