将org.joda.time.Period转换为java.time.Period [英] Converting org.joda.time.Period to java.time.Period

查看:103
本文介绍了将org.joda.time.Period转换为java.time.Period的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试用java.time替换org.joda.time.Period.

I am trying to replace org.joda.time.Period with java.time.

我们在数据库中存储了以下值.

We have the following values stored in DB.

P1M, P1Y, P1D, PT1H, PT1M

只需解析该值,

Period monthly = ISOPeriodFormat.standard().parsePeriod(<One of the above value from DB>);

这很简单,并且按预期方式获得了期间.但是,现在用java.time替换很麻烦.

This is simple and getting Period as expected. But, now replacing with java.time is troublesome.

因为,P1D, P1M, P1Y应该使用以下代码进行解析,

Because, P1D, P1M, P1Y should be parsed using the below code,

java.time.Period period = java.time.Period.parse("P1M");

java.time.Period period = java.time.Period.parse("P1M");

并且,P1H and P1D应该使用以下代码进行解析.

And, P1H and P1D should be parsed using the below code.

Duration dailyD = Duration.parse("P1D");

所以,我可能还需要一些字符串检查,

So, I might need some string check also like,

if(value.startsWith("PT")) {
   // Use java.time.Duration
} else {
   // Use java.time.Period
}

此逻辑是否还有更好的代码?

Is there any better code for this logic?

此外,最后,我将不得不根据上述java.time.Period或java.time.Duration找到从开始时间到现在为止的发生次数.

Also, Finally, I will have to find the number of occurances from some startTime to till date based on the above java.time.Period or java.time.Duration.

例如,如果startDateTime为01/01/2015 08:30

Like, If startDateTime is 01/01/2015 08:30,

LocalDateTime startDateTime = // the above startDateTime ..

    if(value.startsWith("PT")) {
       // Use java.time.Duration
     ChronoUnit.SECONDS.between(startDateTime,curentDate)/(duration.toMillis()/1000)
    } else {

 if(value.endsWith("Y")) {
       // Use java.time.Period
ChronoUnit.YEARS.between(startDateTime,curentDate)/(period.getYears()/1000)
} else if(value.endsWith("M")){
 ChronoUnit.MONTHS.between(startDateTime,curentDate)/(period.getMonths()/1000)
}

如果没有这个值解析,还有其他更好的方法吗?

Is there any other better way without this value parsing?

我的输入可能有P2M,P10M,P2Y,PT15M,PT10M.它不会像P1MT10M一样具有期间"和时间"的组合.但是可能有数月,数年或数天.

My input could have P2M, P10M, P2Y, PT15M, PT10M. It wont have the combination of both Period and time like P1MT10M. But any number of months, years or days possible.

推荐答案

Java-8没有像org.joda.time.Period类那样复杂的持续时间类型.但是您可以直接创建自己的接口TemporalAmount实现:

Java-8 does not have such a complex duration type like the class org.joda.time.Period. But you can create your own implementation of the interface TemporalAmount in a straight-forward way:

import java.time.DateTimeException;    
import java.time.temporal.ChronoUnit;
import java.time.temporal.Temporal;
import java.time.temporal.TemporalAmount;
import java.time.temporal.TemporalUnit;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import static java.time.temporal.ChronoUnit.*;

public class SimpleDuration implements TemporalAmount {

    private static final List<TemporalUnit> SUPPORTED_UNITS =
        Collections.unmodifiableList(Arrays.asList(YEARS, MONTHS, DAYS, HOURS, MINUTES));

    private final int amount;
    private final ChronoUnit unit;

    private SimpleDuration(int amount, ChronoUnit unit) {
        this.amount = amount;
        this.unit = unit;
    }

    public static SimpleDuration of(int amount, ChronoUnit unit) {
        if (SUPPORTED_UNITS.contains(unit)) {
            return new SimpleDuration(amount, unit);
        } else {
            throw new IllegalArgumentException("Not supported: " + unit);
        }
    }

    @Override
    public long get(TemporalUnit unit) {
        if (this.unit.equals(unit)) {
          return this.amount;
        }
        return 0;
    }

    @Override
    public List<TemporalUnit> getUnits() {
        return SUPPORTED_UNITS;
    }

    @Override
    public Temporal addTo(Temporal temporal) {
        return temporal.plus(this.amount, this.unit);
    }

    @Override
    public Temporal subtractFrom(Temporal temporal) {
        return temporal.minus(this.amount, this.unit);
    }

    @Override
    public boolean equals(Object obj) {
        if (obj instanceof SimpleDuration) {
            SimpleDuration that = (SimpleDuration) obj;
            return this.unit == that.unit && this.amount == that.amount;
        } else {
            return false;
        }
    }

    @Override
    public int hashCode() {
        return this.unit.hashCode() + 37 * Integer.hashCode(this.amount);
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        if (this.amount < 0) {
            sb.append('-');
        }
        sb.append('P');
        if (this.unit.isTimeBased()) {
            sb.append('T');
        }
        sb.append(Math.abs(this.amount));
        switch (this.unit) {

            case YEARS :
                sb.append('Y');
                break;

            case MONTHS :
                sb.append('M');
                break;

            case DAYS :
                sb.append('D');
                break;

            case HOURS :
                sb.append('H');
                break;

            case MINUTES :
                sb.append('M');
                break;

            default :
                throw new UnsupportedOperationException(this.unit.name());
        }
        return sb.toString();
    }

    public static SimpleDuration parse(String input) {
        int len = input.length();
        int index = 0;
        boolean negative = false;
        if (len > 0 && input.charAt(0) == '-') {
            negative = true; // for XML-Schema (not for ISO-8601)
            index++;
        }
        if (len >= 3 && input.charAt(index) == 'P') {
            boolean timeBased = (input.charAt(index + 1) == 'T');
            char last = input.charAt(len - 1);
            ChronoUnit unit;
            switch (last) {

                case 'Y' :
                    unit = YEARS;
                    break;

                case 'M' :
                    unit = (timeBased ? MINUTES : MONTHS);
                    break;

                case 'D' :
                    unit = DAYS;
                    break;

                case 'H' :
                    unit = HOURS;
                    break;

                default :
                    throw new DateTimeException(
                        "Unknown unit symbol found at last position: " + input
                    );
            }
            if (unit.isTimeBased() != timeBased) {
                throw new DateTimeException("Invalid XML-Schema-format: " + input);
            }
            try {
              int amount =
                Integer.parseInt(
                  input.substring(index).substring(timeBased ? 2 : 1, len - 1 - index));
              if (amount < 0) {
                throw new DateTimeException(
                  "XML-Schema does not allow negative amounts inside: " + input);
              }
              return SimpleDuration.of(negative ? -amount : amount, unit);
            } catch (NumberFormatException ex) {
                throw new DateTimeException("Invalid XML-Schema-format: " + input, ex);
            }
        }
        throw new DateTimeException("Cannot parse: " + input);
    }

    public static void main(String... args) {
        System.out.println(parse("-PT10M")); // -PT10M
    }
}

这篇关于将org.joda.time.Period转换为java.time.Period的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