使用ZoneDateTime与Calendar相比,在转换和增加值时有哪些影响?

huangapple go评论70阅读模式
英文:

What are the implications of using ZoneDateTime versus Calendar, when converting and augmenting values?

问题

我不确定在使用 Calendar 对象与使用 ZonedDateTime 对象时,会发生什么不可预见的影响,特别是无效化方面。

我想知道为什么必须使用一个框架而不是另一个来进行值的转换或解析,是否可以提供洞察力。

我已经查阅了关于 "旧日期时间代码"Java 教程,但我无法找到无效化可能发生的地方。

换句话说,教程提到了以下内容。

> "Calendar 类不是类型安全的".

我不关心类型安全,解析只是几个步骤而已。

> "因为这些类是可变的,所以不能在多线程应用程序中使用它们".

可变状态不是一个问题。

> "由于月份的不寻常编号和缺乏类型安全性,应用程序代码中的错误很常见"

我不关心索引与枚举的比较。

这些观点都不反对抽象的反面。

作为演示,我将同时使用这两个类来讨论它们的逻辑。

我可以使用 SimpleDateFormatCalendar 解析格式化的 String 值。

String string = "MMMM dd, yyyy ' @ ' h:mm:ss a z";
SimpleDateFormat format = new SimpleDateFormat(string);
String value = "May 28, 2023 @ 6:50:01 pm EDT";
Calendar calendar = Calendar.getInstance();
calendar.setTime(format.parse(value));

如果我打印来自 calendar 的数据,我会得到有效的结果。

System.out.println(calendar.getTimeInMillis());
System.out.printf("%tc", calendar.getTimeInMillis());
1685314201000
Sun May 28 18:50:01 EDT 2023

此外,我可以使用 DateTimeFormatterZonedDateTime 解析相同格式的 String 值。尽管需要将 value 中的 "PM" 大写,但这并不会有任何问题。DateTimeParseException 甚至指定了字符索引。

DateTimeFormatter format = DateTimeFormatter.ofPattern(string);
ZonedDateTime zonedDateTime = ZonedDateTime.parse(value, format);

同样地,如果我打印来自 zonedDateTime 的数据,我会得到有效的结果。

System.out.println(zonedDateTime.toInstant().toEpochMilli());
System.out.printf("%tc%n", zonedDateTime.toInstant().toEpochMilli());
System.out.println(zonedDateTime);
1685314201000
Sun May 28 18:50:01 EDT 2023
2023-05-28T18:50:01-04:00[America/New_York]

如果你比较这两组数据,你会发现它们是等价的,因此两者都是有效的。

如果我想要增加值,比如添加 4 小时,因为 EDT 是 UTC-4,我可以使用这两个类都可以做到。

对于 Calendar 类,我可以使用 add 方法。该方法在 Calendar 类内部具有可扩展的 规范

calendar.add(Calendar.HOUR_OF_DAY, 4);
1685328601000
Sun May 28 22:50:01 EDT 2023

同样地,对于 zonedDateTime,我可以使用 plusHours 方法。

zonedDateTime = zonedDateTime.plusHours(4);
1685328601000
Sun May 28 22:50:01 EDT 2023
2023-05-28T22:50:01-04:00[America/New_York]

再次说明,在解析和增强方面,无论是 Calendar 还是 ZonedDateTime,我都得到了相等的值。

如果我从 1,685,314,201,000 中减去 1,685,328,601,000,我得到了 14,400,00014,400,000 相当于 4 小时 乘以 (60 分钟 乘以 (60 秒 乘以 1000 毫秒))。

这就带我得出了结论,关于在基本解析和增强方面使用一个类而不是另一个类所带来的不可预见的错误是什么?

例如,一个类是否在年份测量方面更准确,比如 365.25 天,而不是 365.2425

除了Java所述的设计影响之外,从哪个类更符合惯用法的角度来看,哪个类被视为更符合惯例——考虑到两者都会生成等价的值。

我指的是从哲学的角度来看的 "符合惯用法",而不是从范式、意识形态、抗议的方式来看的 "符合惯用法"。

无需应用经验性证据。

英文:

I am unsure of what unforeseeable implications, specifically invalidation, will occur when utilizing a Calendar object, versus using a ZonedDateTime object.

I am wondering if insight can be provided to why the conversion, or parsing, of a value must be done using one framework versus the other.

