java Joda-Time:DateTime、DateMidnight 和 LocalDate 用法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2538448/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Joda-Time: DateTime, DateMidnight and LocalDate usage
提问by mickthompson
Joda-Timelibrary includes different datetime classes
DateTime- Immutable replacement for JDK Calendar
DateMidnight- Immutable class representing a date where the time is forced to midnight
LocalDateTime- Immutable class representing a local date and time (no time zone)
DateTime- JDK Calendar 的不可变替代品
DateMidnight- 表示时间强制为午夜的日期的不可变类
LocalDateTime- 表示本地日期和时间(无时区)的不可变类
I'm wondering how are you using these classes in your Layered Applications.
我想知道您如何在分层应用程序中使用这些类。
I see advantages in having almost all the Interfaces using LocalDateTime (at the Service Layer at least) so that my Application doesn't have to manage Timezones and can safely assume Times always in UTC. My app could then use DateTime to manage Timezones at the very beginning of the Execution's Flow.
我看到几乎所有接口都使用 LocalDateTime(至少在服务层)的优势,这样我的应用程序就不必管理时区并且可以安全地假设时间总是在 UTC 中。然后,我的应用程序可以在执行流程的最开始使用 DateTime 来管理时区。
I'm also wondering in which scenario can DateMidnight be useful.
我还想知道 DateMidnight 在哪种情况下有用。
回答by leonbloy
I see advantages in having almost all the Interfaces using LocalDateTime (at the Service Layer at least) so that my Application doesn't have to manage Timezones and can safely assume Times always in UTC.
我看到几乎所有接口都使用 LocalDateTime(至少在服务层)的优势,这样我的应用程序就不必管理时区并且可以安全地假设时间总是在 UTC 中。
I'm not sure I understand your line of thinking here. LocalDateTimeand DateTimerepresent two quite different concepts. It's not the case that a LocalDateTimehas some implicit UTC timezone: it actually has notimezone (internally it may be represented as a DateTimewith UTC timezone, but it's just a implementation detail, it does not matter to the programmer who uses it).
我不确定我是否理解你在这里的想法。LocalDateTime并DateTime代表两个完全不同的概念。并非 aLocalDateTime具有某些隐式 UTC 时区的情况:它实际上没有时区(在内部它可能表示为DateTime带有 UTC 时区的 a,但这只是一个实现细节,对于使用它的程序员来说无关紧要)。
You can see in the API docsthat, while a DateTimeis a "Instant" (a point in the world time line, a physical concept), a LocalDateTimeis NOT such a thing. The LocalDateTimeis actually a Partial, (a "civil" concept), in a different class hierarchy. The classes names might -unfortunately- make you think that LocalDateTimeis some specialization of DateTime: well, it isn't.
您可以在 API 文档中看到,虽然 aDateTime是“ Instant”(世界时间线中的一个点,一个物理概念),但 aLocalDateTime不是这样的。该LocalDateTime实际上是一个Partial,(一个“公民”的概念),在不同的类层次结构。类名称可能 - 不幸的是 - 让您认为这LocalDateTime是 的某种专业化DateTime:嗯,它不是。
A LocalDateTimeshould be regarded as a pair {Date(Y/M/D) ; Time(hh:mm:ss.msec)}, a bunch of numbers which corresponds to the "civil" standard representation of time-related data. If we are given a LocalDateTime, we cannot convert it directly to a DateTime, we need to specify a timezone; and that conversion takes we to another kind of entity. (An analogy: Strings and byte streams in Java: to convert between them you must specify a charset encoding, because they are conceptually different things)
ALocalDateTime应该被视为一对{ Date( Y/M/D); Time( hh:mm:ss.msec)},一组数字,对应于时间相关数据的“民用”标准表示。如果给定 a LocalDateTime,则不能直接将其转换为 a DateTime,需要指定时区;这种转换将我们带到另一种实体。(类比:Java 中的字符串和字节流:要在它们之间进行转换,您必须指定字符集编码,因为它们在概念上是不同的)
When to use one or the other in the application... it's sometimes arguable, but frequently is clear enough, once the Jodatime concepts are understood. And IMO is not much related to "layers", perhaps more to use cases or scenarios.
何时在应用程序中使用一个或另一个......有时有争议,但一旦理解了 Jodatime 概念,通常就足够清楚了。而且 IMO 与“层”的关系不大,可能更多地与用例或场景相关。
A non-trivial -borderline- example: You work at Google, programming the Calendar. You must let the user manage (add, see, modify) an event which includes a date-time (lets ignore recurrent events), say "I have an appointement with my doctor on 2019-July-3 at 10:00 am". What is the time-date entity to use in the software layer (for this usecase)? I'd say: a LocalDateTime. Because the user is not really dealing with a physical point in time, but with a civil time: the date and time that displays the clock in his wrist or in his home. He does not even think of timezones (lets ignore the special case of a user who is traveling around the world...) Then, in the bussiness and presentation layer, a LocalDateTimeseems the right entity.
一个重要的边界示例:您在 Google 工作,为日历编程。您必须让用户管理(添加、查看、修改)包含日期时间的事件(让我们忽略重复事件),例如“我在 2019 年 7 月 3 日上午 10:00 与我的医生有约会”。在软件层中使用的时间-日期实体是什么(对于这个用例)?我会说:一个LocalDateTime。因为用户并不是真正在处理物理时间点,而是处理民用时间:在他的手腕或家里显示时钟的日期和时间。他甚至没有想到时区(让我们忽略环游世界的用户的特殊情况......)然后,在业务和表示层,a LocalDateTime似乎是正确的实体。
But suppose that you must also code a different scenario: a reminder. When the Google internal scheduler detects that the event stored by the user is N minutes in the future from now, it must send him a reminder. Here, "N minutes from now" is a totally "physical" concept of time, so here the "business layer" would deal with a DateTime. There are several alternatives, for example: the event was stored in the DB as a LocalDateTime(ie. just time and date without timezone - one frequently uses a UTC timestamp to represent that, but this an implementation detail). In this scenario (only in this) we must load it as a DateTime, we convert it using a Timezone, probably from the user's profile.
但是假设您还必须编写一个不同的场景:提醒。当 Google 内部调度器检测到用户存储的事件是从现在开始的 N 分钟后,它必须向他发送提醒。在这里,“从现在开始的 N 分钟”是一个完全“物理”的时间概念,因此这里的“业务层”将处理一个DateTime. 有几种选择,例如:事件作为一个存储在数据库中LocalDateTime(即没有时区的只是时间和日期 - 人们经常使用 UTC 时间戳来表示,但这是一个实现细节)。在这种情况下(仅在这种情况下)我们必须DateTime将其加载为,我们使用时区转换它,可能来自用户的个人资料。
回答by Basil Bourque
The Answer by leonbloyis correct and vitally important. I am merely translating to the java.time classes that replace the Joda-Time project.
leonbloy的答案是正确且至关重要的。我只是翻译为取代 Joda-Time 项目的 java.time 类。
java.time
时间
Specific moment
特定时刻
For a specific moment on the timeline:
对于时间轴上的特定时刻:
- Always in UTC is represented by
Instant. - Assigned an offset-from-UTC is represented by
OffsetDateTime. - Assign a full time zone rather than mere offset is represented by
ZonedDateTime.
- 始终在 UTC 中由 表示
Instant。 - 分配的 UTC 偏移量由 表示
OffsetDateTime。 - 分配一个完整的时区而不仅仅是偏移量由 表示
ZonedDateTime。
These all replace the Instant& DateTimeclass in Joda-Time. These java.time classes all have a resolution of nanosecondsversus the milliseconds used by Joda-Time.
这些都取代了Joda-Time 中的Instant&DateTime类。这些 java.time 类都具有纳秒分辨率,而 Joda-Time 使用的毫秒分辨率。
Midnight versus Start-of-day
午夜与一天的开始
For midnight, the Joda-Time project concluded “midnight” is a vague and unproductive concept. The midnight-related classes and midnights were all deprecated in later versions of Joda-Time, replaced with the practical concept of “first moment of the day”.
对于午夜,Joda-Time 项目得出的结论是“午夜”是一个模糊且毫无成效的概念。与午夜相关的类和午夜在 Joda-Time 的后续版本中都被弃用,取而代之的是“一天中的第一刻”的实用概念。
The java.time classes took the same lesson, using a "first moment of the day" approach. Look for atStartOfDaymethods on java.time classes such as LocalDate.
java.time 类采用了相同的教训,使用“一天中的第一时刻”方法。atStartOfDay在 java.time 类上查找方法,例如LocalDate.
Never assume a day starts at 00:00. Anomalies such as Daylight Saving Time (DST) mean the day may start at other times such as 01:00.
永远不要假设一天从 00:00 开始。夏令时 (DST) 等异常意味着一天可能在其他时间开始,例如 01:00。
ZonedDateTime zdt =
LocalDate.of( 2017 , Month.MARCH , 12 ) // Instantiate a date-only value without time zone.
.atStartOfDay( ZoneId.of( "America/Havana" ) ) ; // Cuba jumps from 00:00 to 01:00 on Spring DST cut-over.
For example, see how Cuba starts the day at 1 AM on their Spring DST cut-over.
例如,看看古巴如何在春季 DST 切换时从凌晨 1 点开始新的一天。
zdt: 2017-03-12T01:00-04:00[America/Havana]
zdt: 2017-03-12T01:00-04:00[美国/哈瓦那]
Unzoned
未分区
For representing the vague idea of possible moments over a range of about 26-27 hours but not an actual moment on the timeline, use LocalDateTime. This class purposely lacks any offset-from-UTC or time zone.
要表示大约 26-27 小时范围内可能的时刻的模糊概念,但不是时间线上的实际时刻,请使用LocalDateTime. 此类故意缺少任何与 UTC 或时区的偏移量。
LocalDateTime ldt = LocalDateTime.of( 2017 , Month.JANUARY , 23 , 1 , 2 , 3 , 0 ) ;
If your business context implies a specific time zone, you can apply it to get a ZonedDateTime.
如果您的业务环境暗示了特定的时区,您可以应用它来获得ZonedDateTime.
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = ldt.atZone( z ) ; // Determine a specific point on timeline by providing the context of a time zone.
About java.time
关于 java.time
The java.timeframework is built into Java 8 and later. These classes supplant the troublesome old legacydate-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
该java.time框架是建立在Java 8和更高版本。这些类取代了麻烦的旧的遗留日期时间类,例如java.util.Date, Calendar, & SimpleDateFormat。
The Joda-Timeproject, now in maintenance mode, advises migration to the java.timeclasses.
现在处于维护模式的Joda-Time项目建议迁移到java.time类。
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
要了解更多信息,请参阅Oracle 教程。并在 Stack Overflow 上搜索许多示例和解释。规范是JSR 310。
Where to obtain the java.time classes?
从哪里获得 java.time 类?
- Java SE 8, Java 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 6and Java SE 7
- Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
- Android
- The ThreeTenABPproject adapts ThreeTen-Backport(mentioned above) for Android specifically.
- See How to use ThreeTenABP….
- Java SE 8、Java SE 9及更高版本
- 内置。
- 具有捆绑实现的标准 Java API 的一部分。
- Java 9 添加了一些小功能和修复。
- Java SE 6和Java SE 7
- 多的java.time功能后移植到Java 6和7在ThreeTen-反向移植。
- 安卓
- 所述ThreeTenABP项目适应ThreeTen-反向移植(上述)为Android特异性。
- 请参阅如何使用ThreeTenABP ...。
The ThreeTen-Extraproject 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.
该ThreeTen-额外项目与其他类扩展java.time。该项目是未来可能添加到 java.time 的试验场。你可能在这里找到一些有用的类,比如Interval,YearWeek,YearQuarter,和更多。

