2013-07-03 65 views
3

我目前正在验证生成的Excel工作表包含正确呈现的“时间戳”,其日期和时间部分在单独的单元格中,并且其格式通过语言环境进行调整。使用新日期创建Java日期时忽略夏令时(aDate.getTime()+ aTime.getTime())

我的测试用例失败了,因为当我从字符串中读取Excel工作表的时间时,似乎忽略了夏令时。

这里是我的Java代码:

Date now = new Date(); 

    // [... other code, creating and reading the Excel sheet etc. ...] 

    // from an Excel sheet 
    String dateString = cellB2.getStringCellValue(); // e.g., 3.7.2013 
    String timeString = cellB3.getStringCellValue(); // e.g., 13:38:09 

    TimeZone tz = TimeZone.getDefault(); // Berlin, CEST 
    dateFormat.setTimeZone(tz); // dateFormat is result of DateFormat.getDateInstance(DateFormat.MEDIUM, locale); e.g. with locale "cs_CZ" 
    timeFormat.setTimeZone(tz); // timeFormat is result of DateFormat.getTimeInstance(DateFormat.MEDIUM, locale); e.g. with locale "cs_CZ" 

    // try to parse the time/date strings using the expected format 
    Date actualDate = dateFormat.parse(dateString); // e.g., Wed Jul 03 00:00:00 CEST 2013 
    Date actualTime = timeFormat.parse(timeString); // e.g. Thu Jan 01 13:38:09 CET 1970 

    // now: e.g. Wed Jul 03 13:38:09 CEST 2013 
    // actualDateTime: e.g. Wed Jul 03 12:48:07 CEST 2013 
    Date actualDateTime = new Date(actualDate.getTime() + actualTime.getTime()); 
    assertFalse(now.after(actualDateTime)); // fails 
+1

首先我不喜欢你解析的方式。我首先要连接两个输入字符串(在它们之间有空格),然后只进行一个解析。我不是100%确定当你解析一个没有日期值的时间时会发生什么,可能是它将当前日期作为默认值,还是真的考虑0 + timeConversion?我希望看到什么actualDate和ActualTime返回,如果你格式化他们...此代码以前工作? – Martin

+0

不,代码没有工作过。 关于仅使用一个解析:我无法找到一种方法从DateFormats中获取模式而不投射 - 是否有任何? – RobertG

+0

关于解析一个只显示时间的字符串,你可能是对的:评论显示actualTime似乎是关闭一个小时(CET而不是CEST),但我想知道是否可以阻止。显然,setTimeZone()不起作用。 – RobertG

回答

1

继双方马丁和马特的建议,这是我最后的程序片断:

// from an Excel sheet 
    String dateString = cellB2.getStringCellValue(); 
    String timeString = cellB3.getStringCellValue(); 

    TimeZone tz = TimeZone.getDefault(); 

    // NEW! 
    DateFormat dateTimeFormat = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM, l); 
    dateTimeFormat.setTimeZone(tz); 

    Date actualDateTime = dateTimeFormat.parse(dateString + " " + timeString); 
    assertFalse(now.after(actualDateTime)); 
0

设置actualTime后,我必须作出以下区别:

if (tz.inDaylightTime(actualDate)) { 
     actualTime = new Date(actualTime.getTime() + 1000 * 60 * 60); 
    } 

随着时间的唯一字符串总是会导致一个日期1月1日1970年,夏令时永远不会考虑(至少不是柏林的情况),我必须手动进行调整。

+2

实际上,在1970年1月1日期间,一些时区*是夏令时。具体来说,英国是BST而不是GMT。 –

+0

谢谢,我改变了答案。 – RobertG

2

罗伯特,

您的解决方案的工作,但我认为这是喜欢拍各地的另外一个解决方法,它使你的代码更复杂,因此更难十个分量。为什么不使用的SimpleDateFormat使用此模式:

"dd.MM.YYYY kk:mm:ss" 

然后,只需做一个日期字符串是这样的:

String dateTime = cellB2.getStringCellValue() + " " + cellB3.getStringCellValue(); 

然后你可以解析它...我没有实际测试它,但它应该给你的想法,也许你需要检查的模式String,这里的参考:

http://docs.oracle.com/javase/1.4.2/docs/api/java/text/SimpleDateFormat.html

问候

+0

这些模式是我输入的一部分:它们使用\t DateFormat.getDateInstance(...)和DateFormat.getTimeInstance(...)检索。但我想我会给DateFormat.getDateTimeInstance(...)一个镜头 - 否则,我将不得不将DateFormat转换为SimpleDateFormat或其他东西,我不想这样做。 – RobertG

+0

为什么不使用SimpleDateFormat来代替?因此,您可以在构造函数中传递该模式,并使其表现得与您需要的一样。它看起来像这样SimpleDateFormat dateTimeFormat = new SimpleDateFormat(“dd.MM.YYYY kk:mm:ss”);你不需要施放任何东西...... – Martin

+1

当分别解析时可能会出现其他细微差别,所以我强烈推荐这种方法。例如,如果午夜的日期是模糊的DST回滚转换的一部分,但在特定时间处于正常状态,会发生什么情况?在午夜肯定有时区转换(例如巴西)。 –

0

日期在Java中不会自动添加日光节约时间。这是因为java Date是通过epoch(自1970年1月1日以来的秒数)计算出来的,并且表示UTC时间。

如果您希望您正在使用的课程自动更正夏令时,则可以使用内置的Calendar类或Joda Time。我真的建议看看乔达时间。它优于java.util.Date的java.sql.Date和java.util.Calendar的组合!处理一个真正完整的时间库要比处理三个不同的时间库更容易,并尝试在它们之间进行转换。

此外,正如一个有趣的文章,显示了DST的难度,请参阅this video - 大约4分钟时间,它解释了不同国家如何实施DST以及这对每个人造成的头痛。