更改Date对象的时区而不更改日期 [英] Change timezone of Date object without changing date

查看:414
本文介绍了更改Date对象的时区而不更改日期的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我可以在不更改日期的情况下更改java代码中Date对象的时区吗?
当我写
日期日期=新日期(longValue);
我在当地时区得到这个日期。我希望得到这个日期,但我的时区应该是我的用户ID(例如美国/芝加哥)的DB(非本地)中的一个。



提前感谢为了你的帮助。

解决方案

tl; dr



  ZonedDateTime zdtMontreal = 
ZonedDateTime.now(ZoneId.of(America / Montreal));

ZonedDateTime zdtAuckland =
zdtMontreal.withZoneSameLocal(ZoneId.of(Pacific / Auckland));

不是同一时刻。 zdtAuckland 几小时前发生的时刻



确定这是你真正的意图。我有一种沉闷的感觉,你做错了事,对日期时间处理的工作方式感到困惑。日期时间工作 令人困惑。一定要搜索和研究Stack Overflow。



java.time





当前时刻



获取当前时刻,请致电 Instant.now Instant class代表 UTC 中时间轴上的一个时刻,分辨率为纳秒(小数部分最多九(9)位)。

 即时实例= 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(太平洋/奥克兰)); 

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



要保持相同的时刻,而是调用 ZonedDateTime :: withZoneSameInstant



数据库



通常最好将日期时间值存储在 UTC 。已经在Stack Overflow上进行了广泛讨论。搜索更多信息。






关于java.time



构建了 java.time 框架进入Java 8及更高版本。这些类取代了麻烦的旧遗留日期时间类,例如 java.util.Date 日历 ,& SimpleDateFormat



Joda-时间项目现在处于维护模式,建议迁移到java.time。



要了解更多信息,请参阅 Oracle教程。并搜索Stack Overflow以获取许多示例和解释。规范是 JSR 310



从哪里获取java.time类?





ThreeTen-Extra 项目使用其他类扩展了java.time。该项目是未来可能添加到java.time的试验场。您可以在这里找到一些有用的课程,例如 间隔 YearWeek YearQuarter 更多


Can I change the timezone of Date object in my java code without changing the date? When I write Date date = new Date(longValue); I get this date in my local timezone. I want to get this date but my timezone should be one present in DB (not local) for my userID (for eg "America/Chicago").

Thanks in advance for your help.

解决方案

tl;dr

ZonedDateTime zdtMontreal = 
    ZonedDateTime.now( ZoneId.of( "America/Montreal" ) );

ZonedDateTime zdtAuckland = 
    zdtMontreal.withZoneSameLocal( ZoneId.of( "Pacific/Auckland" ) );  

Not the same moment. The zdtAuckland moment occurred several hours earlier.

Be certain that is truly your intention. I have a sinking feeling you are doing the wrong thing, confused about how date-time handling works. Date-time work is confusing. Be sure to search and study Stack Overflow.

java.time

The Joda-Time project, now in maintenance mode, advises migration to java.time.

The Local… classes purposely have no time zone or offset-from-UTC information.

LocalDate ld = LocalDate.of( 2016 , Month.January , 23 ); // 2016-01-23
LocalTime lt = LocalTime.of( 12 , 34 , 56 );  // 12:34:56

These values do not yet represent a point on the timeline. Would that be the noon hour of Auckland NZ, Paris FR, or Montréal CA? We must apply a time zone to determine an actual moment. We apply a ZoneId to get a ZonedDateTime.

Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as EST or IST or CST as they are not true time zones, not standardized, and not even unique(!).

ZoneId zMontreal = ZoneId.of( "America/Montreal" );
ZonedDateTime zdtMontreal = ZonedDateTime.of( ld , lt , zMontreal );

To see a string representing this value in the standard ISO 8601 format, call toString. Actually, the ZonedDateTime class extends the standard format by wisely appending the name of the time zone in square brackets.

String outputMontreal = zdtMontreal.toString();

2016-01-23T12:34:56-05:00[America/Montreal]

To get the same date and same time-of-day in another time zone, repeat the process.

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 );

But know that you are getting a different moment in time. Noon in Auckland happens several hours before noon in Paris, and noon in Montréal is even later, for three different points in time that happen to share coincidentally the same wall-clock time.

2016-01-23T12:34:56-05:00[America/Montreal]

2016-01-23T12:34:56+01:00[Europe/Paris]

2016-01-23T12:34:56+13:00[Pacific/Auckland]

Current moment

To get the current moment, call Instant.now. The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction).

Instant instance = Instance.now();

Apply a ZoneId to adjust into a time zone.

ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instance.atZone( z );

Repeat the process for other desired time zones, similar to what we did further above.

As a shortcut, you can get a ZonedDateTime directly.

ZonedDateTime zdtMontreal = ZonedDateTime.now( ZoneId.of( "America/Montreal" ) );

And as another shortcut, you can apply a different time zone while retaining the same date and same time-of-day (the same wall-clock time). Call ZonedDateTime::withZoneSameLocal.

ZonedDateTime zdtAuckland = zdtMontreal.withZoneSameLocal( ZoneId.of( "Pacific/Auckland" ) );

I repeat: This results is different points on the time line. The zdtAuckland is happening several hours before zdtMontreal occurs.

To keep the same moment, instead call ZonedDateTime::withZoneSameInstant.

Database

Usually best to store your date-time values in a database in UTC. Already discussed extensively on Stack Overflow. Search for more info.


About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

The Joda-Time project, now in maintenance mode, advises migration to java.time.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

Where to obtain the java.time classes?

  • Java SE 8 and SE 9 and later
    • Built-in.
    • Part of the standard Java API with a bundled implementation.
    • Java 9 adds some minor features and fixes.
  • Java SE 6 and SE 7
    • Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
  • Android

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

这篇关于更改Date对象的时区而不更改日期的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