Создание новой даты из разницы / вычитание двух периодов (с отрицательным временем)

1

Я хочу вычесть 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 (чт 01 января 01:06:00 CET 1970), я думаю, что это зависит от часового пояса. Но как я могу это решить? Должен ли я изменить часовой пояс jvm?

Теги:
date
timezone
time

4 ответа

1
Лучший ответ

Пространство времени

Ваш вопрос непонятен. Видимо, вы хотите работать с промежутком времени. Для этого вам определенно нужна библиотека Joda-Time (или новый пакет java.time, встроенный в Java 8).

Joda времени

Joda-Time предлагает 3 класса для промежутков времени:

  • интервал
    Представляет пару точек старта-остановки вдоль временной шкалы. Пример: 2013-01-01T00:00:00.000-05:00/2013-01-04T18:00:00.000-05:00
  • продолжительность
    Длительность в миллисекундах. Не привязаны к временной шкале.
  • период
    Представляет диапазон как количество полей, таких как годы, месяцы, недели, дни, часы, минуты, секунды и миллины.

ISO 8601

Стандарт ISO 8601 определяет разумные текстовые форматы для представления различных аспектов значений даты и времени. Joda-Time (и java.time в Java 8) использует ISO 8601 в качестве значений по умолчанию.

В частности, ISO 8601 определяет формат для Durations (то, что Joda-Time вызывает период †). Значение представлено в виде строки в формате PnYnMnDTnHnMnS. "P" указывает начало строки продолжительности (Period). 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" и одного из этих трех имен классов, чтобы найти много примеров.


† Временные термины сильно различаются по их использованию и значению. Началось новое стандартное предложение о нормализации таких условий. Но на данный момент привыкнуть к тому, чтобы "переводить" термины при переключении контекстов.

  • 0
    Мне нужно работать только с ЧЧ: мм. Было бы полезно иметь это тоже: 18:30 - 18:40 = -00: 10
  • 0
    @Accollativo (а) Я добавил пример кода для иллюстрации. (б) Вы бы нашли такие примеры, если бы искали StackOverflow. (c) Потратьте некоторое время на учебу. Дата-время работы удивительно сложна и хитра.
4

Обратите внимание на javadoc конструктора Date(long)

Выделяет объект Date и инициализирует его для представления указанного количества миллисекунд с момента стандартного базового времени, известного как "эпоха", а именно 1 января 1970 года, 00:00:00 GMT.

Это не интервал.

Joda-Time предоставляет класс Interval для выполнения таких вычислений. Java 8 также должен иметь такой класс, когда он выходит.

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);
  • 0
    Это не работает, если: long разность = a.getTime () - b.getTime () - c.getTime (); Может быть, лучше использовать Joda Time ...
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;
    }

}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню