当前位置: 首页 > 知识库问答 >
问题:

将org.joda.time.Period转换为java.time.Period

夏景同
2023-03-14

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

我们将以下值存储在DB中。

P1M, P1Y, P1D, PT1H, PT1M

只是为了解析这个值,

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

这是一个简单的过程,并且正如预期的那样。但是,现在它正被java取代。时间很麻烦。

因为,P1D, P1M, P1Y应该使用下面的代码解析,

Java . time . period period = Java . time . period . parse(" P1M ");

并且,< code>P1H和P1D应该使用下面的代码进行解析。

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

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

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

这个逻辑还有更好的代码吗?

此外,最后,我必须根据上面的java.time.Period或java.time.Duration找到从某个开始时间到截止日期的发生次数。

例如, 如果 startDateTime 是 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)
}

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

我的输入可以有P2M、P10M、P2Y、PT15M、PT10M。它不会像P1MT10M那样同时包含周期和时间。但是可以有任意数量的月、年或天。

共有1个答案

邵锐
2023-03-14

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

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
    }
}
 类似资料:
  • 问题内容: 我正在开发一些应用程序,它允许从SD卡中选择图像,将其保存到数据库中并为ImageView设置此值。我需要知道将uri转换为字符串并将字符串转换为uri的方法。现在,我使用了Uri的getEncodedPath()方法,但是例如,此代码不起作用: 因此,我不知道如何将Uri保存到数据库中并根据保存的值创建新的Uri。请帮我修复它。 问题答案: 我需要知道将uri转换为字符串并将字符串转

  • 我正在努力将图像标记转换为链接并复制标记内的参数,即。 进入 我的问题不仅仅是复制src和alt数据,还包括丢失和额外的标记。 进入 和 进入 这需要对整个字符串中img标记的所有实例执行。 不是说听起来像是一个挑战,但是有人能提出一个可能的解决方案吗,我相信这可以用preg_replace但是我就是做不到? 非常感谢。

  • 最近,我浏览了一些网站,将中缀转换成前缀符号,最后我被卷了起来。 我已经给出了我所做的步骤。。 例:-(1(2*3))(5*6)(7/8) 方法1:-(无需任何算法的手动转换):- 方法2:- 根据现场情况http://scanftree.com/Data_Structure/infix-to-prefix 所以,在这里我完全被绞死了。 请任何人提供以下方面的信息:- 关于我在以上2种方法中哪里出

  • 问题内容: 如何从float转换为string或从string转换为float? 在我的情况下,我需要在2个值字符串(我从表中获得的值)和我计算出的浮点值之间进行断言。 我尝试从浮动到字符串: 但是断言失败 问题答案: 使用Java的类。 为了进行比较,将字符串转换为float并比较两个float总是更好。这是因为对于一个浮点数,存在多个字符串表示形式,与字符串相比,它们是不同的(例如“ 25”!

  • 我们正在获取具有以下字段的订单数据(仅显示相关字段) 具有NULLoriginal_orderid的订单可以被认为是父订单 其中一些父母订单可能有子订单,子订单的original_orderid映射到父母的订单。 子顺序可以产生另一个子顺序,如图像所示,带有颜色编码。 与原始文本相同的数据: 作为转换,我们需要将所有子节点映射到它们的原始父节点(original_orderid为NULL),并获得

  • 问题内容: 有没有一种简单的方法可以避免处理文本编码问题? 问题答案: 您确实无法避免处理文本编码问题,但是Apache Commons中已有一些解决方案: 至: 至: 您只需要选择所需的编码即可。