java.time period,将org.joda.time.Period转换为java.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

Just to parse this value,

Period monthly = ISOPeriodFormat.standard().parsePeriod();

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

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

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

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?

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.

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?

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

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值