从差异创建新日期/减去两个周期(具有负时间)

时间:2014-03-16 16:12:35

标签: java date time timezone

我想减去2个日期并保存差异:

SimpleDateFormat formatter = new SimpleDateFormat("HH:mm");
Date a = formatter.parse("08:06");
Date b = formatter.parse("08:00");
Date asd =  new Date(a.getTime() - b.getTime());

问题是 asd 不是00:06,而是01:06(Thu Jan 01 01:06:00 CET 1970),我认为这取决于时区。但是我该如何解决这个问题呢?我应该更改jvm时区吗?

4 个答案:

答案 0 :(得分:4)

请注意Date(long) constructor

的javadoc
  

分配Date个对象并初始化它以表示指定的对象   自标准基准时间以来被称为"的毫秒数   时代",即1970年1月1日00:00:00 GMT。

这不是间隔。

Joda-Time确实提供了Interval类来执行此类计算。它出现时,Java 8也应该有such a class

答案 1 :(得分:3)

long difference = a.getTime() - b.getTime();
int hours = (int) (difference / 3600000);
int minutes = (int) (difference % 3600000 / 60000);
String formatted = String.format("%02d:%02d", hours, minutes);

答案 2 :(得分:1)

时间跨度

你的问题不明确。显然你想要在一段时间内工作。为此,您肯定需要Joda-Time库(或内置于java.time package的新Java 8)。

约达时间

Joda-Time提供3个课程时间跨度:

  • Interval
    代表时间轴上的起止点对。示例:2013-01-01T00:00:00.000-05:00/2013-01-04T18:00:00.000-05:00
  • Duration
    一段时间(以毫秒为单位)。与时间表无关。
  • Period
    以多个字段表示范围,例如年,月,周,日,小时,分钟,秒和毫秒。

ISO 8601

ISO 8601标准定义了合理的文本格式来表示日期时间值的各个方面。 Joda-Time(以及Java 8中的java.time)使用ISO 8601作为其默认值。

特别是,ISO 8601定义了Durations的格式(Joda-Time称之为句号†)。值以PnYnMnDTnHnMnS的格式表示为字符串。 ' P'表示持续时间(句点)字符串的开头。 A' T'表示时间部分。每个数字都在其元素指示符之前。例如," P3Y6M4DT12H30M5S"表示持续时间为三年,六年,四天,十二小时,三十分钟和五十秒。

示例代码

// Specify the time zone rather than rely on default. https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
DateTimeZone timeZone = DateTimeZone.forID( "Europe/Rome" );
DateTime a = new DateTime( 2014, 1, 2, 8, 6, 0, timeZone );
DateTime b = new DateTime( 2014, 1, 2, 8, 0, 0, timeZone );
Period period = new Period( a, b);
long millis = period.toStandardDuration().getMillis();

转储到控制台...

System.out.println( "a: " + a );
System.out.println( "b: " + b );
System.out.println( "period: " + period );
System.out.println( "millis: " + millis );

跑步时......

a: 2014-01-02T08:06:00.000+01:00
b: 2014-01-02T08:00:00.000+01:00
period: PT-6M
millis: -360000

更多信息

搜索StackOverflow" joda"以及这三个类名中的一个可以找到很多例子。


†时间相关术语的用法和含义差异很大。已经开始实施这些术语规范化的新标准提案。但是,现在,习惯于不得不翻译"切换上下文时的术语。

答案 3 :(得分:0)

感谢您的所有解决方案,这对我的下一个项目非常有用。

但我不需要Joda内部的所有东西,我只需要轻量级的东西来总结和减去时间(并且有负时间),所以我花几分钟时间来创建我自己的时间处理类。

自由使用:

public class Time {

    private int hours;
    private int minutes;
    private long totalMinutes;

    public Time()
    {
        hours = 0;
        minutes = 0;
        totalMinutes = 0;
    }

    public Time(String time) throws RuntimeException
    {
        try
        {
            String[] items = time.split(":");
            this.hours = Integer.parseInt(items[0]);
            this.minutes = Integer.parseInt(items[1]);
            this.totalMinutes = hours*60+minutes;
        }
        catch (RuntimeException re)
        {
            throw new RuntimeException("Parsing time error", re);
        }
    }

    public Time(Time time)
    {
        this.hours = time.hours;
        this.minutes = time.minutes;
        this.totalMinutes = time.totalMinutes;
    }

    public Time add(Time val)
    {
        Time ret = new Time(this);
        ret.totalMinutes += val.totalMinutes;
        ret.hours = (int) Math.abs( (long)ret.totalMinutes/60 );
        ret.minutes = (int) Math.abs( (long)ret.totalMinutes%60 );
        return ret;
    }

    public Time sub(Time val)
    {
        Time ret = new Time(this);
        ret.totalMinutes -= val.totalMinutes;
        ret.hours = (int) Math.abs( (long)ret.totalMinutes/60 );
        ret.minutes = (int) Math.abs( (long)ret.totalMinutes%60 );
        return ret;
    }

    public int getHours() {
        return hours;
    }

    public void setHours(int hours) {
        this.hours = hours;
    }

    public int getMinutes() {
        return minutes;
    }

    public void setMinutes(int minutes) {
        this.minutes = minutes;
    }

    @Override
    public String toString() 
    {
        StringBuilder tmpHHmm = new StringBuilder("" + hours);
        if (totalMinutes<0)
        {
            tmpHHmm.insert(0, "-");
        }
        if (hours<10)
        {
            tmpHHmm.insert(tmpHHmm.length()-1, "0");
        }
        tmpHHmm.append(":"+minutes);
        if (minutes<10)
        {
            tmpHHmm.insert(tmpHHmm.length()-1, "0");
        }
        return tmpHHmm.toString();
    }

    public long getTotalMinutes() {
        return totalMinutes;
    }

    public void setTotalMinutes(long totalMinutes) {
        this.totalMinutes = totalMinutes;
    }

}