当前位置: 首页 > 知识库问答 >
问题:

在Java中计算两小时之间的持续时间

邵阳德
2023-03-14

我想计算Java中两小时(HH:mm:ss)之间的时间差(持续时间)。在这里,我读了几个关于这个主题的主题,但我的问题有点不同。

我也不能使用乔达时间

示例:

input values:    12:03:00 
                 00:00:00

expected output: 11:57:00

ode:

public static void main(String[] args) throws ParseException {

    Scanner sc = new Scanner(System.in);
    String startTime = sc.next();
    String endTime = sc.next();

    SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
    Date d1 = sdf.parse(startTime);
    Date d2 = sdf.parse(endTime);
    long elapsed = d2.getTime() - d1.getTime();

    String hms = String.format("%02d:%02d:%02d",
        TimeUnit.MILLISECONDS.toHours(elapsed),
        TimeUnit.MILLISECONDS.toMinutes(elapsed) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(elapsed)),
        TimeUnit.MILLISECONDS.toSeconds(elapsed) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(elapsed)));

    if (elapsed > 0) {
        System.out.println(hms);
    } else {

        elapsed = elapsed * (-1); //otherwise, print hours with '-'

        String hms1 = String.format("%02d:%02d:%02d",
            TimeUnit.MILLISECONDS.toHours(elapsed),
            TimeUnit.MILLISECONDS.toMinutes(elapsed) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(elapsed)),
            TimeUnit.MILLISECONDS.toSeconds(elapsed) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(elapsed)));

        System.out.println(hms1);
    }
}

结果:

expected output: 11:57:00

actual output:   12:03:00 //that's the problem

共有3个答案

方飞翼
2023-03-14

这是你想做的:

import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;

public class HourTest {
    public static void main(String[] args) throws Exception {
        LocalDateTime ldt1 = LocalDateTime.parse("2015-05-04T12:07:00");
        LocalDateTime ldt2 = LocalDateTime.parse("2015-05-04T00:00:00");

        long seconds = Math.abs(ChronoUnit.SECONDS.between(ldt1, ldt2));

        String hms = String.format("%02d:%02d:%02d", seconds / 3600, (seconds / 60) % 60, seconds % 60);

        // Prints 12:07:00. I tried it.
        System.out.println(hms);
    }
}
寿元白
2023-03-14

这里的基本缺陷是,您想要两个时间之间的最近距离。当你构造你的日期对象时,即使你只格式化为小时:分钟:秒,它仍然存储日/月/年等等...对于日期12:03:00和00:00:00,它默认为同一天,所以从(午夜到中午)的差异是您第二天没有得到的(中午到午夜)。您的解决方案是检查时间是否小于12点(军事时间),如果是,则在一天中加1。

以下是您的操作方式:

    String t1 = "12:03:00";
    String t2 = "00:00:00";
    SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");

    Date d1 = sdf.parse(t1);
    Date d2 = sdf.parse(t2);
    Calendar c1 = Calendar.getInstance();
    Calendar c2 = Calendar.getInstance();
    c1.setTime(d1);
    c2.setTime(d2);

    if(c2.get(Calendar.HOUR_OF_DAY) < 12) {
        c2.set(Calendar.DAY_OF_YEAR, c2.get(Calendar.DAY_OF_YEAR) + 1);
    }
    long elapsed = c2.getTimeInMillis() - c1.getTimeInMillis();
谷梁建中
2023-03-14
Duration.between( 
    LocalTime.parse( "12:03:00" ) , 
    LocalTime.parse( "23:59:59.999999999" ) 
).plusNanos( 1 ).withNanos( 0 ) 

PT11H57M

现代方法使用 java.time 类。

问题是,仅对于一天中的时间,没有午夜。因此,您显然打算在一天结束时的00:00实际上被解释为一天的开始。

一天结束前只有最后一纳秒。LocalTime为最后一纳秒定义了一个常量LocalTime.MAX=23:59:59.999999999

因为你只关心整秒,所以我们可以利用这一秒。如果您的结束时间恰好是< code>00:00:00,请替换为< code>LocalTime。最大。然后计算一个< code>Duration对象。您可以添加一个纳秒,然后通过将小数秒(纳秒)设置为零来截断得到的小数秒。

