- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我不确定我是否理解了 Java Period
和 Duration
之间的微妙之处。
当我阅读 Oracle 的 explanation 时,它说我可以找出自生日以来的多少天(使用他们使用的示例日期):
LocalDate today = LocalDate.now();
LocalDate birthday = LocalDate.of(1960, Month.JANUARY, 1);
Period birthdayPeriod = Period.between(birthday, today);
int daysOld = birthdayPeriod.getDays();
但正如他们指出的那样,这并没有考虑您出生的时区和您现在所在的时区。但这是一台计算机,我们可以做到精确,对吧?那么我会使用 Duration
吗?
ZoneId bornIn = ZoneId.of("America/New_York");
ZonedDateTime born = ZonedDateTime.of(1960, Month.JANUARY.getValue(), 1, 2, 34, 56, 0, bornIn);
ZonedDateTime now = ZonedDateTime.now();
Duration duration = Duration.between(born, now);
long daysPassed = duration.toDays();
现在实际时间是准确的,但如果我理解正确,这些天数可能无法正确表示日历日,例如与 DST 等。
那么我该怎么做才能根据我的时区获得准确的答案?我唯一能想到的是回到使用 LocalDate
,但首先根据 ZonedDateTime
值规范化时区,然后使用 Duration
.
ZoneId bornIn = ZoneId.of("America/New_York");
ZonedDateTime born = ZonedDateTime.of(1960, Month.JANUARY.getValue(), 1, 2, 34, 56, 0, bornIn);
ZonedDateTime now = ZonedDateTime.now();
ZonedDateTime nowNormalized=now.withZoneSameInstant(born.getZone());
Period preciseBirthdayPeriod = Period.between(born.toLocalDate(), nowNormalized.toLocalDate());
int preciseDaysOld = preciseBirthdayPeriod.getDays();
但是要得到一个精确的答案似乎真的很复杂。
最佳答案
您对 Java-8 类 Period
和 Duration
的分析或多或少是正确的。
java.time.Period
类仅限于日历日期精度。java.time.Duration
类仅处理秒(和纳秒)精度,但始终将天视为等同于 24 小时 = 86400 秒。通常情况下,在计算一个人的年龄时忽略时钟精度或时区就足够了,因为护照等个人文件不会记录某人出生的确切时间。如果是这样,则 Period
类完成其工作(但请小心处理其方法,如 getDays()
- 见下文)。
但是您想要更高的精度并根据考虑时区的本地字段描述结果。嗯,第一部分(精度)由 Duration
支持,但是不是第二部分。
使用 Period
也无济于事,因为确切的时差(被 Period
忽略)会影响以天为单位的增量。此外(仅打印代码的输出):
Period preciseBirthdayPeriod =
Period.between(born.toLocalDate(), nowNormalized.toLocalDate());
int preciseDaysOld = preciseBirthdayPeriod.getDays();
System.out.println(preciseDaysOld); // 13
System.out.println(preciseBirthdayPeriod); // P56Y11M13D
如您所见,使用 preciseBirthdayPeriod.getDays()
方法来获取以天为单位的总增量是非常危险的。不,这只是总增量的一部分。还有 11 个月和 56 年。我认为不仅以天为单位打印增量是明智的,因为这样人们就可以更容易地想象增量有多大(请参阅打印持续时间的常见用例社交媒体,例如“3 年 2 个月零 4 天”)。
显然,您更需要一种方法来确定持续时间,包括日历单位以及特殊时区中的时钟单位(在您的示例中:某人出生的时区)。 Java-8-time-library 的缺点是:它不支持 Period
和 Duration
的任何组合。并且导入外部库 Threeten-Extra-class Interval
也无济于事,因为 long daysPassed = interval.toDuration().toDays();
仍然会忽略时区效应(1天 == 24 小时)并且也无法打印其他单位(如月份等)的增量。
总结:
您已经尝试了 Period
解决方案。 @swiedsw给出的答案尝试了基于Duration
的方案。这两种方法在精度方面都有缺点。您可以尝试将这两个类合并到一个实现 TemporalAmount
的新类中,并自己实现必要的时间算法(不是那么简单)。
旁注:
我自己已经在我的时间库中实现了Time4J你在寻找什么,所以它可能对你自己的实现有所启发。示例:
Timezone bornZone = Timezone.of(AMERICA.NEW_YORK);
Moment bornTime =
PlainTimestamp.of(1960, net.time4j.Month.JANUARY.getValue(), 1, 22, 34, 56).in(
bornZone
);
Moment currentTime = Moment.nowInSystemTime();
MomentInterval interval = MomentInterval.between(bornTime, currentTime);
MachineTime<TimeUnit> mt = interval.getSimpleDuration();
System.out.println(mt); // 1797324427.356000000s [POSIX]
net.time4j.Duration<?> duration =
interval.getNominalDuration(
bornZone, // relevant if the moments are crossing a DST-boundary
CalendarUnit.YEARS,
CalendarUnit.MONTHS,
CalendarUnit.DAYS,
ClockUnit.HOURS,
ClockUnit.MINUTES
);
// P56Y11M12DT12H52M (12 days if the birth-time-of-day is after current clock time)
// If only days were specified above then the output would be: P20801D
System.out.println(duration);
System.out.println(duration.getPartialAmount(CalendarUnit.DAYS)); // 12
这个例子也表明了我的一般态度,即使用月、日、小时等单位在严格意义上并不准确。唯一严格精确的方法(从科学的角度来看)是使用十进制秒的机器时间(最好是 SI 秒,也可能在 1972 年之后的 Time4J 中)。
关于java - Java Period 和 Duration 之间的微妙之处,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41123166/
我写了一个 mdx 脚本来显示 Internet Sales Amount 的周期增长,一切正常。我们正在使用一个界面,您可以在其中放置一个切片器,以便用户可以选择他感兴趣的 date.Calenda
我有一列数据,例如 '1971q1'、'1972q2' 等(年份后跟季度)当我这样做时: print(type(df.Quarterly)) 答案是系列 我需要的是将此列“转换”/转换为真正的 pd.
下面是我要处理的句子。它由前面以两个哈希值 (##2312435) 开头的 ID 以及其余文本组成。我需要一个正则表达式来查找其中包含单词 likely 的句子,并检索整个句子和 ID。 句子: ##
这两条线有什么区别? call apoc.periodic.iterate("MATCH (n:Nodes) return n", "DETACH DELETE n", {batchSize:1000
这个问题在这里已经有了答案: When does Thread.CurrentThread.Join() make sense? (6 个答案) 关闭 9 年前。 有人可以向我解释 Thread.S
我正在尝试用 java.time 替换 org.joda.time.Period。 我们在数据库中存储了以下值。 P1M, P1Y, P1D, PT1H, PT1M 只是解析这个值: Period m
我正在尝试解析 linux dig 的输出使用正则表达式在一次拍摄中执行多项操作。 假设我挖掘主机 mail.yahoo.com : /usr/bin/dig +nocomments +noquest
我正在尝试创建一个匹配以下内容的正则表达式: 一个或多个数字 允许在第一个数字后有 0 到 1 个句点 如果有句号 句点后需要 1 - 2 位数字 这是我目前使用的正则表达式,它并不适用于所有情况:
这是我的代码。我想绘制美国东部夏令时9:30-10点的最高点和最低点。我破解了这个代码,但我搞不清时间了。只有当我将其设置为0800-0900时才有效,这没有任何意义。如果我把它设置为0930-100
我正在制作一个仅用于学习目的的应用程序。我试图计算两个日期之间的差异 LocalDate today = LocalDate.now(); LocalDate localHoudbaarheid =
我正在使用 SEO 友好的 URL,我可以通过 ASP.NET 处理其中的大部分,通过将 aspnet_isapi.dll 映射到所有 URL。 (我在 IIS 中设置了一个处理程序映射,它对所有路径
我准备了以下数据 Timestamp Weighted Value SumVal Group 1 1600 800 1 2
为什么结果为periodBetween.Days和 substracted.Days不同的? 我可以看到一个 periodBetween.Months是 0 和 substracted.Months是
我有生日和第二个 LocalDate.now()我使用 Periof 打印这个 Period test = Period.between(dateofbirth,LocalDa
我使用 cocoa 在 Mac 上开发了一个应用程序。我需要将 cmd + period(.) 键盘事件作为我设计的命令来处理。但现在 cmd + period(.) 键盘事件没有像我预期的那样得到很
我有4000个观测值的数据,所以这是head(both): kön gdk age fbkurs pers stterm 1 man
我有一个包含特定类元素 vector 的类。主要思想是根据序列的一个周期(elems_)和周期数(nperiod_)生成元素的周期性序列,因此我不需要存储所有元素,而只需存储一个周期。 class P
我正在尝试添加句点“。”以及变量的后缀“-on”(下面第 4 行): function globalProducts(cat, self){ $("div.info").hide();
例如: requests.get() 是一个带有句点的函数。我如何制作自己的函数,例如: def foo(): return 'bar' 并像这样调用该函数: x.foo() 不是这样的: f
我尝试使用java.time.Period,结果与我手动计算的结果相差了三天。这里奇怪的是,当我将时间段分为两个时间段时,结果与我的手动计算相符。 第二种方法就像我手动计算周期一样。 我是不是漏掉了什
我是一名优秀的程序员,十分优秀!