Удаление '-' из отрицательных периодов времени Joda - PullRequest
2 голосов
/ 08 мая 2020

У меня есть вопрос относительно вычитания Joda DateTimes, и я использую Period, чтобы получить количество дат, часов, минут и секунд между ними.

Пример вывода: 2 дня 11h 23min 05se c

DateTimeFormatter formatter = DateTimeFormat.forPattern("dd/MM/yyyy HH:mm:ss");
DateTime firstDate = formatter.parseDateTime(firstStringDateValue);
DateTime secondDate = formatter.parseDateTime(secondStringDateValue);

DurationFieldType[] types = {DurationFieldType.days(), 
                             DurationFieldType.hours(), 
                             DurationFieldType.minutes(), 
                             DurationFieldType.seconds()};

Period period = new Period(firstDate, secondDate, PeriodType.forFields(types));

PeriodFormatter periodFormatter = new PeriodFormatterBuilder()
            .minimumPrintedDigits(2)
            .appendDays().appendSuffix(" Day", " Days").appendSeparator(" ")
            .appendHours().appendSuffix("h").appendSeparator(" ")
            .appendMinutes().appendSuffix("min").appendSeparator(" ")
            .appendSeconds().appendSuffix("sec")
            .toFormatter();

String result = periodFormatter.print(period);

Проблема в том, что дата начала больше даты окончания.

Результат примерно такой: -2 дня -11ч -23мин-05сек c

Так что мне было интересно, есть ли способ сделать так, чтобы это выглядело так: - 2 дня 11ч 23мин 05сек c, только с одним знаком «-» перед всем. Но используя функции, связанные с Joda.

Или, по крайней мере, способ сообщить мне, отрицательный ли период.

Я могу сделать это, используя манипуляции со строками, но это кажется слишком ручным.

Спасибо.

Ответы [ 2 ]

2 голосов
/ 08 мая 2020

К сожалению, Period не имеет метода abs() по сравнению с Duration.

Однако мы можем написать наш собственный вспомогательный метод для достичь этого с помощью метода Period::negated():

public static Period periodAbs(Period period) {
    return period.toStandardSeconds().getSeconds() < 0
        ? period.negated()
        : period;
}

Кроме того, вы можете извлечь этот logi c в отдельный класс (это определенно лучший выбор, на мой взгляд), если вы не Мне не нравятся методы c:

public static class AbsPeriod {
    private final Period period;

    public AbsPeriod(Period period) {
        this.period = period;
    }

    public Period value() {
        return period.toStandardSeconds().getSeconds() < 0
            ? period.negated()
            : period;
    }
}

Полный пример выполнения:

import org.joda.time.DateTime;
import org.joda.time.DurationFieldType;
import org.joda.time.Period;
import org.joda.time.PeriodType;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.joda.time.format.PeriodFormatter;
import org.joda.time.format.PeriodFormatterBuilder;

class Scratch {
    public static void main(String[] args) {
        DateTimeFormatter formatter = DateTimeFormat.forPattern("dd/MM/yyyy HH:mm:ss");
        DateTime firstDate = formatter.parseDateTime("12/11/2001 12:12:12");
        DateTime secondDate = formatter.parseDateTime("12/11/2000 12:12:12");

        DurationFieldType[] types = {DurationFieldType.days(),
            DurationFieldType.hours(),
            DurationFieldType.minutes(),
            DurationFieldType.seconds()};

        Period period = new Period(firstDate, secondDate, PeriodType.forFields(types));

        PeriodFormatter periodFormatter = new PeriodFormatterBuilder()
            .minimumPrintedDigits(2)
            .appendDays().appendSuffix(" Day", " Days").appendSeparator(" ")
            .appendHours().appendSuffix("h").appendSeparator(" ")
            .appendMinutes().appendSuffix("min").appendSeparator(" ")
            .appendSeconds().appendSuffix("sec")
            .toFormatter();

        System.out.println("original period = " + periodFormatter.print(period));
        System.out.println("absolute period = " + periodFormatter.print(new AbsPeriod(period).value()));
    }

    public static class AbsPeriod {
        private final Period period;

        public AbsPeriod(Period period) {
            this.period = period;
        }

        public Period value() {
            return period.toStandardSeconds().getSeconds() < 0
                ? period.negated()
                : period;
        }
    }
}

И соответствующий STDOUT, созданный этим тестовым фрагментом:

original period = -365 Days
absolute period = 365 Days
2 голосов
/ 08 мая 2020

Что вам нужно, так это сравнение двух дат.

Существуют методы isAfter и isBefore , которые сравнивают даты в миллисекундах (без учета часового пояса).

firstDate.isBefore(secondDate)
firstDate.isAfter(secondDate)

Теперь вы можете установить параметры в правильном порядке.
Затем, при необходимости, добавьте начальный минус.

...