Java 8 更改日期对象的时区而不更改日期

Java 8 更改日期对象的时区而不更改日期,java-8,jodatime,Java 8,Jodatime,我可以在java代码中更改Date对象的时区而不更改日期吗? 当我写作时 Date-Date=新日期(longValue) 我在本地时区得到这个日期。我想得到这个日期,但我的时区应该是我的用户ID(例如“America/Chicago”)的DB(非本地)中的一个 提前感谢您的帮助。您可能会发现ZoneDateTime非常有用: 或者,您可以创建另一个Date对象,并手动对其应用一些偏移量。如何使用Java8ZonedDateTime类执行此操作的示例: Date date = new Date

我可以在java代码中更改Date对象的时区而不更改日期吗? 当我写作时
Date-Date=新日期(longValue)
我在本地时区得到这个日期。我想得到这个日期,但我的时区应该是我的用户ID(例如“America/Chicago”)的DB(非本地)中的一个


提前感谢您的帮助。

您可能会发现
ZoneDateTime
非常有用:


或者,您可以创建另一个
Date
对象,并手动对其应用一些偏移量。

如何使用Java8
ZonedDateTime
类执行此操作的示例:

Date date = new Date(longValue);
ZoneId = ZoneId.of("America/Chicago");
ZonedDateTime dt = ZonedDateTime.ofInstant(date.toInstant(), zoneId);
您已经用Joda标记了这个问题,但实际上用Java8您不再需要它了。

tl;博士 不是同一时刻。zdtAuckland
时刻发生在几个小时之前

确保这是你真正的意图。我有一种下沉的感觉,你在做错误的事情,对日期时间的处理方式感到困惑。日期时间工作令人困惑。确保搜索和研究堆栈溢出

java.time 该项目现已启动,建议迁移到java.time

Local…
类故意没有时区或信息

LocalDate ld = LocalDate.of( 2016 , Month.January , 23 ); // 2016-01-23
LocalTime lt = LocalTime.of( 12 , 34 , 56 );  // 12:34:56
这些值尚未表示时间线上的某个点。那是新西兰奥克兰、法国巴黎还是加利福尼亚州的中午时间?我们必须使用时区来确定实际时刻。我们应用
ZoneId
来获得
zoneDateTime

大陆/地区
的格式指定,例如,或
太平洋/奥克兰
。切勿使用3-4个字母的缩写,例如
EST
IST
CST
,因为它们不是真正的时区,不标准化,甚至不是唯一的(!)

要查看以标准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 );
但要知道,你正处在一个不同的时刻。奥克兰的中午比巴黎的中午早几个小时,蒙特勒尔的中午更晚,因为有三个不同的时间点恰好相同

2016-01-23T12:34:56-05:00[美国/蒙特利尔]

2016-01-23T12:34:56+01:00[欧洲/巴黎]

2016-01-23T12:34:56+13:00[太平洋/奥克兰]

当前时刻 要获取当前时刻,请调用
Instant.now
。该类表示时间线上的一个时刻,分辨率为(小数点的九(9)位)

应用
ZoneId
调整到时区

ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instance.atZone( z );
对其他所需时区重复此过程,类似于我们在上面所做的

作为快捷方式,您可以直接获取
ZoneDateTime

ZonedDateTime zdtMontreal = ZonedDateTime.now( ZoneId.of( "America/Montreal" ) );
作为另一个快捷方式,您可以应用不同的时区,同时保留相同的日期和时间(相同的墙上时钟时间)。打电话

我重复一遍:这个结果是时间线上的不同点。
zdtAuckland
发生在
zdtontrol
发生前几个小时

要保持不变,请打电话

数据库 通常最好将日期时间值存储在数据库中。已经对堆栈溢出进行了广泛讨论。搜索更多信息


关于java.time 该框架内置于Java8及更高版本中。这些类取代了麻烦的旧日期时间类,例如,&

该项目现已启动,建议迁移到java.time

要了解更多信息,请参阅。并搜索堆栈溢出以获得许多示例和解释。规格是

从哪里获得java.time类

  • 后来
    • 内置的
    • 标准JavaAPI的一部分,带有捆绑实现
    • Java9添加了一些次要功能和修复
    • 大部分java.time功能都在中向后移植到Java6和Java7
    • 该项目专门针对Android采用了Three Ten Backport(如上所述)

该项目使用其他类扩展了java.time。这个项目是java.time将来可能添加的一个试验场。您可以在这里找到一些有用的类,例如、、和。

始终使用UTC时间将日期保存在DB中,并且您可以在需要时获取任何时区日期。我已经尝试过了,但它没有解决我的问题。我只想更改时区,不想更改日期。例如,我希望将2016年11月23日美国东部时间下午4:16改为2016年11月23日美国中部时间下午4:16。这可能吗?我已经试过了,但没有解决我的问题。我只想更改时区,不想更改日期。例如,我希望将2016年11月23日美国东部时间下午4:16改为2016年11月23日美国中部时间下午4:16。您的示例也会更改日期。
Instant instance = Instance.now();
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instance.atZone( z );
ZonedDateTime zdtMontreal = ZonedDateTime.now( ZoneId.of( "America/Montreal" ) );
ZonedDateTime zdtAuckland = zdtMontreal.withZoneSameLocal( ZoneId.of( "Pacific/Auckland" ) );