java – 在JDK7中查找日期之间的真正区别
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了java – 在JDK7中查找日期之间的真正区别,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含4017字,纯文字阅读大概需要6分钟。
内容图文
![java – 在JDK7中查找日期之间的真正区别](/upload/InfoBanner/zyjiaocheng/757/7942bfdd1b8347b88ec5efac7a9a3d35.jpg)
如何在JDK7中找到两个日期之间的差异,以便可以添加差异以使两个日期相等?
我尝试使用similar StackOverflow question中的解决方案,从另一个中减去一个日期的毫秒数,但这可能导致日期之间的差异不正确.
在这个例子中,我尝试通过设置a =(b-a)a来使a等于b
private void makeTwoDatesEqual(GregorianCalendar a, GregorianCalendar b, DatatypeFactory datatypeFactory) {
long b_minus_a = b.getTimeInMillis() - a.getTimeInMillis();
Duration delta = datatypeFactory.newDuration(b_minus_a);
delta.addTo(a);
}
但结果出人意料:
之前
a = "2015-08-29T00:00:00.000Z"
b = "2040-01-01T00:00:00.000Z"
delta = "P24Y4M5DT0H0M0.000S" // 2 days longer than it should be.
后
a = "2040-01-03T00:00:00.000Z"
b = "2040-01-01T00:00:00.000Z"
delta = "P24Y4M5DT0H0M0.000S"
a.equals(b) = false
Joda-Time也有同样的问题:
private void makeTwoDatesEqual(GregorianCalendar a, GregorianCalendar b) {
DateTime date1 = new DateTime(a);
DateTime date2 = new DateTime(b);
Interval interval = new Interval(a.getTimeInMillis(), b.getTimeInMillis());
Period offsetPeriod = interval.toPeriod();
date1 = date1.plus(offsetPeriod);
date1.equals(date2); // false in my example
}
之前
date1 = "2015-08-29T00:00:00.000-05:00"
date2 = "2040-01-01T00:00:00.000-05:00"
offsetPeriod = "P24Y4M2DT23H"
date1.equals(date2) = false
后
date1 = "2039-12-31T23:00:00.000-05:00"
date2 = "2040-01-01T00:00:00.000-05:00"
offsetPeriod = "P24Y4M2DT23H"
date1.equals(date2) = false
在被问到之前,应该没有必要考虑夏令时或闰年,因为在每个例子中,我都在相应的时间段内添加时间间隔.
解决方法:
作为@Meno explained in the comments,日期算术很奇怪,因为月和年可以有不同的长度.在我们的ISO日历中,一个月可以有28天,29天,30天或31天,一年可以有365天或366天.
因此,像P24Y4M5D这样的时期(24年,4个月和5天)可以代表完全不同的天数,具体取决于您何时开始计算.
例如,如果我从2017-01-01T00:00Z开始.如果我添加24年,我得到2041-01-01,然后加上4个月,我得到2041-05-01,然后加上5天我得到2041-05-06.总差异相当于8891天.
但是,如果我从2016-01-01T00:00Z开始并添加相同的时间段(24年,4个月和5天):添加24年我得到2040-01-01,然后添加4个月我得到2040-05- 01,然后加5天我得到2040-05-06.但如果我加8891天,我会得到2040-05-05.
这是因为一个月和一年没有固定的长度,所以相应的总天数将始终取决于所涉及的日期(更不用说夏令时和闰秒效果,这也会改变小时,分钟,秒和毫秒).
要不依赖于此,您必须使用持续时间(以毫秒为单位)进行计算(而不是使用非固定长度变量,例如年和月).在Joda-Time中,您可以使用org.joda.time.Duration类:
public void makeTwoDatesEqual(GregorianCalendar a, GregorianCalendar b) {
DateTime date1 = new DateTime(a);
DateTime date2 = new DateTime(b);
System.out.println("date1=" + date1);
System.out.println("date2=" + date2);
Duration duration = new Duration(date1, date2);
DateTime date3 = date1.plus(duration);
System.out.println("date3=" + date3);
System.out.println(date3.equals(date2));
}
假设a等于2015-08-29T00:00:00Z且b为2040-01-01T00:00:00Z,则此代码将输出:
date1=2015-08-29T00:00:00.000Z
date2=2040-01-01T00:00:00.000Z
date3=2040-01-01T00:00:00.000Z
true
ThreeTen Backport
Joda-Time处于维护模式,正在被新的API取代,因此我不建议使用它来启动新项目.即使在joda’s website它也说:“请注意,Joda-Time被认为是一个很大程度上”完成“的项目.没有计划进行重大改进.如果使用Java SE 8,请迁移到java.time(JSR-310).”
如果您不能(或不想)从Joda-Time迁移到新API,则可以忽略此部分.
如果您使用的是Java 6或7,则可以使用ThreeTen Backport,这是Java 8新日期/时间类的优秀后端.而对于Android,你还需要ThreeTenABP(更多关于如何使用它here).
您可以使用org.threeten.bp.DateTimeUtils类将GregorianCalendar转换为org.threeten.bp.Instant,然后计算它们之间的差异,从而得到org.threeten.bp.Duration:
public void makeTwoDatesEqual(GregorianCalendar a, GregorianCalendar b) {
Instant instantA = DateTimeUtils.toInstant(a);
Instant instantB = DateTimeUtils.toInstant(b);
System.out.println(instantA);
System.out.println(instantB);
Duration duration = Duration.between(instantA, instantB);
Instant instantC = instantA.plus(duration);
System.out.println(instantC);
System.out.println(instantC.equals(instantB)); // true
}
假设a等于2015-08-29T00:00:00Z且b为2040-01-01T00:00:00Z,则此代码将输出:
2015-08-29T00:00:00Z
2040-01-01T00:00:00Z
2040-01-01T00:00:00Z
true
内容总结
以上是互联网集市为您收集整理的java – 在JDK7中查找日期之间的真正区别全部内容,希望文章能够帮你解决java – 在JDK7中查找日期之间的真正区别所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。