我正在尝试解析这样的日期:
DateFormat df = new SimpleDateFormat("MMM dd, yyyy K:mm:ss,SSS a z", Locale.ENGLISH);
Date date = df.parse("Oct 04, 2015 2:11:58,757 AM UTC");
我的价值是5小时,因为我住的是UTC + 3时区。但是我需要具有2am的值,但是,使用相同的格式字符串(以指定格式给出的日期字符串,我不允许更改)。怎么做?
更新:我不需要在适当的时区格式化日期,我需要通过没有时区的值来比较这些日期。我想要确切地说该日期已经解析了忽略原始字符串中的时区 - 并且总是在同一时区(例如我的),无论包含原始字符串:UTC或UTC + 3还是其他什么。
答案 0 :(得分:6)
accepted Answer工作太辛苦了。操纵偏移是日期时间库的范畴。自己做这样的工作是浪费你的时间,并可能成为错误的来源。
旧的java.util.Date/.Calendar类非常麻烦。避免他们。而是使用java.time或Joda-Time。
Java 8及更高版本内置了一个新的java.time框架。
你的问题很困惑。你说你想忽略时区,但是你接受了一个确实解析并处理时区的答案。然后,该答案通过偏移调整结果。所以,似乎你不想要忽略时区。
实际上,忽略时区很少有意义。也许你想比较柏林和底特律的一对工厂,看看他们是否同时休息。在这种情况下,您要比较各自的wall-clock time。 java.time框架为此提供了“Local”类:LocalDate
,LocalTime
和LocalDateTime
。但根据我的经验,这在大多数业务场景中很少需要。这些对象与时间轴无关。
所以你做想要的就是能够比较不同时区的日期时间值。 java.time类隐式地执行此操作。具有各种指定时区的ZonedDateTime
个对象可以使用isBefore
,isAfter
和isEqual
方法相互比较。
首先我们解析输入字符串。
z
模式代码意味着期望和解析时区。如果未指定其他特定时区,则还将为结果日期时间对象分配此对象。
我们还为Locale
对象分配了一个人类语言组件,该组件与我们希望在输入字符串中看到的文本相匹配。在这种情况下,我们需要任何带英语的Locale。
String input = "Oct 04, 2015 2:11:58,757 AM UTC";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "MMM dd, yyyy K:mm:ss,SSS a z" ).withLocale( Locale.ENGLISH );
ZonedDateTime then = ZonedDateTime.parse( input, formatter );
接下来,我们获取Québec的当前时间。这个任意选择的时区将进一步说明我们可以将这个ZonedDateTime
对象与另一个具有不同时区的对象进行比较。具体而言,与分配给我们上面的then
对象的UTC时区进行比较。
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime now = ZonedDateTime.now( zoneId );
进行比较。
Boolean isThenBeforeNow = then.isBefore( now );
顺便说一下,一般来说,日期时间工作的最佳做法是将所有日期时间值转换为UTC时区,以进行业务逻辑,存储和数据交换。只在需要时调整到时区以满足用户对屏幕或报告的期望。
ZonedDateTime nowUtc = now.withZoneSameInstant( ZoneOffset.UTC );
转储到控制台。
System.out.println( "input: " + input );
System.out.println( "then: " + then );
System.out.println( "now: " + now );
System.out.println( "isThenBeforeNow: " + isThenBeforeNow );
System.out.println( "nowUtc: " + nowUtc );
跑步时。
输入:2015年10月4日上午2:11:58,757 UTC
然后:2015-10-04T02:11:58.757Z [UTC]
现在:2015-10-19T19:28:04.619-04:00 [美国/蒙特利尔]
isThenBeforeNow:true
nowUtc:2015-10-19T23:28:04.619Z
java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.Date
,Calendar
和& SimpleDateFormat
现在位于Joda-Time的maintenance mode项目建议迁移到java.time类。
要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310。
您可以直接与数据库交换 java.time 对象。使用符合JDBC driver或更高版本的JDBC 4.2。不需要字符串,不需要java.sql.*
类。
从哪里获取java.time类?
ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如Interval
,YearWeek
,YearQuarter
和more。
答案 1 :(得分:1)
Upd2:已解决
好的,现在我得到了我想要的东西:
DateFormat df = new SimpleDateFormat("MMM dd, yyyy K:mm:ss,SSS a z", Locale.ENGLISH);
Date date = df.parse("Oct 04, 2015 2:11:58,757 AM UTC");
long diff = TimeZone.getDefault().getRawOffset() - df.getTimeZone().getRawOffset();
date = new Date(date.getTime()-diff);
无论如何,谢谢大家