我正在尝试用java.time替换org.joda.time.Period。
我们在DB中存储了以下值。
P1M, P1Y, P1D, PT1H, PT1M
只是解析这个值,
Period monthly = ISOPeriodFormat.standard().parsePeriod(<One of the above value from DB>);
这很简单,并按预期获得Period。但是,现在用java.time替换是很麻烦的。
因为,P1D, P1M, P1Y
应使用以下代码解析,
java.time.Period period = java.time.Period.parse(“P1M”);
并且,P1H and 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找到从某个startTime到date的出现次数。
喜欢,如果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那样具有时间和时间的组合。但任何数月,数年或数天都可能。
答案 0 :(得分:2)
Java-8没有像类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
}
}
实现:
XML