添加时间并没有加起来

Adding time doesn't add up

抱歉,我是带着一个本该已经得到解答的问题来找你的。唉,我的google-foo很弱,虚心来求教

为什么会出现额外的 59 分钟?

好的,所以我得到了一个“打卡”的东西,当出门的人分钟数与分钟数相同时,我的计算出错了。我记得以前听说过这个问题,但没有解决方案。只是一个“好吧,就是这样。祝你好运,伙计。”我试过在计算过程中增加和减少分钟数,但这只会将问题推到 +/- 时间 added/subtracted。我也试过计算到秒(下面未显示),但这也没有帮助。

必填,这是我的代码:

//calculateTotalHours() 
public static String calculateTotalHours(Cell inTime, Cell outTime, Cell breakStart, Cell breakEnd)
{
    System.out.println(LOG + "calculateTotalHours");
    SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm");
    Date in, out, start, end;       
    
    if(null != inTime && null != outTime && null != breakStart && null != breakEnd)
    {   
        try
        {
            in = timeFormat.parse(inTime.getStringCellValue());
            out = timeFormat.parse(outTime.getStringCellValue());
            start = timeFormat.parse(breakStart.getStringCellValue());
            end = timeFormat.parse(breakEnd.getStringCellValue());

            long lunchTotal = end.getTime() - start.getTime();
            long totalWork = out.getTime() - in.getTime();
            long totalTime = totalWork - lunchTotal;            
            long diffHours = totalTime/HOURS % 24;
            totalTime -= diffHours;
            long diffMinutes = totalTime/MINUTES % 60;
            totalTime -= diffMinutes;       
            
            return String.format("%02d:%02d", diffHours, diffMinutes);
        } 
        catch (ParseException e) {e.printStackTrace();}
    }
    else
    {
        try
        {
            if(null == breakStart || null == breakEnd)              {
                in = timeFormat.parse(inTime.getStringCellValue());
                out = timeFormat.parse(outTime.getStringCellValue());           
                
                long totalTime = out.getTime() - in.getTime();              
                long diffHours = totalTime/HOURS % 24;
                totalTime -= diffHours;
                long diffMinutes = totalTime/MINUTES % 60;
                totalTime -= diffMinutes;
                
                return String.format("%02d:%02d", diffHours, diffMinutes);
            }
            else if(null == inTime.getStringCellValue())
            {
                System.out.println(LOG + "inTime is blank");
                return "-1";
            }
        } 
        catch (ParseException e) {e.printStackTrace();}
    }
    return "-1";
}   

对于我调用代码的混乱,我深表歉意。让我知道按秒或毫秒计算是否可行。那样做时我可能忽略了一些东西。

2020 年更新:

我想更新我的代码以及我应该做的事情。首先,我应该将单元格、字符串和时间分开。其次,为了清楚起见,我应该将其分解为更多方法。

我只显示 getTotalHours(startTimeString, endTimeString):

    DateTimeFormatter format = DateTimeFormatter.ofPattern("HH:mm");
    LocalTime end = LocalTime.parse(endTimeString.trim(), format);
    LocalTime start = LocalTime.parse(startTimeString.trim(), format);
    
    return   Duration.between(start, end).toHoursPart()%24 
           + ":"
           + Duration.between(start, end).toMinutes()%60;

你的数学完全错误,无法处理 getTime() 返回的时间值以毫秒为单位的事实。

我猜(因为上面没有显示)HOURSMINUTES 分别是一小时和一分钟的毫秒数常数?如果是这样,你只是部分地处理了单位是毫秒的事实,因为当你这样做时:

totalTime -= diffHours;

...你只会从你的总时间中减去几毫秒,而不是实现我认为你认为你正在完成的事情,即删除所有时间,以便剩下的时间是几分钟。

此代码还有其他问题,但这是最明显的问题。

private static final String defaultHours = "-1";

public static String calculateTotalHours(Cell inTime, Cell outTime, Cell breakStart, Cell breakEnd)
{
    try {
        LocalTime inLocalTime = LocalTime.parse(inTime.getStringCellValue());
        LocalTime outLocalTime = LocalTime.parse(outTime.getStringCellValue());
        LocalTime breakStartTime = LocalTime.parse(breakStart.getStringCellValue());
        LocalTime breakEndTime = LocalTime.parse(breakEnd.getStringCellValue());

        Duration lunch = Duration.between(breakStartTime, breakEndTime);
        Duration present = Duration.between(inLocalTime, outLocalTime);
        Duration worked = present.minus(lunch);

        return String.format("%02d:%02d", worked.toHours(), worked.toMinutesPart());

    } catch (DateTimeParseException dtpe) {
        System.out.println(dtpe);
        return defaultHours;
    }
}

以上代码使用了Duration中引入的toMinutesPart方法Java 9.假设您使用的是ThreeTenABP(详情见下文)或更早的Java版本,它是:

        long hours = worked.toHours();
        long minutes = worked.minusHours(hours).toMinutes();
        return String.format("%02d:%02d", hours, minutes);

为清楚起见,我省略了空值检查,我相信您可以处理这些。

如评论中所述,将时间数学留给经过良好测试的库方法。它不仅不容易出错,而且还提供了更清晰的代码。我正在使用 java.time,现代 Java 日期和时间 API。它还使我们免于指定显式格式化程序,因为 LocalTime.parse()HH:mm 的格式解析为默认格式(它是 ISO 8601 格式)。

你的代码出了什么问题?

作为 中的 kshetline,我相信 totalTime 以毫秒为单位,而 diffHours 以小时为单位。所以当你做 totalTime -= diffHours; 时,你从毫秒中减去小时,你一定会得到不正确的结果(顺便说一句,与 totalTime -= diffMinutes; 相同,但你没有使用后一个减法的结果,所以这个错误没有显示)。

问题:我可以在 Android 上使用 java.time 吗?

是的,java.time 在新旧 Android 设备上都能很好地工作。它只需要至少 Java 6.

  • 在 Java 8 和更高版本以及较新的 Android 设备上(据我所知,来自 API 级别 26)现代 API 是内置的。
  • 在 Java 6 和 7 中获取 ThreeTen Backport,新 类 的 backport(ThreeTen 用于 JSR 310;请参阅底部的链接)。
  • 在(较旧的)Android 使用 ThreeTen Backport 的 Android 版本。它叫做 ThreeTenABP。并确保使用子包从 org.threeten.bp 导入日期和时间 类。

链接