我正面临Java的一个奇怪问题(版本6,7,8)。在这段代码中,我试图计算两个日期之间的日期差异,这段代码给出了我在03/12/2018和01/04/2018之间的日期差异,为66.958天,而不是67天,这有点令人惊讶。我从未见过这种行为。
为了证明这一理论,你可以尝试在03/11/2018之前的任何日期,这是一个简单的数学。请告知你们的想法。我已经尝试了与Java捆绑在一起的ChronoUnit类,它正确地计算了天数,但只是想知道这里发生了什么以及你是否有任何意见。
static void dateLogic1() throws ParseException{
String matYear1 = "03/11/2018";
String matYear2 = "03/12/2018";
String stlDate = "01/04/2018";
java.util.Date mtYear1 = new SimpleDateFormat("MM/dd/yyyy").parse(matYear1);
java.util.Date mtYear2 = new SimpleDateFormat("MM/dd/yyyy").parse(matYear2);
java.util.Date stYear = new SimpleDateFormat("MM/dd/yyyy").parse(stlDate);
long time1 = mtYear1.getTime();
long time2 = mtYear2.getTime();
long time4 = stYear.getTime();
double diff1 = (double) (mtYear1.getTime()-stYear.getTime()) /( 24 * 60 * 60 * 1000);
double diff2 = (double) (mtYear2.getTime()-stYear.getTime()) /( 24 * 60 * 60 * 1000);
System.out.println("Date Diff between "+ mtYear1 +" & "+ stYear +" is " + diff1 );
System.out.println("Date Diff between "+ mtYear2 +" & "+ stYear +" is " + diff2 );
}
答案 0 :(得分:8)
这与夏令时有关。 2018年3月11日凌晨2点,很多地方都损失了一个小时。如果您将该小时转换为一天的一小部分(1/24),结果是67和66.958之间的差异。
编辑: Date.getTime()返回自Date对象表示的1970年1月1日00:00:00 GMT以来的毫秒数。因为你失去了一个小时的千分之一,这就是分数小时丢失的原因。
答案 1 :(得分:3)
Duration.between( ZonedDateTime , ZonedDateTime )
Sam M的回答和scottb的评论都是正确的。
你正在使用现在遗留下来的麻烦的旧日期时间类,取而代之的是java.time类。
LocalDate start = LocalDate.of( 2018 , Month.JANUARY , 4 ) ;
LocalDate stop = LocalDate.of( 2018 , Month.MARCH , 12 ) ;
long days = ChronoUnit.DAYS.between( start , stop ) ;
如果您想要时刻而不是日期,则必须指定时区。对于任何特定时刻,日期在全球范围内因地区而异。
ZoneId z = ZoneId.of( "Pacific/Auckland" ) ;
让java.time确定一天的第一时刻,因为它并不总是在00:00。
我们添加一天来计算最后一天的整个长度。
ZonedDateTime zdtStart = start.atZone( z ) ;
ZonedDateTime zdtStop = stop.plusDays( 1 ).atZone( z ) ;
使用Duration
对象计算经过纳秒级分辨率的时间。
Duration d = Duration.between( zdtStart , zdtStop ) ;
将标准ISO 8601格式的字符串表示为字符串。
String output = d.toString() ; // Generate string in standard ISO 8601 format.
经验教训:
java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.Date
,Calendar
和& SimpleDateFormat
现在位于Joda-Time的maintenance mode项目建议迁移到java.time类。
要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310。
从哪里获取java.time类?
ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如Interval
,YearWeek
,YearQuarter
和more。