将org.joda.time.Period转换为java.time.Period [英] Converting org.joda.time.Period to 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屋!