Java 考虑日期时的小时数差异

Java 考虑日期时的小时数差异,java,datetime,date-difference,date,Java,Datetime,Date Difference,Date,我需要从数据库中提取日期字段并将其存储在VO中。如何比较两个日期的小时数差异 对于ex: 比如说date1=01-SEP-17 10:00:00和date2=05-SEP-17 12:00:00。我需要比较这两个日期并执行以下操作: if(hours>10){ //do something } if(hours<10){ //do something else } if(小时数>10){ //做点什么 } 如果(hours使用Java 8中添加的新Java Time API很容

我需要从数据库中提取日期字段并将其存储在VO中。如何比较两个日期的小时数差异

对于ex:
比如说
date1=01-SEP-17 10:00:00
date2=05-SEP-17 12:00:00
。我需要比较这两个日期并执行以下操作:

if(hours>10){
//do something
}
if(hours<10){
//do something else
}  
if(小时数>10){
//做点什么
}

如果(hours使用Java 8中添加的新Java Time API很容易做到:

DateTimeFormatter fmt = new DateTimeFormatterBuilder()
                        .parseCaseInsensitive()
                        .appendPattern("dd-MMM-yy HH:mm:ss")
                        .toFormatter(Locale.US);
LocalDateTime date1 = LocalDateTime.parse("01-SEP-17 10:00:00", fmt);
LocalDateTime date2 = LocalDateTime.parse("05-SEP-17 12:00:00", fmt);
long hours = ChronoUnit.HOURS.between(date1, date2);
System.out.println(hours);
输出

98

您基本上已经获得了毫秒数的时间。您可以直接比较毫秒数

long tenHoursInMillis = 36000000;
long dateVOMillis = someVO.getDate().getTime();
long dateSysMillis = System.currentTimeMillis();
if(dateSysMillis - dateAMillis > tenHoursInMillis) {
    // do something
}
else if(dateSysMillis - dateAMillis < tenHoursInMillis) {
    // do something else
}
// do something when they're equal
long tenHoursInMillis=36000000;
long-dateVOMillis=someVO.getDate().getTime();
long-dateSysMillis=System.currentTimeMillis();
如果(dateSysMillis-dateAMillis>十小时百万){
//做点什么
}
else if(dateSysMillis-dateAMillis<十小时新密){
//做点别的
}
//当他们平等的时候做点什么

首先,您需要更改
SimpleDataFormat
中使用的模式,并使用
java.util.Locale
指定月份名称为英语(否则它使用系统默认的区域设置,并且不能保证总是英语)

然后,使用
java.util.concurrent.TimeUnit获得每个
日期的对应毫秒值,计算它们之间的差值,并将其转换为小时:

SimpleDateFormat df = new SimpleDateFormat("dd-MMM-yy HH:mm:ss", Locale.ENGLISH);
Date date1 = df.parse("01-SEP-17 10:00:00");
Date date2 = df.parse("05-SEP-17 12:00:00");

// get the difference in hours
long dateDiff = TimeUnit.MILLISECONDS.toHours(date2.getTime() - date1.getTime());
dateDiff
将是
98

如果要与当前日期进行比较,只需使用
newdate()


夏令时问题 这种方法有一个问题。虽然它在一年中的大部分时间里都不会产生影响,但由于变化,可能会产生影响

默认情况下,
SimpleDataFormat
使用JVM默认时区。如果在这两个日期之间有夏时制转换(或只是偏移量更改),结果可能会不同

例如:在2017年9月3日凌晨2点,时钟向前移动了1小时,从凌晨2点到凌晨3点(偏移量从
+01:00
更改为
+02:00
)。这意味着,在这一天,凌晨2点到凌晨2:59之间的所有本地时间在此时区中都不存在(就像他们“跳过”了这一小时)

因此,如果JVM默认时区是
非洲/温得和克
,那么使用上述代码的时间差将是97小时(而不是98小时)

即使您的JVM默认时区不是
非洲/温得和克
,这仍然可能发生,具体取决于时区和所涉及的日期。 不仅如此,还有默认时区。最好指定您使用的时区,而不是仅仅依赖默认时区

您无法避免DST效应(除非使用UTC),但至少您可以选择要使用的时区,而不是依赖系统默认值(可以在不通知的情况下更改)

可以在格式化程序中设置时区,因此所有日期都将根据该时区进行解析。在下面的示例中,我使用的是
欧洲/伦敦
,但您当然可以更改为最适合您的情况:

// set Europe/London timezone in the SimpleDateFormat
df.setTimeZone(TimeZone.getTimeZone("Europe/London"));
现在,所有解析的日期都将被视为在伦敦时区(但请注意,DST效应仍将被考虑——优点是您知道您正在使用的时区,JVM默认值中的任何更改都不会使您的代码突然产生不同和意外的结果)

始终使用(始终采用
大陆/城市
格式,如
美国/圣保罗
欧洲/柏林
)。 避免使用三个字母的缩写(如
CST
PST
),因为它们是

您可以使用
TimeZone.getAvailableIDs()
获取所有时区的列表-然后您可以选择最适合您的情况的一个

如果您不想考虑DST效果,可以使用<代码> TimeZeal.GETTimeZONE(“UTC”)< /C> >因为.< /P>


Java新的日期/时间API 旧类(
Date
Calendar
SimpleDateFormat
)具有和,它们正在被新的API所取代

如果你使用<强> java 8 <强>,考虑使用它。它更容易,

如果您使用的是Java
// set Europe/London timezone in the SimpleDateFormat
df.setTimeZone(TimeZone.getTimeZone("Europe/London"));
DateTimeFormatter fmt = new DateTimeFormatterBuilder()
    // case insensitive for month name in all caps
    .parseCaseInsensitive()
    // date/time pattern
    .appendPattern("dd-MMM-yy HH:mm:ss")
    // use English locale for month name
    .toFormatter(Locale.ENGLISH)
    // set a timezone
    .withZone(ZoneId.of("Europe/London"));
// parse the dates
ZonedDateTime z1 = ZonedDateTime.parse("01-SEP-17 10:00:00", fmt);
ZonedDateTime z2 = ZonedDateTime.parse("05-SEP-17 12:00:00", fmt);
// calculate the difference in hours
long diffHours = ChronoUnit.HOURS.between(z1, z2);
// use the same ZoneId used in the formatter if you want to consider DST effects
ZonedDateTime.now(ZoneId.of("Europe/London"));
Date date = // java.util.Date
// convert to zoneddatetime (java 8)
ZonedDateTime z = date.toInstant().atZone(ZoneId.of("Europe/London"));
// convert to zoneddatetime (java 7 ThreeTen Backport)
ZonedDateTime z = DateTimeUtils.toInstant(date).atZone(ZoneId.of("Europe/London"));
// convert to zoneddatetime (java 8)
Date date = Date.from(z.toInstant());
// convert to zoneddatetime (java 7 ThreeTen Backport)
Date date = DateTimeUtils.toDate(z.toInstant());