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

在Java中计算两小时之间的持续时间,java,date,duration,Java,Date,Duration,我想计算Java中两个小时(HH:mm:ss)之间的时差(持续时间)。在这里,我读了几个关于这个主题的主题,但我的问题有点不同 我也不能使用Joda时间 示例: input values: 12:03:00 00:00:00 expected output: 11:57:00 С代码: public static void main(String[] args) throws ParseException { Scanner sc = ne

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

我也不能使用Joda时间

示例:

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

expected output: 11:57:00
С代码:

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

这就是你想要做的:

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);
    }
}

这就是你想要做的:

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);
    }
}

这里的基本缺陷是您需要两次之间的最近距离。在构建日期对象时,即使只设置小时:分钟:秒的格式,它仍然存储日/月/年等。。。对于日期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();
String t1=“12:03:00”;
字符串t2=“00:00:00”;
SimpleDataFormat sdf=新的SimpleDataFormat(“HH:mm:ss”);
日期d1=sdf.parse(t1);
日期d2=sdf.parse(t2);
Calendar c1=Calendar.getInstance();
Calendar c2=Calendar.getInstance();
c1.设定时间(d1);
c2.设定时间(d2);
if(c2.get(日历小时数)<12){
c2.set(日历年的日历日,c2.get(日历年的日历日)+1);
}
长时间运行=c2.getTimeInMillis()-c1.getTimeInMillis();

这里的基本缺陷是您想要两次之间的最近距离。在构建日期对象时,即使只设置小时:分钟:秒的格式,它仍然存储日/月/年等。。。对于日期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();
String t1=“12:03:00”;
字符串t2=“00:00:00”;
SimpleDataFormat sdf=新的SimpleDataFormat(“HH:mm:ss”);
日期d1=sdf.parse(t1);
日期d2=sdf.parse(t2);
Calendar c1=Calendar.getInstance();
Calendar c2=Calendar.getInstance();
c1.设定时间(d1);
c2.设定时间(d2);
if(c2.get(日历小时数)<12){
c2.set(日历年的日历日,c2.get(日历年的日历日)+1);
}
长时间运行=c2.getTimeInMillis()-c1.getTimeInMillis();
tl;博士 PT11H57M

使用纳秒 现代方法使用java.time类

问题是,只有在一天中的某个时候,才没有午夜。所以你的
00:00
显然是一天的结束,实际上被解释为一天的开始

离一天结束只有最后一纳秒了。
LocalTime
为最后一纳秒定义了一个常量:=
23:59:59.99999999

因为你只关心整秒,我们可以利用那分数秒。如果您的结束时间恰好是
00:00:00
,则替换为
LocalTime.MAX
。然后计算一个对象。您可以添加单个纳秒,然后通过将分数秒(纳秒)设置为零来截断生成的分数秒

对于非
00:00:00
的结束时间,数学仍然有效。添加一纳秒将使您获得秒的分数,并将截断不需要的分数

// 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 );
看这个

PT11H57M

格式化
toString
的输出是标准的。
Duration
类可以解析并生成这些字符串

我强烈建议不要用时间样式HH:MM:SS表示时间跨度。这是模棱两可的,当人类阅读时,往往会造成混乱

但是如果你坚持这种格式,你必须自己构建字符串。
Duration
类缺少其他java.time类中的
format
方法。奇怪的是,这个类最初缺少提取部分的方法,包括天数、小时、分钟、秒和分数秒。请参阅以进行讨论。Java9将这种名为
的方法引入到…部分

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

tl;博士 PT11H57M

使用纳秒 现代方法使用java.time类

问题是,只有在一天中的某个时候,才没有午夜。所以你的
00:00
显然是一天的结束,实际上被解释为一天的开始

离一天结束只有最后一纳秒了。
LocalTime
为最后一纳秒定义了一个常量:=
23:59:59.99999999

因为你只关心整秒,我们可以利用那分数秒。如果您的结束时间恰好是
00:00:00
,则替换为
LocalTime.MAX
。然后计算一个对象。您可以添加单个纳秒,然后通过将分数秒(纳秒)设置为零来截断生成的分数秒

对于非
00:00:00
的结束时间,数学仍然有效。添加一纳秒将使您获得秒的分数,并将截断不需要的分数

// 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 );
看这个

PT11H57M

格式化
toString
的输出是标准的。
Duration
类可以解析并生成这些字符串

我强烈建议不要用时间样式HH:MM:SS表示时间跨度。这