简体   繁体   English

计算Java中的日期和时间差

[英]Calculate Date And Time Difference In Java

I have three database (SQLServer) fields: 我有三个数据库(SQLServer)字段:

  1. startDate (Date) startDate(日期)
  2. endDate (Date) endDate(日期)
  3. Duration (text). 持续时间(文本)。

I am calculating date and time difference by using java following code. 我正在通过使用Java以下代码来计算日期和时间差。

public static void main(String[] args) {

      DateTimeUtils obj = new DateTimeUtils();
      SimpleDateFormat simpleDateFormat = 
                new SimpleDateFormat("dd/M/yyyy hh:mm:ss");

      try {

        Date date1 = simpleDateFormat.parse("10/10/2013 11:30:10");
        Date date2 = simpleDateFormat.parse("13/10/2013 20:55:55");

        obj.printDifference(date1, date2);

      } catch (ParseException e) {
        e.printStackTrace();
      }

    }

public void printDifference(Date startDate, Date endDate){

        //milliseconds
        long different = endDate.getTime() - startDate.getTime();
        String diff = "";
        System.out.println("startDate : " + startDate);
        System.out.println("endDate : "+ endDate);
        System.out.println("different : " + different);


        diff = String.format("%d:%d", TimeUnit.MILLISECONDS.toHours(different), TimeUnit.MILLISECONDS.toMinutes(different) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(different)));

And It returns “HH:MM” and updates the Duration field as String in my database. 并且它返回“ HH:MM”,并在我的数据库中将Duration字段更新为String。 This works great. 这很好。

Now there will be multiple duration, what I want to do is once I have Duration, I would like to do add up multiple duration and it should return totalDuration: 现在将有多个持续时间,我想做的是一旦有了持续时间,我想做多个持续时间,它应该返回totalDuration:

For Example: In my table # 1 I have, 例如:在我的1号表中

Id | ID | Duration 持续时间

1001 | 1001 | 05:04 05:04

1001 | 1001 | 12:19 12:19

1001 | 1001 | 02:16 02:16

Table # 2 表#2

Id | ID | totalDuration totalDuration

1001 | 1001 | 19:39 19:39

My Question is: How do I convert HH:Mm to Date and add multiple records together to get totalDuration. 我的问题是:如何将HH:Mm转换为Date并将多个记录加在一起以获得totalDuration。 Total duration should be text and return the same format “HH:MM 总时长应为文本,并返回相同的格式“ HH:MM

如果您在表1中确实有开始和结束的日期值,则使用datediff并将这些值求和会容易得多。

If you still have all the values you worked out then just accumulate a long millisecond count as you go and use that. 如果您仍然拥有所有已计算出的值,则只需在使用时累积一个较长的毫秒数即可。

If not then there are a few ways, the simplest is probably going to be: 如果没有,那么有几种方法,最简单的方法可能是:

String[] split = duration.split(":");
long duration = Long.parseLong(split[0])*60*60*1000 + Long.parseLong(split[1])*60*1000;

You can then loop through adding up all those durations, then at the end convert it back to a String . 然后,您可以循环添加所有这些持续时间,最后将其转换回String

Really you should store the millisecond count in your database and then convert it to text to display though. 确实,您应该将毫秒计数存储在数据库中,然后将其转换为文本以显示。

Question Not Clear 问题不清楚

Your question is not clear. 您的问题不清楚。 (a) Question fails to address issue of time zones. (a)问题未能解决时区问题。 Are these date-times all in UTC/GMT? 这些日期时间都在UTC / GMT中吗? (b) Your example dates seem to be 3 days apart, yet your code returns only hours and minutes. (b)您的示例日期似乎相隔3天,但是您的代码仅返回小时和分钟。

Joda-Time 乔达时间

Trying to roll your own date-time calculations usually leads to trouble and frustration. 尝试滚动自己的日期时间计算通常会带来麻烦和沮丧。 See if a good date-time library can help you, such as Joda-Time or the new java.time.* classes bundled with Java 8. 查看良好的日期时间库是否可以为您提供帮助,例如Joda-Time或Java 8附带的新java.time。*类。

ISO 8601 Duration ISO 8601持续时间

The international standard for date and time, ISO 8601 , defines a way to work with what it calls durations . 日期和时间的国际标准ISO 8601定义了一种使用工期的方法 Historically, the concept has also been called periods. 历史上,该概念也被称为时期。 A duration tracks the concept of elapsed time in terms of years, months, days, hours, and minutes. 持续时间以年,月,日,小时和分钟为单位来跟踪经过时间的概念。

