【问题标题】:Java add dates of format dd:HH:mm:ssJava 添加日期格式为 dd:HH:mm:ss
【发布时间】:2014-11-06 17:52:43
【问题描述】:

我有三个日期作为String 对象,格式为:dd:HH:mm:ss

  • 00:1:9:14
  • 00:3:10:4
  • 00:3:39:49

如何在 Java 中添加这些日期以获得总和 (00:7:59:07)?

示例代码:

SimpleDateFormat sdf = new SimpleDateFormat("dd:HH:mm:ss");
Date d1 = sdf.parse("00:1:9:14");
Date d2 = sdf.parse("00:3:10:4");
Date d3 = sdf.parse("00:3:39:49");

System.out.println(d1);
System.out.println(d2);
System.out.println(d3);
Date d = new Date(d1.getTime() + d2.getTime() + d3.getTime());

System.out.println(d);

输出(错误):

Wed Dec 31 01:09:14 IST 1969
Wed Dec 31 03:10:04 IST 1969
Wed Dec 31 03:39:49 IST 1969
Sun Dec 28 20:59:07 IST 1969

【问题讨论】:

  • 您希望如何添加日期?什么是“2008 年 12 月 14 日”加上“2013 年 10 月 12 日”?
  • This thread 似乎想做同样的事情。简而言之,将自纪元以来的总毫秒数相加,并根据结果创建一个新日期。
  • @mattias:请注意,您链接到的问题的公认答案是完全错误的。
  • @jambjo:是的,考虑到这一点,我猜不是总结实际日期值,而是计算两个表示为日期对象的“计时器值”。正如您所说的那样,将 2008 年与 2013 年相加会有什么好处/商业价值。
  • 仅供参考,java.util.Datejava.util.Calendarjava.text.SimpleDateFormat 等存在严重缺陷的日期时间类现在是 legacy,被 Java 8 及更高版本中内置的 java.time 类所取代.

标签: java date simpledateformat addition


【解决方案1】:

dd 格式包括月份中的某天。因此,如果您使用 SimpleDateFormat(或 Java Date,因为它还包括一个月中的某一天),您的 00 值将下溢。相反,请分析您的时间部分并自己计算。

例如,您可以创建一个类TimePartdayshoursminutesseconds 类似

static class TimePart {
    int days = 0;
    int hours = 0;
    int minutes = 0;
    int seconds = 0;

    static TimePart parse(String in) {
        if (in != null) {
            String[] arr = in.split(":");
            TimePart tp = new TimePart();
            tp.days = ((arr.length >= 1) ? Integer.parseInt(arr[0]) : 0);
            tp.hours = ((arr.length >= 2) ? Integer.parseInt(arr[1]) : 0);
            tp.minutes = ((arr.length >= 3) ? Integer.parseInt(arr[2]) : 0);
            tp.seconds = ((arr.length >= 4) ? Integer.parseInt(arr[3]) : 0);
            return tp;
        }
        return null;
    }

    public TimePart add(TimePart a) {
        this.seconds += a.seconds;
        int of = 0;
        while (this.seconds >= 60) {
            of++;
            this.seconds -= 60;
        }
        this.minutes += a.minutes + of;
        of = 0;
        while (this.minutes >= 60) {
            of++;
            this.minutes -= 60;
        }
        this.hours += a.hours + of;
        of = 0;
        while (this.hours >= 24) {
            of++;
            this.hours -= 24;
        }
        this.days += a.days + of;
        return this;
    }

    @Override
    public String toString() {
        return String.format("%02d:%02d:%02d:%02d", days, hours, minutes,
                seconds);
    }
}

然后你的测试用例就像

