在两个日期之间找到总共的小时数

50
我有两个日期对象,我需要获取时间差以确定它们之间的总工时,它们恰好来自同一天。我想要的结果将包含小时和分钟。 当我对我的日期对象使用.toString()时,我得到了这个:Fri Dec 18 08:08:10 CST 2009 我尝试过以下方法:
long diff = (this.endDate.getTime() - this.startDate.getTime()) / (60 * 60 * 1000);

但这只给了我小时,没有分钟。我知道这是一个简单的问题,但我现在想不出来。

编辑:对于那些感兴趣的人,以下是最终解决方案。感谢Michael Brewer-Davis

Period p = new Period(this.startDate, this.endDate);
long hours = p.getHours();
long minutes = p.getMinutes();
    
String format = String.format("%%0%dd", 2);
    
return Long.toString(hours) + ":" + String.format(format, minutes);
11个回答

81

这应该可以工作。

long secs = (this.endDate.getTime() - this.startDate.getTime()) / 1000;
int hours = secs / 3600;    
secs = secs % 3600;
int mins = secs / 60;
secs = secs % 60;

我们可以在小时和分钟之前添加类型转换,例如:int hours = int(secs / 3600); - xiaojueguan

66

这是使用Joda时间的方式:

DateTime startTime, endTime;
Period p = new Period(startTime, endTime);
int hours = p.getHours();
int minutes = p.getMinutes();
你可以使用Joda的格式化程序(例如PeriodFormat)进行格式化,但我建议使用Java的。详见此问题以了解更多详情。

编辑:使用此方法检查小时之间时要小心。该函数不尊重两个日期之间的天数。它只计算两个时间之间的小时数。2022-07-20 11.00和2022-07-21 12.00之间返回1小时,而不是25小时


1
这几乎完美。感谢Joda Time链接。但是如何将显示设置为“H:mm”,其中H表示小时,m表示分钟。例如“1:05”。目前它会显示“1:5”。 - clang1234
我的程序结果显示小时数为零... 请帮忙解决。 - Parijat Bose
14
奇怪的是,Period对我没有起作用。即使日期相隔数天,我所有小时数都只得到了0。相反,我使用了以下代码: Hours hours = Hours.hoursBetween(startTime, endTime);幸运的是,我只需要小时,所以这个方法对我有用。 - Somaiah Kumbera
8
这只在起始/结束日期是同一天的情况下才有效,正如原帖所示。评论者指出,当使用不同日期时,此方法会失效。Joda Period将时间段分为若干字段,并且getXXX方法仅返回特定字段的值(例如,对于持续2天、2小时、30分钟的时间段,getHours将返回2,而不是50(2*24+2))。使用Joda正确计算“两个日期之间的总小时数”的方法是根据Somaiah的评论。 - hendalst
如果我没记错的话,这不是总小时数,而是包含在内的小时数。 当我有Period = P-2W-5DT-8H-30M-11.844S,并要求p.getHours()时,它返回8,而不是2周,5天等的总小时数。 - radonthetyrant
使用这种方法是危险的!它不考虑日期之间的天数,只计算两个日期之间的小时数。例如,2022-07-20 11.00和2022-07-21 12.00之间的差值将返回1小时,而不是25小时。 - mtrakal

14

这里有一个简单的方法:

private static int hoursDifference(Date date1, Date date2) {

    final int MILLI_TO_HOUR = 1000 * 60 * 60;
    return (int) (date1.getTime() - date2.getTime()) / MILLI_TO_HOUR;
}

1
如果使用joda时间,请使用DateTimeConstants.MILLIS_PER_HOUR。 - Troveldom

12

java.time.Duration

我希望贡献一个现代(Java 8+)的答案。使用Joda-Time解决方案也是可以的,但是Joda-Time项目处于维护模式,所以我们不应该在新代码中使用它。我遵循Joda-Time项目的官方建议,使用java.time,这是现代的Java日期和时间API:

    Duration dur = Duration.between(startDate, endDate);
    String result = String.format("%d:%02d", dur.toHours(), dur.toMinutesPart());
    System.out.println(result);

如果 startDateendDate 都属于 InstantOffsetDateTimeZonedDateTimeLocalDateTimeLocalTime 类型,则此方法有效。所有这些类型都来自java.time包。如果从LocalDate开始,则调用任一一个atStartOfDay方法。

toMinutesPart 方法是在Java 9中引入的。 如果您使用Java 8(或ThreeTen Backport),请搜索“java格式持续时间”或类似内容,以了解如何将持续时间格式化为小时和分钟。

Joda-Time首页上的两个引用:

用户现在被要求迁移到java.time(JSR-310)。

请注意,Joda-Time被认为是一个已经基本完成的项目。没有计划进行重大增强。 如果使用Java SE 8,请迁移到 java.time(JSR-310)。

链接


4
请采用Somaiah在评论中提出的建议,使用Hours:

Hours hours = Hours.hoursBetween(startTime, endTime);

调用getHours()方法只返回时间差的小时部分,并忽略年份、月份之间的差异,因此在某些情况下不正确。

如果您使用Period.toStandardHours()将时间差转换为小时,则计算会抛出异常,如果两个日期之间的时间差包括年份或月份的差异,因为月份的长度是未知的。


0

对于 Kotlin,您可以使用以下函数并获取两个日期之间的小时数

private val dateFormat: String = "yyyy-MM-dd @ hh:mm a"
val startDate = SimpleDateFormat(dateFormat).parse("2018-10-01 @ 12:33 PM")
val endDate = SimpleDateFormat(dateFormat).parse("2018-10-01 @ 02:46 PM")

private fun hoursDifference(date1: Date, date2: Date): Int {
    val milliToHour : Long = 1000 * 60 * 60
    return ((date1.time - date2.time) / milliToHour).toInt()
}

println(hoursDifference(endDate,startDate).toString())

输出: 2


0

所以我猜测,getTime()方法返回一个整数。

在这种情况下,左括号的类型是int,对吗?

(60*60*1000)

也是一个整数。

这意味着您得到的长差异=((int)/(int)),因此在将东西转换为长整型之前进行整数除法。 因此,您会失去您的分钟。

尝试在除法之前对它们进行转换。


getTime() 方法返回的是 Long 类型而不是 int 类型。 - clang1234
啊...然后是罗布·范·达姆说的话,我想。还有格雷格斯说的话。 - Ritwik Bose

0
尽管已经有一个被接受的答案,但使用Joda time库对我来说起作用了。
/**
 *
 * @param date1
 * @param date2
 * @return hours between two dates rounded down
 */
public static int hoursBetween(DateTime date1, DateTime date2) {
    if(date1 == null || date2 == null) return NOT_FOUND;

    return Math.abs(Hours.hoursBetween(date1.toLocalDateTime(), date2.toLocalDateTime()).getHours());
}

0
这是一个纯Java 8+的解决方案,不涉及Joda或数学运算。
import java.time.*;
import java.time.temporal.*;

// given two java.util.Dates
Date startDate ...
Date endDate ...

// convert them to ZonedDateTime instances
ZonedDateTime start = ZonedDateTime.ofInstant(startDate.toInstant(), ZoneId.systemDefault());
ZonedDateTime end = ZonedDateTime.ofInstant(endDate.toInstant(), ZoneId.systemDefault());

// get the total duration of minutes between them
Duration total = Duration.ofMinutes(ChronoUnit.MINUTES.between(start, end));

// use the duration to determine the hours and minutes values
long hours = total.toHours();
long minutes = total.minusHours(hours).toMinutes();

0
private void getHours(Date d1, Date d2){
long diff = d2.getTime() - d1.getTime();

  long diffSeconds = diff / 1000 % 60;
        long diffMinutes = diff / (60 * 1000) % 60;
  long diffDays = diff / (24 * 60 * 60 * 1000);
        long diffHours = diff / (60 * 60 * 1000) % 24;

        System.out.print(diffDays + " days, ");
        System.out.print(diffHours + " hours, ");
        System.out.print(diffMinutes + " minutes, ");
        System.out.print(diffSeconds + " seconds.\n");

}`

//显示: /* 1天,1小时,1分钟,50秒。*/


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接