A value is represented as a string in the format of PnYnMnDTnHnMnS . 值以PnYnMnDTnHnMnS的格式表示为字符串。 The 'P' indicates the beginning of a duration (Period) string. “ P”表示持续时间(句点)字符串的开头。 A 'T' indicates the time portion. “ T”表示时间部分。 Each number precedes its element designator. 每个数字都在其元素标识符之前。 For example, "P3Y6M4DT12H30M5S" represents a duration of "three years, six months, four days, twelve hours, thirty minutes, and five seconds". 例如,“ P3Y6M4DT12H30M5S”表示持续时间为“三年,六个月,四天,十二小时,三十分钟和五秒”。

Joda-Time is ISO 8601 savvy, offering the Period class to represent an ISO duration. Joda-Time精通ISO 8601,提供了Period类来表示ISO持续时间。 A Period can be constructed by passing an ISO duration string. 可以通过传递ISO持续时间字符串来构造Period。 Likewise, the default toString implementation on Period outputs an ISO duration string. 同样,Period上的默认toString实现输出一个ISO持续时间字符串。 You could store that ISO duration string in your database. 您可以将该ISO持续时间字符串存储在数据库中。 Joda-Time Period instances can be added together by calling the plus method. 可以通过调用plus方法将Joda-Time Period实例添加在一起。

Example Code 范例程式码

Here's example code using Joda-Time 2.3 in Java 7. I sourced the two date-time strings from your question. 这是在Java 7中使用Joda-Time 2.3的示例代码。我从您的问题中获取了两个日期时间字符串。 To demonstrate addition, I add an extra 5 minutes. 为了演示添加,我另外增加了5分钟。

Good practice dictates being explicit about time zones rather than rely on defaults. 优良作法要求明确显示时区,而不要依赖默认值。 Here I use Paris, choosing so arbitrarily. 在这里,我使用巴黎,所以随意选择。 You may well be using UTC/GMT (no time zone offset), in which case you may pass the pre-defined time zone DateTimeZone.UTC . 您可能正在使用UTC / GMT(无时区偏移),在这种情况下,您可以传递预定义的时区DateTimeZone.UTC

// © 2013 Basil Bourque. This source code may be used freely forever by anyone taking full responsibility for doing so.
// import org.joda.time.*;
// import org.joda.time.format.*;

DateTimeZone timeZone_Paris = DateTimeZone.forID( "Europe/Paris" ); // Or for UTC/GMT, use: DateTimeZone.UTC
DateTimeFormatter formatter = DateTimeFormat.forPattern( "dd/MM/yyyy HH:mm:ss" ).withZone( timeZone_Paris );

DateTime start = formatter.parseDateTime( "10/10/2013 11:30:10" );
DateTime stop = formatter.parseDateTime( "13/10/2013 20:55:55" );
Period period = new Period( start, stop );

DateTime now = new DateTime( timeZone_Paris );
Period period2 = new Period( now , now.plusMinutes( 5 ));

Period total = period.plus( period2 );

Dump to console… 转储到控制台...

System.out.println( "start: " + start.toString() );
System.out.println( "stop: " + stop.toString() );
System.out.println( "period: " + period.toString() );
System.out.println();
System.out.println( "now: " + now.toString() );
System.out.println( "period2: " + period2.toString() );
System.out.println();
System.out.println( "total: " + total.toString() );

When run… 运行时...

start: 2013-10-10T11:30:10.000+02:00
stop: 2013-10-13T20:55:55.000+02:00
period: P3DT9H25M45S

now: 2013-12-24T01:03:10.029+01:00
period2: PT5M

total: P3DT9H30M45S

Note how the 25M increased to 30M . 注意25M如何增加到30M

Date-Time Strings 日期时间字符串

Tip: If you control those date-time strings as shown in your example code, your work will be easier if you switched to using the standard ISO 8601 format. 提示:如果按示例代码中所示控制日期和时间字符串,则改用标准ISO 8601格式将使您的工作更加轻松。 For example: 2013-12-21T21:03:48+05:30 or 2013-12-21T21:03:48Z . 例如: 2013-12-21T21:03:48+05:302013-12-21T21:03:48Z

Using the "dd/M/yyyy hh:mm:ss" format is ambiguous. 使用“ dd / M / yyyy hh:mm:ss”格式不明确。 No reason to use that rather than the standard format. 没有理由使用它而不是标准格式。 A bonus: The standard format gives a chronological order when sorting alphabetically. 额外的好处:标准​​格式在按字母顺序排序时按时间顺序排列。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM