从String转换日期时,为什么它与Java时区不同?

时间:2013-03-17 10:20:40

标签: java date timezone date-format gmt

我的日期字符串格式为YYYYMMDD,我试图使用日期格式化程序解析为日期

public static DateFormat getDateFormat() {
  SimpleDateFormat result = new SimpleDateFormat("yyyyMMdd");                  
  result.setLenient(false);
  return result;
}

我在程序运行时设置默认时区

public static void doTheDateZoneInit() {
    TimeZone tzone = TimeZone.getTimeZone("Europe/London");
    TimeZone.setDefault(tzone);
}

当我格式化日期并输出时没有在打印字符串中指定时区

Date myDate= getDateFormat().parse("20110331");
System.out.println("Date after it is formatted:" + myDate);

输出位于BST时区

Date after it is formatted:Thu Mar 31 01:00:00 BST 2011

如果我在不同的日期反复运行,我会得到不同的输出

  • 20120331>> BST>>格式化后的日期:星期三3月31日01:00:00 BST 2012
  • 20121231>> GMT>>格式化后的日期:Mon Dec 31 00:00:00 GMT 2012
  • 20130328>> GMT>>格式化后的日期:Thu Mar 28 00:00:00 GMT 2013
  • 20130331>> GMT>>格式化后的日期:Sun Mar 31 00:00:00 GMT 2013
  • 20140331>> BST>>格式化后的日期:Mon Mar 31 01:00:00 BST 2014
  • 20130401>> BST>>格式化后的日期:Mon Apr 01 01:00:00 BST 2013
  • 20130402>> BST>>格式化后的日期:Tue Apr 02 01:00:00 BST 2013
  • 20130501>> BST>>格式化后的日期:Wed May 01 01:00:00 BST 2013

似乎在2012年到2013年有一个范围,所有都计算到GMT。我不知道为什么会这样。

问题是我在这些日期添加了结束时间...... 例如我使用从String转换的日期调用以下方法,并向其添加23:59:59:999以获取指定日期的最新时间。

public static Date addAlmostOneDay(Date startDate) {
    Calendar cal = new GregorianCalendar();
    cal.setTime(startDate);
    cal.add(Calendar.HOUR, 23);
    cal.add(Calendar.MINUTE, 59);
    cal.add(Calendar.SECOND, 59);
    cal.add(Calendar.MILLISECOND, 999);
    return cal.getTime();
}

但是如果我要添加23:59:59而转换为GMT的情况......它没有将日期设置为原始日期的结尾,而是将BST和GMT之间的时间差异考虑在内

  • Sun Mar 31 00:00:00 GMT 2013成为2013年4月1日00:59:59 BST 2013(第二天+ 1小时) 而
  • Mon Apr 01 01:00:00 BST 2013成为Mon Apr 01 23:59:59 BST 2013(今天的结束是我想要的)

有人可以详细说明为什么这似乎在起作用。使用YYYMMDD格式的不同输入运行相同的代码?

2 个答案:

答案 0 :(得分:5)

好吧,我想我明白你的意思了。您将默认时区设置为伦敦时区。

今年夏天,伦敦正处于英国夏令时(BST)时区。在冬天,它是在GMT时区。而且这个时区变化的日子每年都有所不同。

答案 1 :(得分:2)

BST是英国的夏季时间,是2013年3月31日至2013年10月27日,2014年3月30日至2014年10月26日伦敦的有效时区。

在这些日期之间选择欧洲/伦敦作为时区,将给你BST,在冬季伦敦的正确时区是GMT,这与你的输出一致。