我怎样才能得到一个时期的开始和结束时间?
How can I get the start and end time of a period?
我有一个枚举 TimeFrame
,其值如下:Yesterday
、LastWeek
、NextMonth
等
我正在尝试编写一个接受 TimeFrame
和 return 那个时间段的开始和结束日期的方法。
我查看了新的 Java 8 Period
class ,它可能需要开始时间和结束时间,但之后似乎没有任何干净的方法来检索这些值.
如何在不使用 List
(似乎是错误的数据结构)或一些丑陋的日期时间算法的情况下,立即 return 干净地return 开始和结束日期?
不,Period
不记录 start/end - 它只是代表它们之间的时间量,在日历意义上(而不是 "precise amount of time" 代表Duration
).
听起来基本上您应该创建自己的 class,它具有开始日期和结束日期。您仍然可以使用 Period
来实现它,但是您需要 getStartDate()
和 getEndDate()
返回 LocalDate
值。您不需要自己做任何繁重的 date/time 运算 - 只需算出开始日期并添加适当的时间段,或结束日期并减去适当的时间段,具体取决于时间范围。
时光荏苒
传递“昨天”、“明天”等枚举值时要小心。这就提出了几个问题,时区和午夜。
日期和星期几仅在时区上下文中有意义。对于任何给定时刻,日期在全球范围内各不相同。例如,巴黎的午夜过后几分钟在蒙特利尔仍然是“昨天”。因此,当您打算使用“昨天”之类的内容时,请始终指定 desired/expected 时区。
每个非atomic命令和代码行都与前一个分开执行。每次执行都需要一点时间,无论多么短暂。在任何这些时刻,指定时区的午夜都可能会转入新的一天。在午夜的那一刻,你的相对时间标志,比如“昨天”,突然有了一个全新的含义。鉴于该代码开始时条件(日期)不同,该含义可能与早期代码的意图不同。
所以我觉得传递 Instant
objects, or perhaps OffsetDateTime
or ZonedDateTime
对象更有意义。这些日期时间值被冻结,代表时间轴上的特定时刻。您之前的原始代码可以验证该值的含义,检查日期是否确实是 Friday
或类似的日期。经过这样的验证后,该值可以传递给其他代码。现在您不必担心半夜偶尔会出现奇怪的错误。
java.time
你真的不需要构建一个 class 或枚举来表达你的相对时间的意图,比如“昨天”。 java.time classes 内置于 Java 8 及更高版本中,具有用于添加和减去天、周、月的简单阅读方法。这些基本上是一行,所以直接调用这些 plus…
和 minus…
方法即可。
ZonedDateTime now = ZonedDateTime.now();
ZonedDateTime yesterday = now.minusDays( 1 );
ZonedDateTime weekLater = now.plusWeeks( 1 );
该代码隐式应用了 JVM 当前的默认时区。最好指定。
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime now = ZonedDateTime.now( zoneId );
您可能需要没有时间和时区的仅日期。使用 LocalDate
.
LocalDate weekPrior = now.toLocalDate().minusWeeks( 1 );
您可能想获得当天的第一时间。不总是 00:00:00.0
.
的时间
ZonedDateTime yesterdayStart = now.minusDays( 1 ).toLocalDate().atStartOfDay( zoneId );
如果要表示由一对日期时间值定义的时间跨度,请查看 Interval
class found in the ThreeTen-Extra project that extends the java.time framework. This class tracks a pair of Instant
objects which are moments on the timeline in UTC. You can extract an Instant
from your ZonedDateTime
by calling toInstant
。
Interval intervalYesterday = Interval.of( yesterdayStart.toInstant() , yesterdayStart.plusDays( 1 ).toInstant() );
要从 Instant
返回分区日期时间,请应用 ZoneId
。
ZonedDateTime zdt = ZonedDateTime( instant , zoneId );
对于仅限日期的间隔,您需要构建自己的 class 来存储一对 LocalDate
对象。我会称之为 DateRange
.
提示:搜索 "Half-Open" 了解跟踪时间跨度的做法,其中开始于 包含 而结束为 包含 [=66] =].
我有一个枚举 TimeFrame
,其值如下:Yesterday
、LastWeek
、NextMonth
等
我正在尝试编写一个接受 TimeFrame
和 return 那个时间段的开始和结束日期的方法。
我查看了新的 Java 8 Period
class ,它可能需要开始时间和结束时间,但之后似乎没有任何干净的方法来检索这些值.
如何在不使用 List
(似乎是错误的数据结构)或一些丑陋的日期时间算法的情况下,立即 return 干净地return 开始和结束日期?
不,Period
不记录 start/end - 它只是代表它们之间的时间量,在日历意义上(而不是 "precise amount of time" 代表Duration
).
听起来基本上您应该创建自己的 class,它具有开始日期和结束日期。您仍然可以使用 Period
来实现它,但是您需要 getStartDate()
和 getEndDate()
返回 LocalDate
值。您不需要自己做任何繁重的 date/time 运算 - 只需算出开始日期并添加适当的时间段,或结束日期并减去适当的时间段,具体取决于时间范围。
时光荏苒
传递“昨天”、“明天”等枚举值时要小心。这就提出了几个问题,时区和午夜。
日期和星期几仅在时区上下文中有意义。对于任何给定时刻,日期在全球范围内各不相同。例如,巴黎的午夜过后几分钟在蒙特利尔仍然是“昨天”。因此,当您打算使用“昨天”之类的内容时,请始终指定 desired/expected 时区。
每个非atomic命令和代码行都与前一个分开执行。每次执行都需要一点时间,无论多么短暂。在任何这些时刻,指定时区的午夜都可能会转入新的一天。在午夜的那一刻,你的相对时间标志,比如“昨天”,突然有了一个全新的含义。鉴于该代码开始时条件(日期)不同,该含义可能与早期代码的意图不同。
所以我觉得传递 Instant
objects, or perhaps OffsetDateTime
or ZonedDateTime
对象更有意义。这些日期时间值被冻结,代表时间轴上的特定时刻。您之前的原始代码可以验证该值的含义,检查日期是否确实是 Friday
或类似的日期。经过这样的验证后,该值可以传递给其他代码。现在您不必担心半夜偶尔会出现奇怪的错误。
java.time
你真的不需要构建一个 class 或枚举来表达你的相对时间的意图,比如“昨天”。 java.time classes 内置于 Java 8 及更高版本中,具有用于添加和减去天、周、月的简单阅读方法。这些基本上是一行,所以直接调用这些 plus…
和 minus…
方法即可。
ZonedDateTime now = ZonedDateTime.now();
ZonedDateTime yesterday = now.minusDays( 1 );
ZonedDateTime weekLater = now.plusWeeks( 1 );
该代码隐式应用了 JVM 当前的默认时区。最好指定。
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime now = ZonedDateTime.now( zoneId );
您可能需要没有时间和时区的仅日期。使用 LocalDate
.
LocalDate weekPrior = now.toLocalDate().minusWeeks( 1 );
您可能想获得当天的第一时间。不总是 00:00:00.0
.
ZonedDateTime yesterdayStart = now.minusDays( 1 ).toLocalDate().atStartOfDay( zoneId );
如果要表示由一对日期时间值定义的时间跨度,请查看 Interval
class found in the ThreeTen-Extra project that extends the java.time framework. This class tracks a pair of Instant
objects which are moments on the timeline in UTC. You can extract an Instant
from your ZonedDateTime
by calling toInstant
。
Interval intervalYesterday = Interval.of( yesterdayStart.toInstant() , yesterdayStart.plusDays( 1 ).toInstant() );
要从 Instant
返回分区日期时间,请应用 ZoneId
。
ZonedDateTime zdt = ZonedDateTime( instant , zoneId );
对于仅限日期的间隔,您需要构建自己的 class 来存储一对 LocalDate
对象。我会称之为 DateRange
.
提示:搜索 "Half-Open" 了解跟踪时间跨度的做法,其中开始于 包含 而结束为 包含 [=66] =].