I've reviewed the Java Tutorials, in reference to "legacy date-time code", and I am unable to procure where an invalidation may happen.

To paraphrase, the tutorial mentions the following.

> "The Calendar class was not type safe".

I am not concerned with type safety, parsing is only a few steps.

> "Because the classes were mutable, they could not be used in multithreaded applications".

Mutable state is not a topic.

> "Bugs in application code were common due to the unusual numbering of months and the lack of type safety".

I'm not concerned with an index versus an enumeration.

None of these points defy an antithesis for abstraction.

As a demonstration, I'll utilize both classes collectively, in an attempt to discuss their logic.

I can parse a formatted String value using SimpleDateFormat, and Calendar.

String string = "MMMM dd, yyyy '@' h:mm:ss a z";
SimpleDateFormat format = new SimpleDateFormat(string);
String value = "May 28, 2023 @ 6:50:01 pm EDT";
Calendar calendar = Calendar.getInstance();
calendar.setTime(format.parse(value));

If I print the data from calendar I receive a valid result.

System.out.println(calendar.getTimeInMillis());
System.out.printf("%tc", calendar.getTimeInMillis());
1685314201000
Sun May 28 18:50:01 EDT 2023

And, I could parse the same formatted String value using DateTimeFormatter, and ZonedDateTime.
Granted, I have to uppercase the "PM" within value—this is not a set-back.
The DateTimeParseException had even specified a character index.

DateTimeFormatter format = DateTimeFormatter.ofPattern(string);
ZonedDateTime zonedDateTime = ZonedDateTime.parse(value, format);

Similarly, if I print the data from zonedDateTime, I get a valid result.

System.out.println(zonedDateTime.toInstant().toEpochMilli());
System.out.printf("%tc%n", zonedDateTime.toInstant().toEpochMilli());
System.out.println(zonedDateTime);
1685314201000
Sun May 28 18:50:01 EDT 2023
2023-05-28T18:50:01-04:00[America/New_York]

If you review the data side-by-side, you'll find they are equivalent, thus both are valid.

If I wanted to augment the values, let's say, by adding 4 hours, since EDT is UTC-4, to derive a UTC value; I can achieve this with both classes.

For the Calendar class I can use the add method.
Which, has an extensible specification from within the Calendar class.

calendar.add(Calendar.HOUR_OF_DAY, 4);
1685328601000
Sun May 28 22:50:01 EDT 2023

Equivalently, for zonedDateTime, I can use the plusHours method.

zonedDateTime = zonedDateTime.plusHours(4);
1685328601000
Sun May 28 22:50:01 EDT 2023
2023-05-28T22:50:01-04:00[America/New_York]

Again, I'm arriving at equal values, in terms of Calendar versus ZonedDateTime.

If I subtract 1,685,314,201,000 from 1,685,328,601,000, I get 14,400,000.
14,400,000 is equivalent to, 4 hours × (60 minutes × (60 seconds × 1000 milliseconds)).

This brings me to my conclusion, on the adverse effects of using one class over another, in terms of basic parsing, and augmentation.

What is the unforeseen error that will be calculated when using one class versus the other?

For example, is one class using a more accurate year measurement, such as 365.25 days, over 365.2425?

Aside from the design implications stated by Java, where does one class prove as idiomatic over another—considering both will generate equivalent values.

I mean idiomatic from the philosophical stand-point, and not idiomatic in the paradigmatic, ideological, protestant way.

Empirical evidence need not apply.

答案1

得分: 1

不,他们没有使用“更准确的年份测量”。在日历方面没有任何不正确或会导致完全错误的值。

日历已经过时,因为它难以正确使用,例如将月份从0到11编号,而不是从1到12。它还混淆了物理时间和文明时间,重要的是要区分开来。

使用java.util.Calendar可以编写100%正确的代码。不过,大多数人不会这样做。

英文:

No, they are not using a "more accurate year measurement." There is no aspect in which Calendar is incorrect or will result in values that are simply wrong.

Calendar is obsolete because it is difficult to use correctly, e.g. numbering months from 0 to 11 instead of 1 to 12.
It also conflates physical and civil times, which it's important to draw a distinction between.

It's possible to write 100% correct code with java.util.Calendar. Most people won't, though.

huangapple
  • 本文由 发表于 2023年5月29日 08:53:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/76354129.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定