更改日期对象的时区而不更改日期
我可以在不更改日期的情况下更改我的java代码中Date对象的时区吗? 当我写 Date date = new Date(longValue);
我在我的当地时区得到这个日期。我想得到这个日期,但我的时区应该是我的用户ID(例如“America/Chicago”)在DB(不是本地)中出现的时区。更改日期对象的时区而不更改日期
在此先感谢您的帮助。
TL;博士
ZonedDateTime zdtMontreal =
ZonedDateTime.now(ZoneId.of("America/Montreal"));
ZonedDateTime zdtAuckland =
zdtMontreal.withZoneSameLocal(ZoneId.of("Pacific/Auckland"));
不同一时刻。zdtAuckland
时刻。
要确定这是你的意图。我对你做错事感到心有余悸,对日期时间处理的工作方式感到困惑。日期时间工作是混淆。一定要搜索和研究堆栈溢出。
java.time
的Joda-Time项目,现在在maintenance mode,建议迁移java.time。
Local…
类故意没有时区或offset-from-UTC信息。
LocalDate ld = LocalDate.of(2016 , Month.January , 23); // 2016-01-23
LocalTime lt = LocalTime.of(12 , 34 , 56); // 12:34:56
这些值不尚未代表时间轴上的一个点。那是奥克兰新西兰,巴黎FR还是蒙特利尔CA的中午时间?我们必须应用时区来确定实际时刻。我们应用ZoneId
获得ZonedDateTime
。
在continent/region
的格式指定一个proper time zone name,如America/Montreal
,Africa/Casablanca
,或Pacific/Auckland
。切勿使用3-4字母缩写,如EST
或IST
或CST
,因为它们是而不是真正的时区,不是标准化的,甚至不是唯一的(!)。
ZoneId zMontreal = ZoneId.of("America/Montreal");
ZonedDateTime zdtMontreal = ZonedDateTime.of(ld , lt , zMontreal);
要看到代表在标准ISO 8601格式该值的字符串,调用toString
。实际上,ZonedDateTime
类通过在方括号中明智地附加时区名称来扩展标准格式。
String outputMontreal = zdtMontreal.toString();
2016-01-23T12:34:56-05:00 [美国/蒙特利尔]
要获得相同的日期和时间相同的日另一个时区,重复这个过程。
ZoneId zParis = ZoneId.of("Europe/Paris");
ZonedDateTime zdtParis = ZonedDateTime.of(ld , lt , zParis);
ZoneId zAuckland = ZoneId.of("Pacific/Auckland");
ZonedDateTime zdtAuckland = ZonedDateTime.of(ld , lt , zAuckland);
但是知道你在时间上得到一个不同时刻。奥克兰中午发生在巴黎中午前几个小时,而在蒙特利尔中午甚至更晚,因为三个不同时间点碰巧分享巧合wall-clock time。
2016-01-23T12:34:56-05:00 [美国/蒙特利尔]
2016-01-23T12:34:56 + 01:00 [欧洲/巴黎]
2016-01-23T12:34:56 + 13:00 [太平洋/奥克兰]
当前时刻
要获得当前时刻,请致电Instant.now
。 Instant
类表示UTC中时间轴上的一个时刻,分辨率为nanoseconds(小数点后最多九位数字)。
Instant instance = Instance.now();
将ZoneId
应用于调整到一个时区。
ZoneId z = ZoneId.of("America/Montreal");
ZonedDateTime zdt = instance.atZone(z);
对其他所需时区重复此过程,与我们在上面做的类似。
作为快捷方式,您可以直接获得ZonedDateTime
。
ZonedDateTime zdtMontreal = ZonedDateTime.now(ZoneId.of("America/Montreal"));
而作为另一种快捷方式,可以采用不同的时区,同时保持相同的日期和时间相同的日(相同挂钟时间)。致电ZonedDateTime::withZoneSameLocal
。
ZonedDateTime zdtAuckland = zdtMontreal.withZoneSameLocal(ZoneId.of("Pacific/Auckland"));
我再说一遍:这导致是在时间线上不同点。 zdtAuckland
正在zdtMontreal
发生前几个小时发生。
要保持同一时刻,请拨打ZonedDateTime::withZoneSameInstant
。
数据库
平时最好存储在数据库中UTC您的日期时间值。已经在Stack Overflow上进行了广泛的讨论。搜索更多信息。
关于java。时间
java.time框架内置于Java 8及更高版本中。这些类别取代了日期时间类别legacy,如java.util.Date
,Calendar
,& SimpleDateFormat
。
Joda-Time项目现在在maintenance mode中,建议迁移到java.time。请致电Oracle Tutorial。并搜索堆栈溢出了很多例子和解释。规格是JSR 310。
从何处获取java.time类?
-
Java SE 8和SE 9后来
- 内置。
- 带捆绑实现的标准Java API的一部分。
- Java 9增加了一些次要功能和修复。在ThreeTen-Backport
-
Java SE 6和SE 7
- 大部分的java.time功能后移植到Java 6 & 7。
-
Android
- 的ThreeTenABP项目适应ThreeTen-反向移植(上述)为Android特异性。
- 请参阅How to use…。
的ThreeTen-Extra项目与其他类扩展java.time。这个项目是未来可能增加java.time的一个试验场。您可以在这里找到一些有用的类,例如Interval
,YearWeek
,YearQuarter
和more。
你会发现ZonedDateTime
非常有帮助:
Java 8 Convert given time and time zone to UTC time
另外,您可以创建另一个Date
对象,并应用一些手动偏移到它。
我已经尝试过,但它并没有解决我的问题。我只想改变我的时区而不是约会。例如,我希望将这个日期11/23/2016,4:16 PM EST更改为2016/11/23,4:16 PM CST。这可能吗? – user3334226
如何使用Java8 ZonedDateTime
类做一个例子:
Date date = new Date(longValue);
ZoneId = ZoneId.of("America/Chicago");
ZonedDateTime dt = ZonedDateTime.ofInstant(date.toInstant(), zoneId);
您已经标记了与乔达的问题,但真正与Java8你不需要它了。
我已经尝试过,但它没有解决我的问题。我只想改变我的时区而不是约会。例如,我希望将这个日期11/23/2016,4:16 PM EST更改为2016/11/23,4:16 PM CST。你的例子也改变了日期。 – user3334226
始终使用UTC时间在数据库中保存日期,并且您可以在需要时获取任何时区日期。 –