解析后,Java Date已经移动了几个小时

时间:2017-02-23 09:41:09

标签: java

我有一个休息服务,它将日期作为字符串,并且适配器将其解析为 java.util.date

p

private static final String FORMAT_DATE = "dd.MM.yyyy"; /* * Omitted. */ SimpleDateFormat sdf = new SimpleDateFormat(FORMAT_DATE); sdf.setLenient(false); try { setTime(sdf.parse(stringRealizationDate).getTime()); invalidDate = false; } catch (ParseException parseException) { invalidDate = true; LOG.error("Instantiation failed"); } 是:2017年2月23日,在解析之后它变成22.02.2017 23:00。 如何使它永远是23.02.2017 00:00没有任何时区方面?在任何情况下都不能转移。

1 个答案:

答案 0 :(得分:0)

如果不以某种方式定义时区,您不能依赖解析不明确包含时区信息的String。

this在内部使用SimpleDateFormat来存储解析结果。此日历将使用系统区域设置进行实例化,因此系统时区将实例化。您的Calendar将被视为与系统时区的上下文一起传递,该时区似乎为stringRealizationDate

现在,+01:00返回SimpleDateFormat.parse()。但是Date用于存储 UTC 值,因此Date时区偏移会导致在转换为 UTC 期间减去一个小时。

一种解决方案是在使用+01:00时设置正确的时区(+01:00),以便从 UTC Date的计算结果正确价值是例如印在屏幕上。但是在大型应用程序中进行管理是一种棘手的问题。

另一种解决方案是在调用+01:00之前使用SimpleDateFormat.setTimeZone()来明确定义格式化程序应该假设输入的时区(如果没有明确定义)。但是,始终带有 UTC 时区值的parse()的问题根本无法解决。

最好的解决方案是使用自Java8以来可用的新Time API。在您的案例LocalDate中,您有明确保存非时间值的类。

有趣的方法是LocalDate.parse(CharSequence text, DateTimeFormatter formatter),因为它允许您传递输入字符串并定义预期的日期格式。 但请注意,如果不传递时区(并对其时间部分进行假设),则无法将Date转换为Unix timestamp,因为它不代表时间点但是它的一个片段,日期部分。