java - 如何在不使用 Joda Time 的情况下计算特定工作时间的两个日期之间的小时数?

标签 java date

我有某种 Activity ,其特征是开始日期和 期间。

我需要确定当前时间的 Activity 是否已经完成,以及完成后还剩多少小时或已经过去了多少小时。

我有一个条件,只计算上午 10 点到下午 6 点之间的工作时间(int work_start = 10, int work_end = 18)。 如果现在是上午 9 点,则应仅将昨天的时间计算为最后工作时间,如果今天是下午 01 点,则应计算今天已经过去了 3 小时

我创建了两种方法,但计算时没有考虑工作时间。如何只计算工作时间?

使用 Joda Time 的条件是。可能吗?

我的两种方法是:

public String getProgramEndDate(Date dateStart, int totalDuration){
        long durationInMillis = totalDuration * 3600000;
        long end = dateStart.getTime() + durationInMillis;
        Date date=new Date(end);
        SimpleDateFormat df2 = new SimpleDateFormat("dd/MM/yyyy");
        String endD = df2.format(date);
        return endD;
    }

public StringBuilder getDaysEndOfTheProgram(Long howMuchTime) {
    SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy HH");
    long diffHours = howMuchTime / (60 * 60 * 1000) % 8;
    long diffDays = howMuchTime / (24 * 60 * 60 * 1000);
    StringBuilder sb = new StringBuilder();
    sb.append(diffDays + " days, ");
    sb.append(diffHours + " hours. ");
    return sb;

最佳答案

首先,您正在使用麻烦的旧日期类,这些类现在已成为遗留的,已被 java.time 类取代。

Date 等效的是Instant,它是UTC 时间轴上的一个时刻,但具有更精细的纳秒分辨率。传递此类的对象作为您的第一个参数。如果给定一个 Date,请使用添加到旧类中的新方法 Date::toInstant 进行转换。

Instant = myUtilDate.toInstant() ;

为您的持续时间使用一个类,而不仅仅是一个整数。这使您的代码更加自文档化并为您提供类型安全性。

Duration d = Duration.ofHours( … ) ;

由于您需要一天中的某些时间和当前日期,因此我们需要一个时区。我们必须将 UTC 值调整为该时区。

ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdtInitial = instant.atZone( z ) ;

你明白Date实际上是一个日期时间吗?如果您打算传递不含时间的仅日期值,请传递 LocalDate 对象。您的代码表明您确实意味着包含一天中的实际时间。

首先测试您的开始时间是否在工作时间内。

LocalTime ltStart = LocalTime.of( 10 , 0 ) ;
LocalTime ltStart = LocalTime.of( 18 , 0 ) ;

LocalTime ltInitial = zdtInitial.toLocalTime() ;
if( ( ! ltInitial.isBefore( ltStart ) ) && ltInitial.isBefore( ltStop ) ) { … }

接下来,测试您的开始时间是否尚未到来。

ZonedDateTime zdtNow = ZonedDateTime.now( z ) ;
if( zdtNow.isBefore( zdtInitial ) ) { … }

对于一天的工作时间问题没有神奇的答案。只需开始计数,逐渐减少持续时间

Duration dRemaining = d ; 

ZonedDateTime zdtInitialEndOfDay = ZonedDateTime.of( zdtInitial.toLocalDate() , ltStop ) ; 
Duration dBetween = Duration.between( zdt.Initial , zdtInitialEndOfDay ) ; 

测试之间的金额是否等于或超过剩余金额。

if( dBetween.compareTo( dRemaining ) >= 0 ) {
    // Add remaining duration to the zdt to get the ending moment. End looping. 
} else {  // between is less than remaining. So subtract, and move on to next day.
    dRemaining = dRemaining.minus( dBetween ); 
    // get `LocalDate as seen above, call `plusDays` and create another `ZonedDateTime` as seen above.
}

关于java - 如何在不使用 Joda Time 的情况下计算特定工作时间的两个日期之间的小时数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45084363/

相关文章:

java - 如何将 "9:00 PM EST"转换为 Date 对象

php - MySQL获取上述两个日期变量之间/之上的记录

java - 有没有一种方法可以编写 Mockito.when(...) 来覆盖方法的所有重载,即对于共享相同方法名称的任何调用返回相同的内容?

java - 异步调用集合中的每个项目

java - Spring MVC : wrong encoding of downloaded file

javascript - 打印给定位置的时间

java - 当 Java 类没有父类时,是否应该调用 super() ?

java - 如何在被杀死后立即在android中重新启动应用程序?

python - Pandas 从组中获取列的第一个和最后一个值

date - 使用 Mercurial 执行历史构建