【问题标题】:Java calculate time difference between check in and outJava计算签入和签出之间的时间差
【发布时间】:2019-01-16 10:12:29
【问题描述】:

我想用java dateformat

计算时差时分

用户应该像这样输入 打卡时间:23:00 下班时间:01:00

预期输出应类似于 2 小时 00 分钟

但是我该如何计算它们呢?

Scanner input = new Scanner(System.in);

    //Read data
    System.out.print("Clock In: ");
    String sTimeIn = input.nextLine();

    System.out.print("Clock Out: ");
    String sTimeOut = input.nextLine();

    // Process data
    String sHourIn = sTimeIn.substring(0, 2);
    String sMinuteIn = sTimeIn.substring(3, 5);
    String sHourOut = sTimeOut.substring(0, 2);
    String sMinuteOut = sTimeOut.substring(3, 5);

    int iHourIn = Integer.parseInt(sHourIn);
    int iMinuteIn = Integer.parseInt(sMinuteIn);
    int iHourOut = Integer.parseInt(sHourOut);
    int iMinuteOut = Integer.parseInt(sMinuteOut);

    int sumHour =
    int sumMinute = 

    //Display Output
    System.out.print(sumHour +"Hour "+ sumMinute + " Minute");

}

}

在我查看了您提供的所有解决方案之后。这是我编辑的内容。但是我还是发现了一个问题, 如果 时钟在 23:00 时钟输出:01:00 并且输出是 22Hour(s) 0 Minute(s)。输出应该是02 Hour(s) 0 Minute(s)

System.out.println("*Your time format must be 00:00");
        System.out.print("Clock In: ");
        String getTimeIn = input.nextLine();

        System.out.print("Clock Out: ");
        String getTimeOut = input.nextLine();

        // Process data
        String sHourIn = getTimeIn.substring(0, 2);
        String sMinuteIn = getTimeIn.substring(3, 5);
        String sHourOut = getTimeOut.substring(0, 2);
        String sMinuteOut = getTimeOut.substring(3, 5);

        int sumHour = Integer.parseInt(sHourIn) - Integer.parseInt(sHourOut);
        int sumMinute = Integer.parseInt(sMinuteIn) - Integer.parseInt(sMinuteOut);

        if(sumHour < 0) {
            sumHour =-sumHour;
        }

        if(sumMinute < 0) {
            sumMinute =- sumMinute;
        }

        //Display Output
         System.out.print(sumHour +"Hour(s) "+ sumMinute + " Minute(s)");

【问题讨论】:

  • Time api中有Java提供的获取数据的方法,你为什么不用呢?
  • @Jens 我已经提到“不使用日期格式”
  • @GaryHooi 我没有提到日期格式。
  • @GaryHooi 是的,我已经看到了。但是因为我从来没有说过任何关于使用 dateformat 的事情,或者你在说什么,我不明白你的意思。

标签: java time


【解决方案1】:

如果你想使用 Java 8 的 LocalTimeChronoUnit 类:

String sTimeIn = "23:15";
String sTimeOut = "1:30";
LocalTime timeIn = LocalTime.parse(sTimeIn, DateTimeFormatter.ofPattern("H:m"));
LocalTime timeOut = LocalTime.parse(sTimeOut, DateTimeFormatter.ofPattern("H:m"));
long dif = ChronoUnit.MINUTES.between(timeIn, timeOut);
if (dif < 0)
    dif += 24 * 60;
long sumHour = dif / 60;
long sumMinute = dif % 60;

System.out.println(sumHour + ":"+ sumMinute);

或格式化为HH:mm:

System.out.println(String.format("%02d", sumHour) + ":"+ String.format("%02d", sumMinute));

将打印:

02:15

【讨论】:

  • 你在正确的轨道上。最好还是使用Duration 类,让它为你做小时和分钟之间的转换。
  • 不使用日期格式化程序是要求的一部分
【解决方案2】:

正如@Stultuske 所说,时间库应该是一个更安全的选择,我在下面提供了一个示例

import java.time.LocalTime;

