gpt4 book ai didi

java - 使用小时调整而不是语言环境来打印DateTime的最简单方法是什么?

转载 作者:行者123 更新时间:2023-12-01 09:47:23 27 4
gpt4 key购买 nike

我正在使用一个系统,每个用户都可以在几小时内从UTC指定其调整设置。

因此,当从该用户输入日期/时间时,该值将通过其设置进行调整并保存为UTC。同样,在出门时,将从数据库中检索日期/时间,并根据其设置进行调整并显示。

我可能考虑得太多了,但这是否意味着要为每个人显示正确的日期/时间,我必须有效地调整小时数,并告诉我的SimpleDateFormat实例这是“ UTC”吗?现在,我在英国,当前时区为UTC + 1,如果我未指定使用UTC进行打印,那么时间将减少一小时!

DateTime dateWithOffset = statusDate.plusMinutes(currentTimezoneOffsetInMinutes);

SimpleDateFormat sdf = new SimpleDateFormat("dd MMM yyyy HH:mm");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
return sdf.format(dateTime.toDate());


我在想这个吗?或者,如果我只想从UTC调整小时数,是否有一种更简单的方法以某种格式打印日期?

最佳答案

你太辛苦了切勿手动调整偏移量和时区,也不要为此目的在日期时间值上增加或减去分钟。让一个不错的日期时间库来完成这项工作。

java.time

Joda-Time团队建议我们迁移到Java 8及更高版本中内置的java.time框架。

ZoneOffset类表示offset-from-UTC。请记住,在某些地区,偏移量可能不仅涉及数小时,而且可能涉及数分钟甚至数秒钟。

OffsetDateTime类表示时间轴中具有指定偏移量的时刻。

int hours = 3;  // input by user

ZoneOffset offset = ZoneOffset.ofHours( hours );
OffsetDateTime odt = OffsetDateTime.now( offset );


java.time中的toString方法使用标准的ISO 8601格式。

String output = odt.toString();


通常,最佳实践是在UTC中进行业务逻辑和数据存储。与偏移量或区域值之间的相互转换仅用于与用户进行交互。

在java.time中, UTC中时间轴上的时刻由 Instant类表示。您可以从 Instant中提取 OffsetDateTime对象。

Instant instant = odt.toString();


Instant和此 OffsetDateTime都表示时间轴上的同一时刻。它们表示不同的 wall-clock times

跳过使用 OffsetDateTime.now便捷方法并从 Instant开始可能更清楚。

Instant instant = Instant.now();  // Always in UTC, by definition.
ZoneOffset offset = ZoneOffset.ofHours( hours );
OffsetDateTime odt = OffsetDateTime.ofInstant( instant , offset ); // Same moment but presenting alternate wall-clock time.


处理输入

如果用户以字符串形式输入日期时间值,则需要进行解析。在java.time中,这意味着 DateTimeFormatter类。格式代码与过时的 java.text.SimpleDateFormat类似,但不完全相同,因此请务必研究文档。

DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "dd MMM uuuu HH:mm";


由于自UTC的偏移量是单独给出的,因此我们将此输入字符串解析为缺少时区信息的 LocalDateTime

LocalDateTime ldt = LocalDateTime.parse( inputString , formatter );


要查看,请通过调用 ldt.toString()创建以ISO 8601格式设置格式的String对象。


2016-01-02T12:34:45


应用预定的 ZoneOffset对象以产生 OffsetDateTime对象。

OffsetDateTime odt = ldt.atOffset( offset );



2016-01-12T12:34:45 + 03:00


在UTC中思考

处理日期时间值令人头疼。 UTC是您的阿司匹林。

程序员到达办公室时,应脱下“英国公民/伦敦居民”帽子,并戴上“ UTC”帽子。忘记所有关于您自己的本地时区的信息。学会思考UTC(和24小时制)。在您的办公桌或计算机上添加另一个时钟,设置为UTC(或 Reykjavík Iceland),或至少将诸如 time.is/UTC之类的页面添加为书签。在UTC中进行所有日志记录,业务逻辑,数据序列化,数据交换和调试。

Instant设为您的初学者和入门课程。根据定义,它的值始终以UTC表示。

Instant instant = Instant.now();


查看从上面看到的 Instant值提取的 OffsetDateTime,其String表示形式为 2016-01-12T12:34:45+03:00。使用UTC表示上午9点而不是中午,这是同一时刻,但挂钟时间相差三个小时。 ZZulu的缩写,表示UTC。

String output = odt.toInstant().toString();



2016-01-12T09:34:45Z


用户或数据接收器期望时,仅根据需要调整到偏移量或时区。仅供参考,时区是从UTC偏移的时间,再加上一组用于处理异常的规则,例如夏令时(DST)。尽可能使用时区优先于仅偏移。

Europe/London时区在夏季与UTC相同,但是在冬季使用“夏令时”废话,并且比UTC早一小时。因此,使用与上方相同的 Instant,伦敦的挂钟时间为10 AM,而不是UTC的9 AM,并且与我们看到的中午时间不同,偏移量为 +03:00

ZoneId zoneId = ZoneId.of( "Europe/London" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );



2016-01-12T10:34:45 + 01:00 [欧洲/伦敦]


始终指定所需/所需的偏移量或时区;永远不要通过忽略此可选参数来依赖隐式当前默认值。 (顺便说一下, Locale的Ditto。)请注意,此代码在所有代码中如何回答您的 JVM具有当前默认时区( ZoneId.systemDefault)为 Europe/London以及我的JVM具有一个 America/Los_Angeles的当前默认时区完全不相关。无论您使用什么机器来开发,测试和部署,代码都可以运行相同,获得相同的结果。

语言环境

在生成涉及月或日,逗号或句点等名称的日期时间值的文本表示时,请指定 Locale对象。 Locale确定(a)翻译此类名称时要使用的人类语言,以及(b)确定标点符号等问题时应遵循的文化规范。

Locale与时区和UTC偏移无关。例如,如果您在印度有 Locale.CANADA_FRENCH用户,则可以将 Asia/Kolkata与日期时间设置为 Québécois

关于java - 使用小时调整而不是语言环境来打印DateTime的最简单方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37880030/

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