public static void main(String[] args) {
    try {
        TimePart d1 = TimePart.parse("00:1:9:14");
        TimePart d2 = TimePart.parse("00:3:10:4");
        TimePart d3 = TimePart.parse("00:3:39:49");
        System.out.println(d1);
        System.out.println(d2);
        System.out.println(d3);
        TimePart d4 = d1.add(d2).add(d3);
        System.out.println(d4);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

而且它似乎正确地执行了加法

00:01:09:14
00:03:10:04
00:03:39:49
00:07:59:07

【讨论】:

    【解决方案2】:

    上面的总和是算术加法,所以你需要一个 ref --here d0 (默认纪元)。 Date类有很多问题要小心...

    SimpleDateFormat sdf = new SimpleDateFormat("dd:HH:mm:ss");
    Date d0 = sdf.parse("00:00:00:00"); // ref 
    Date d1 = sdf.parse("00:01:09:14");
    Date d2 = sdf.parse("00:03:10:04");
    Date d3 = sdf.parse("00:03:39:49");
    
    System.out.println(d0);
    System.out.println(d1);
    System.out.println(d2);
    System.out.println(d3);
    Date d = new Date(d1.getTime() + d2.getTime() + d3.getTime() - 2 * d0.getTime()); // impt
    
    System.out.println(d);
    

    注意:- 添加日期不是一件容易的事,请三思而后行。

    【讨论】:

    • 答案是关于你期望得到o/p 00:7:59:07
    【解决方案3】:
    SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss");    
    
    String s1 = "01:02:03";
    String s2 = "10:12:13";
    
    Date d1 = format.parse(s1);
    Date d2 = format.parse(s2);
    
    int sec = d1.getSeconds() + d2.getSeconds();
    int min = d1.getMinutes() + d2.getMinutes();
    int hr = d1.getHours() + d2.getHours();
    
    Time sum = new Time(hr, min, sec);
    System.out.println(sum); // Output: 11:14:16
    

    【讨论】:

    • 像魅力一样工作.. 例如。 01:02:03 + 10:12:13 = 11:14:16
    【解决方案4】:

    您的字符串是否代表/表示时间量?所以使用Duration 类。我们先写一个辅助方法,将字符串解析成Duration

    private static Duration parseDuration(String timeString) {
        // First convert the string to ISO 8601 through a regex
        String isoTimeString = timeString.replaceFirst("^(\\d+):(\\d+):(\\d+):(\\d+)$", "P$1DT$2H$3M$4S");
        // Then parse into Duration
        return Duration.parse(isoTimeString);
    }
    

    Duration.parse() 需要 ISO 8601 格式,它在 1 小时 9 分 14 秒的时间段内类似于PT1H9M14S。或可选P0DT1H9M14S。 0 天的 0DT 之前。因此,我在解析之前使用正则表达式(AKA a regex)将您的字符串格式修改为 ISO 8601。替换字符串中的$1$2等是指圆括号内匹配的内容,即正则表达式中的groups

    现在我们可以把时间加起来了:

        String[] timeStrings = { "00:1:9:14", "00:3:10:4", "00:3:39:49" };
    
        Duration totalTime = Duration.ZERO;
        for (String timeString : timeStrings) {
            Duration dur = parseDuration(timeString);
            totalTime = totalTime.plus(dur);
        }
    
        System.out.println(totalTime);
    

    输出:

    PT7H59M7S

    7 小时 59 分 7 秒。如果需要,您可以将其重新格式化为 00:7:59:07 格式。搜索方法。

    你的代码出了什么问题?

    您的第一个错误似乎是在编写代码之前:将时间视为日期。它们不是,添加日期没有任何意义。 4 月 7 日和 12 月 25 日的总和是多少?

    被这种想法误导,你试图解析成Date 对象。 Date 是一个时间点,而不是一个时间量,所以这是错误的。除此之外,Date 类的设计很差,而且您还尝试使用的 SimpleDateFormat 类非常麻烦。幸运的是,我们在这里没有使用它们,而且日期和时间也早已过时,被现代 Java 日期和时间 API java.time 取代,其中Duration 只是众多类之一。

    链接

    【讨论】:

    • 那是你在那里做的一些花哨的正则表达式!对于可能不知道的读者,我确实建议您添加它实际上是正则表达式的提及。
    • 我会在源代码之前提到正则表达式。这就像旁白,告诉我在我的视线移动到研究代码时会发生什么。
    • 感谢@BasilBourque 的建议。我明白你的意思了。我的风格更多的是先呈现具体的代码,然后再进行解释。作为妥协?不,我认为这种方式实际上很有帮助,我在该代码行之前的代码中的注释中提到了正则表达式。
    【解决方案5】:
    private static String addTimes(String time1, String time2) throws ParseException {
        SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
    
        Calendar c1 = Calendar.getInstance();
        Calendar c2 = Calendar.getInstance();
        c1.setTime(dateFormat.parse(time1));
        c2.setTime(dateFormat.parse(time2));
    
        c1.add(Calendar.HOUR, c2.get(Calendar.HOUR));
        c1.add(Calendar.MINUTE, c2.get(Calendar.MINUTE));
        c1.add(Calendar.SECOND, c2.get(Calendar.SECOND));
        return dateFormat.format(c1.getTime());
    }
    
    addTimes("1:9:14", "3:10:4");    
    

    输出:04:19:18

    【讨论】:

    • (1) Calendar 类早已过时且设计不佳。我建议我们不要使用它。 (2) Calendar 是一天中的日期和时间(带有时区、周编号方案等)。它不是一个持续时间,一个时间量。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-03-20
    • 1970-01-01
    • 2010-11-03
    • 2013-01-28
    • 2022-11-20
    • 2010-09-29
    • 2011-11-16
    相关资源
    最近更新 更多