【问题标题】:Removing '-' from negative Joda time Periods从负 Joda 时间段中删除“-”
【发布时间】:2020-08-24 00:39:48
【问题描述】:

我有一个关于减去 Joda DateTimes 的问题,我使用 Period 来获取两者之间的日期、小时、分钟和秒数。

输出示例:2 天 11 小时 23 分钟 05 秒

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 天 -11h -23min -05sec

所以我想知道有没有办法让它看起来像这样: - 2 天 11 小时 23 分 05 秒,整个事情前面只有一个“-”。但是使用Joda相关的功能。

或者至少有一种方法可以告诉我 Period 是否为负数。

我可以使用字符串操作来做到这一点,但它似乎有点太手动了。

谢谢。

【问题讨论】:

    标签: java date jodatime subtraction


    【解决方案1】:

    你需要比较两个日期。

    isAfterisBefore 方法按毫秒比较日期(忽略时区)。

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

    现在,您可以按正确的顺序设置参数。
    然后,如果需要,添加前导减号。

    【讨论】:

    • 我明白了,我可以使用它来控制 Period 构造函数中的参数顺序并相应地添加“+”或“-”。谢谢。
    【解决方案2】:

    不幸的是,Period 没有方法 abs()Duration 相比。

    但是,我们可以编写自己的辅助方法来实现这一点,借助 Period::negated() 方法:

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

    此外,如果您不喜欢静态方法,您可以将此逻辑提取到单独的类(我认为这绝对是更好的选择):

    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;
            }
        }
    }
    

    以及这个test-sn-p产生的对应STDOUT:

    original period = -365 Days
    absolute period = 365 Days
    

    【讨论】:

    • 这似乎比在构造函数上设置条件更容易理解,我将把它与前面的答案结合起来。谢谢
    猜你喜欢
    • 1970-01-01
    • 2015-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-06
    • 1970-01-01
    • 2021-10-05
    • 1970-01-01
    相关资源
    最近更新 更多