public class HelloWorld
{
  public static void main(String[] args)
  {
      LocalTime in = LocalTime.parse("18:20");
      LocalTime out = LocalTime.parse("20:30");

      int hoursDiff = (out.getHour() - in.getHour()),
          minsDiff  = (int)Math.abs(out.getMinute() - in.getMinute()),
          secsDiff  = (int)Math.abs(out.getSecond() - in.getSecond());

      System.out.println(hoursDiff+":"+minsDiff+":"+secsDiff);
  }
}

更新:

解决方案缺少 @Joakim Danielson 指出的午夜十字路口,因此我修改了上述解决方案以检查 in &gt; outout &lt; in

import java.time.LocalTime;

public class HelloWorld
{
  public static void main(String[] args)
  {
      LocalTime in = LocalTime.parse("16:00");
      LocalTime out = LocalTime.parse("01:00");

      int hOut = out.getHour(),
          hIn  = in.getHour();

      int hoursDiff = hOut < hIn ? 24 - hIn + hOut : hOut - hIn,
          minsDiff  = (int)Math.abs(out.getMinute() - in.getMinute()),
          secsDiff  = (int)Math.abs(out.getSecond() - in.getSecond());

      System.out.println(hoursDiff+":"+minsDiff+":"+secsDiff);
  }
}

【讨论】:

  • 这个答案不处理午夜穿越,当 in > out。
  • @JoakimDanielson 好点,我没想到,下面编辑的解决方案应该可以解决。
【解决方案3】:

这是我建议的解决方案,包括对输入的一些简单(不完美)验证,我已将解决方案放在一个方法中,因此不会处理询问用户输入

public static void calcTime(String sTimeIn, String sTimeOut) {
    final String timePattern = "[0-2][0-9]:[0-5][0-9]";

    if (sTimeIn == null || sTimeOut == null || !sTimeIn.matches(timePattern) || !sTimeIn.matches(timePattern)) {
        throw new IllegalArgumentException();
    }

    String[] timeIn = sTimeIn.split(":");
    String[] timeOut = sTimeOut.split(":");

    int inMinutes = 60 * Integer.valueOf(timeIn[0]) + Integer.valueOf(timeIn[1]);
    int outMinutes = 60 * Integer.valueOf(timeOut[0]) + Integer.valueOf(timeOut[1]);

    int diff = 0;
    if (outMinutes > inMinutes) {
        diff = outMinutes - inMinutes;
    } else if (outMinutes < inMinutes) {
        diff = outMinutes + 24 * 60 - inMinutes;
    }

    System.out.printf("Time difference between %s and %s is %d hours and %d minutes\n", sTimeIn, sTimeOut, diff / 60, diff % 60);
}

更新
这里是基于LocalTimeDuration的解决方案

public static void calcTime2(String sTimeIn, String sTimeOut) {
    final String timePattern = "[0-2][0-9]:[0-5][0-9]";

    if (sTimeIn == null || sTimeOut == null || !sTimeIn.matches(timePattern) || !sTimeIn.matches(timePattern)) {
        throw new IllegalArgumentException();
    }

    String[] timeIn = sTimeIn.split(":");
    String[] timeOut = sTimeOut.split(":");

    LocalTime localTimeIn = LocalTime.of(Integer.valueOf(timeIn[0]), Integer.valueOf(timeIn[1]));
    LocalTime localTimeOut = LocalTime.of(Integer.valueOf(timeOut[0]), Integer.valueOf(timeOut[1]));

    Duration duration;
    if (localTimeOut.isAfter(localTimeIn)) {
        duration = Duration.between(localTimeIn, localTimeOut);
    } else {
        Duration prevDay = Duration.ofHours(24).minusHours(localTimeIn.getHour()).minusMinutes(localTimeIn.getMinute());
        Duration nextDay = Duration.between(LocalTime.MIDNIGHT, localTimeOut);
        duration = prevDay.plus(nextDay);
    }

    System.out.printf("Time difference between %s and %s is %d hours and %d minutes\n", sTimeIn, sTimeOut,
            duration.toHours(), duration.minusHours(duration.toHours()).toMinutes());     
}

