gpt4 book ai didi

java - Joda:将系统日期和时间转换为另一个区域中的日期/时间

转载 作者:行者123 更新时间:2023-11-30 06:32:29 25 4
gpt4 key购买 nike

我在SO上阅读了许多帖子,并测试了其中的大多数内容。他们都没有为我工作。这是我的代码:

DateTimeZone fromTimeZone = DateTimeZone.forID("America/New_York");
DateTimeZone toTimeZone = DateTimeZone.forID("US/Central");
Date now = new Date();
DateTime dateTime = new DateTime(now, fromTimeZone);
DateTime newDateTime = dateTime.withZone(toTimeZone);
System.out.println(dateTime.toDate() + "--" + newDateTime.toDate());


这是我的印刷品:


  美国东部时间2017年8月22日星期二13:08:13-美国东部时间2017年8月22日星期二13:08:13


我希望在第二时区显示 "Tue Aug 22 12:08:13 CDT 2017"

最佳答案

java.util.Date doesn't have timezone information。乔达(Joda)的DateTime具有,但已包装到translate this instant to "human readable" date/time fieldsChronology中。

但是最后,两个对象都只是represent points (instants) in the time-line

只需检查dateTime.getMillis()newDateTime.getMillis()dateTime.toDate().getTime()newDateTime.toDate().getTime()的值。它们将完全相同,并且该值表示自历元(1970-01-01T00:00Z)以来的毫秒数。

传递给DateTime对象的时区仅会影响toString()的输出(当将此毫秒值“转换”为本地日期和时间时),但不会更改毫秒值本身。因此,如果您这样做:

DateTime dateTime = new DateTime(now, fromTimeZone);
System.out.println(dateTime);


它将打印与毫秒值等效的日期和时间,但转换为 fromTimeZone(America / New_York):


  2017-08-22T13:33:08.345-04:00


withZone方法只是设置为其他时区,但 keeps the same milliseconds value

DateTime newDateTime = dateTime.withZone(toTimeZone);
System.out.println(newDateTime);


上面的代码保留瞬时值(毫秒值),但在 toTimeZone(美国/中央)中打印等效的日期和时间:


  2017-08-22T12:33:08.345-05:00


.toDate()方法返回一个 java.util.Date,它仅包含相同的毫秒值,并且没有时区信息。然后, System.out.println隐式调用 Date::toString() method和该 converts the milliseconds value to the JVM's default timezone。在这种情况下,两个都将是:


  美国东部时间2017年8月22日13:33:08


因为两个日期都代表相同的时刻(自纪元以来相同的毫秒数)。



如果要获取包含特定格式日期的 String,则可以使用 org.joda.time.format.DateTimeFormatter

DateTimeFormatter fmt = DateTimeFormat.forPattern("EEE MMM dd HH:mm:ss z yyyy").withLocale(Locale.ENGLISH);
System.out.println(fmt.print(new DateTime(DateTimeZone.forID("US/Central"))));


不需要转换date对象,因为实际上没有真正发生转换:上面的所有方法都不会更改毫秒值。

另请注意,我使用 java.util.Locale来确保星期几和星期几为英文。如果您未指定语言环境,则将使用JVM默认值,并且不能保证始终将其设置为英语(并且即使在运行时也可以更改它,因此最好始终指定它)。

然后,我得到了当前日期,并设置了打印时要使用的时区。请注意,您可以直接获取 DateTime,而无需创建 java.util.Date

输出将是:


  CDT 2017年8月22日星期二12:33:08


要获得所需的完全相同的输出(包括两个日期),可以执行以下操作:

DateTimeFormatter fmt = DateTimeFormat.forPattern("EEE MMM dd HH:mm:ss z yyyy").withLocale(Locale.ENGLISH);
DateTime nowNy = new DateTime(DateTimeZone.forID("America/New_York"));
DateTime nowCentral = nowNy.withZone(DateTimeZone.forID("US/Central"));
System.out.println(fmt.print(nowNy) + "--" + fmt.print(nowCentral));


输出将是:


  美国东部时间2017年8月22日星期二13:33:08-CDT 2017年8月22日星期二12:33:08




Java新的日期/时间API

Joda-Time处于维护模式,并已被新的API取代,因此,我不建议使用它来启动新项目。即使在 joda's website中,它也说:“请注意,Joda-Time被认为是一个很大程度上“完成”的项目。没有计划进行重大增强。如果使用Java SE 8,请迁移到java.time(JSR-310)。” (如果您不想或不能从Joda迁移到另一个API,则可以考虑此部分)。

如果您使用的是Java 8,请考虑使用 new java.time APIless bugged and less error-prone than the old APIs更容易。

如果您使用的是Java <= 7,则可以使用 ThreeTen Backport,这是Java 8的新日期/时间类的很好的反向端口。对于Android,还有 ThreeTenABP(有关如何使用 here的更多信息)。

下面的代码对两者都适用。
唯一的区别是包名称(在Java 8中为 java.time,在ThreeTen Backport(或Android的ThreeTenABP)中为 org.threeten.bp),但是类和方法的名称相同。

相关类为 DateTimeFormatter(将日期以特定格式格式化为 String), ZonedDateTime(代表特定时区的日期和时间)和 ZoneId(代表时区):

// formatter - use English locale for month and day of week
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss z yyyy", Locale.ENGLISH);

// current date/time in New York timezone
ZonedDateTime nowNy = ZonedDateTime.now(ZoneId.of("America/New_York"));
// convert to another timezone (US/Central)
ZonedDateTime nowCentral = nowNy.withZoneSameInstant(ZoneId.of("US/Central"));

// format dates
System.out.println(fmt.format(nowNy) + "--" + fmt.format(nowCentral));


输出与上面相同。

关于java - Joda:将系统日期和时间转换为另一个区域中的日期/时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45823501/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com