对于<code>00:00:00</code>以外的结束时间,数学仍然有效。添加纳秒会让您…。00000000 1秒的分数,以及持续时间::WithNano,将截断不需要的分数。

// This code assumes the inputs are *always* in whole seconds, without any fraction-of-second.

LocalTime start = LocalTime.parse( "12:03:00" );
LocalTime stop = LocalTime.parse( "00:00:00" );

if( stop.equals( LocalTime.MIN ) ) {
    stop = LocalTime.MAX ; // `23:59:59.999999999`
}

Duration d = Duration.between( start , stop );
d = d.plusNanos( 1 ).withNanos( 0 ) ;

System.out.println( "start/stop: " + start + "/" + stop );
System.out.println( "d: " + d );

查看此代码在IdeOne.com.运行

PT11H57M

< code>toString的输出是标准的ISO 8601格式。< code>Duration类可以解析并生成这样的字符串。

我强烈建议不要用时间样式HH:MM:SS来表示一段时间。这是不明确的,当被人类阅读时经常会产生混淆。

但是如果您坚持这种格式,您必须自己构建字符串。Duration类缺少在其他java.time类中看到的格式方法。奇怪的是,这个类最初缺乏提取部分的方法,天数、小时数、分钟数、秒数和小数秒。有关讨论,请参阅此问题。Java9将名为的此类方法带到... Part

使用Java8时,我建议对ISO 8601格式的输出进行字符串操作。将PT替换为空字符串。如果有M,将H替换为冒号。如果有S,将M替换为冒号,并将S替换为空字符串。如果没有S,将M替换为空字符串。我相信您可以在Stack Overflow上找到此代码。

 类似资料:
  • 问题内容: 我需要计算两个日期之间经过的时间。 这里要注意的是,我需要像YouTube一样用视频评论时间戳来显示它。也就是说,仅以最大的方式显示它。 例如, 如果时间是50秒前,应该说是50秒前。 如果时间超过一分钟,则应说一分钟前/十分钟前,等等。 如果时差是1小时30分钟,则应显示:一个小时前。 如果时间是一个半星期而不是一个星期前应该说的话。 如果时间超过一个月,则应说一个月前/两个月前,等

  • 问题内容: 我有一个熊猫数据框如下 上面的数据帧有83000行。我想获取两个连续行之间的时间差,并将其保存在单独的列中。理想的结果是 我已经尝试过但出现错误,如下所示 如何解决这个问题 问题答案: 问题是功能需要s或s ,因此首先要转换为,然后得到并除以: 如果需要或每分钟:

  • 我有DateTime字符串2020-04-03 01:29:27和2020-04-03 01:29:37我想得到持续时间在小时。我已经尝试了很多东西,但这却找不到任何帮助

  • 问题内容: 我有一个带有StartDate列的表,我想计算两个连续记录之间的时间差。 谢谢。 @ Mark Byers和@ Yahia,我将请求表作为requestId,startdate 我想知道requestid 1和2、2和3、3和4等之间的时差是多少。我知道我需要在表上进行自我连接,但是我在子句上没有得到正确的支持。 问题答案: 要实现您的要求,请尝试以下操作(从OP编辑后进行更新): 如

  • 问题内容: 我在一个MySQL数据库表上工作,该表的列包含我对其他主机执行ping操作时的时间戳记(例如2014-09-16 09:08:05)。我的问题是如何在几分钟内计算出针对特定主机的第一次ping和最后一次ping之间的差异?另外,如何为上述差异的开始和结束指定不同的时间戳(而不是第一次和最后一次ping)。这是表格的示例: 我希望我已经对自己的解释足够清楚。 问题答案: 您可以使用本机的

  • 问题内容: 我有一个表,其中有两列开始时间和结束时间。我能够计算每一行的持续时间,但我也想获得总持续时间。这该怎么做。 谢谢 问题答案: 您的列的数据类型为TIMESTAMP,如下所示: 从一个时间戳减去另一个时间戳会导致一个INTERVAL数据类型: 并且不能对INTERVAL数据类型求和。这是一个令人讨厌的限制: 为了规避此限制,您可以使用秒数进行转换和计算,如下所示: 然后它们是可以累加的普