【讨论】:

  • @GaryHooi 对此有何反馈?
【解决方案4】:

试试这个:

public static void main(String[] args) {
  Scanner input = new Scanner(System.in);
   //Read data
   System.out.println("Clock In: ");
   String sTimeIn = "20:30";

   System.out.println("Clock Out: ");
   String sTimeOut = "18:20";

   // Process data
   String sHourIn = sTimeIn.substring(0, 2);
   String sMinuteIn = sTimeIn.substring(3, 5);
   String sHourOut = sTimeOut.substring(0, 2);
   String sMinuteOut = sTimeOut.substring(3, 5);

   int iHourIn = Integer.parseInt(sHourIn);
   int iMinuteIn = Integer.parseInt(sMinuteIn);
   int iHourOut = Integer.parseInt(sHourOut);
   int iMinuteOut = Integer.parseInt(sMinuteOut);

   Calendar cal = Calendar.getInstance();

   cal.set(Calendar.HOUR_OF_DAY,iHourIn);
   cal.set(Calendar.MINUTE,iMinuteIn);
   cal.set(Calendar.SECOND,0);
   cal.set(Calendar.MILLISECOND,0);
   Long timeIn = cal.getTime().getTime();

   cal.set(Calendar.HOUR_OF_DAY,iHourOut);
   cal.set(Calendar.MINUTE,iMinuteOut);
   cal.set(Calendar.SECOND,0);
   cal.set(Calendar.MILLISECOND,0);
   Long timeOut = cal.getTime().getTime();

   Long finaltime=  timeIn-timeOut;

   // Convert the result to Hours and Minutes

   Long temp = null;
   // get hours
   temp = finaltime % 3600000 ;
   int sumHour = (int) ((finaltime - temp) / 3600000 );

   finaltime = temp;

   int sumMinute = (int) (finaltime/ 60000);

   //Display Output
   System.out.println(sumHour +" Hour "+ sumMinute + " Minute");
}   

【讨论】:

  • 这个答案不处理午夜穿越,当 in > out。
【解决方案5】:

除了您的代码之外,我还添加了一些代码。请检查并告诉我这是否足以满足您的要求

public class MainClass1 {

public static void main(String[] args) {
    Scanner input = new Scanner(System.in);

    //Read data
    System.out.print("Clock In: ");
    String[] sTimeIn = input.nextLine().split(":");

    System.out.print("Clock Out: ");
    String[] sTimeOut = input.nextLine().split(":");

    int iHourIn = Integer.parseInt(sTimeIn[0]);
    int iMinuteIn = Integer.parseInt(sTimeIn[1]);
    int iHourOut = Integer.parseInt(sTimeOut[0]);
    int iMinuteOut = Integer.parseInt(sTimeOut[1]);

    if(iMinuteIn < iMinuteOut) {
        iMinuteIn = 60 + iMinuteIn;
        iHourIn--;
    }
    int sumHour = iHourIn - iHourOut;
    int sumMinute = iMinuteIn - iMinuteOut;

            //Display Output
            System.out.print(sumHour +"Hour "+ sumMinute + " Minute");


    }
}

【讨论】:

  • 最好使用 split(":") 调用来分隔小时和分钟,否则 "5:15" 可能会得到意想不到的结果
  • 如果 in 是 23:55 并且 out 是 00:05 你会得到什么结果,你希望它是什么?
  • @Stultuske 你是对的。我已经重构了代码。 @Joakim 我假设外出时间总是大于时间。这取决于加里的要求。我们可以为此添加一个额外的条件
  • @SabeshRajendran 00:005 今天早上的时间,大于昨天 23:55。
猜你喜欢
  • 1970-01-01
  • 2016-04-23
  • 1970-01-01
  • 2010-09-21
  • 2018-04-03
  • 1970-01-01
  • 2016-12-17
  • 2017-11-04
  • 2020-12-18
相关资源
最近更新 更多