Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replacing icu/calendar with java.time api #1508

Draft
wants to merge 11 commits into
base: main
Choose a base branch
from
7 changes: 1 addition & 6 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@
<dependency>
<groupId>io.usethesource</groupId>
<artifactId>vallang</artifactId>
<version>0.13.0</version>
<version>0.13.2-RC1</version>
</dependency>
<dependency>
<groupId>org.ow2.asm</groupId>
Expand Down Expand Up @@ -439,11 +439,6 @@
<artifactId>nanohttpd</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>com.ibm.icu</groupId>
<artifactId>icu4j</artifactId>
<version>58.1</version>
</dependency>
<dependency>
<groupId>org.asciidoctor</groupId>
<artifactId>asciidoctorj</artifactId>
Expand Down
134 changes: 70 additions & 64 deletions src/org/rascalmpl/interpreter/result/DateTimeResult.java
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
/*******************************************************************************
* Copyright (c) 2009-2013 CWI
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
* Copyright (c) 2009-2013 CWI All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v1.0 which accompanies this
* distribution, and is available at http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:

* * Jurgen J. Vinju - Jurgen.Vinju@cwi.nl - CWI
* * Mark Hills - Mark.Hills@cwi.nl (CWI)
* * Arnold Lankamp - Arnold.Lankamp@cwi.nl
*******************************************************************************/
*
* * Jurgen J. Vinju - Jurgen.Vinju@cwi.nl - CWI * Mark Hills - Mark.Hills@cwi.nl (CWI) * Arnold
* Lankamp - Arnold.Lankamp@cwi.nl
*******************************************************************************/
package org.rascalmpl.interpreter.result;

import static org.rascalmpl.interpreter.result.ResultFactory.bool;
import static org.rascalmpl.interpreter.result.ResultFactory.makeResult;

import java.time.Duration;
import java.time.LocalDate;
import java.time.Period;
import java.time.temporal.ChronoUnit;
import java.time.temporal.Temporal;
import java.util.Iterator;

import org.rascalmpl.exceptions.RuntimeExceptionFactory;
Expand All @@ -24,6 +26,8 @@
import org.rascalmpl.interpreter.staticErrors.UndeclaredField;
import org.rascalmpl.interpreter.staticErrors.UnexpectedType;
import org.rascalmpl.interpreter.staticErrors.UnsupportedOperation;
import org.rascalmpl.util.DateTimeConversions;
import org.rascalmpl.values.ValueFactoryFactory;

import io.usethesource.vallang.IBool;
import io.usethesource.vallang.IDateTime;
Expand All @@ -34,9 +38,6 @@
import io.usethesource.vallang.type.Type;
import io.usethesource.vallang.type.TypeFactory;
import io.usethesource.vallang.type.TypeStore;
import org.rascalmpl.values.ValueFactoryFactory;

import com.ibm.icu.util.Calendar;

public class DateTimeResult extends ElementResult<IDateTime> {

Expand Down Expand Up @@ -65,8 +66,7 @@ public <V extends IValue> Result<IBool> equals(Result<V> that) {

@Override
protected Result<IBool> equalToDateTime(DateTimeResult that) {
checkDateTimeComparison(that);
return bool(that.value.getInstant() == this.value.getInstant(), ctx);
return bool(that.value.equals(this.value), ctx);
}

@Override
Expand All @@ -76,8 +76,7 @@ public <V extends IValue> Result<IBool> nonEquals(Result<V> that) {

@Override
protected Result<IBool> nonEqualToDateTime(DateTimeResult that) {
checkDateTimeComparison(that);
return bool(that.value.getInstant() != this.value.getInstant(), ctx);
return bool(!that.value.equals(this.value), ctx);
}

@Override
Expand Down Expand Up @@ -282,26 +281,18 @@ public <U extends IValue, V extends IValue> Result<U> fieldUpdate(
}
}

private void checkDateTimeComparison(DateTimeResult that) {
if (that.getValue().isDate()) {
if (this.getValue().isTime()) {
throw new InvalidDateTimeComparison("date","time",ctx.getCurrentAST());
} else if (this.getValue().isDateTime()) {
throw new InvalidDateTimeComparison("date","datetime",ctx.getCurrentAST());
}
} else if (that.getValue().isTime()) {
if (this.getValue().isDate()) {
throw new InvalidDateTimeComparison("time","date",ctx.getCurrentAST());
} else if (this.getValue().isDateTime()) {
throw new InvalidDateTimeComparison("time","datetime",ctx.getCurrentAST());
}
} else {
if (this.getValue().isDate()) {
throw new InvalidDateTimeComparison("datetime","date",ctx.getCurrentAST());
} else if (this.getValue().isTime()) {
throw new InvalidDateTimeComparison("datetime","time",ctx.getCurrentAST());
}
private static String getName(IDateTime val) {
if (val.isDate()) {
return "date";
}
if (val.isTime()) {
return "time";
}
return "datetime";
}

private UnsupportedOperation reportInvalidComparison(IDateTime thisValue, IDateTime thatValue) {
return new UnsupportedOperation("Cannot compare " + getName(thisValue) + " to " + getName(thatValue), ctx.getCurrentAST());
}

@Override
Expand All @@ -311,8 +302,12 @@ public <V extends IValue> Result<IBool> greaterThan(Result<V> that) {

@Override
protected Result<IBool> greaterThanDateTime(DateTimeResult that) {
checkDateTimeComparison(that);
return bool(that.value.getInstant() > this.value.getInstant(), ctx);
try {
return bool(that.value.compareTo(this.value) > 0, ctx);
}
catch (UnsupportedOperationException e) {
throw reportInvalidComparison(this.value, that.value);
}
}

@Override
Expand All @@ -322,8 +317,12 @@ public <V extends IValue> Result<IBool> greaterThanOrEqual(Result<V> that) {

@Override
protected Result<IBool> greaterThanOrEqualDateTime(DateTimeResult that) {
checkDateTimeComparison(that);
return bool(that.value.getInstant() >= this.value.getInstant(), ctx);
try {
return bool(that.value.compareTo(this.value) >= 0, ctx);
}
catch (UnsupportedOperationException e) {
throw reportInvalidComparison(this.value, that.value);
}
}

@Override
Expand All @@ -333,8 +332,12 @@ public <V extends IValue> Result<IBool> lessThan(Result<V> that) {

@Override
protected Result<IBool> lessThanDateTime(DateTimeResult that) {
checkDateTimeComparison(that);
return bool(that.value.getInstant() < this.value.getInstant(), ctx);
try {
return bool(that.value.compareTo(this.value) < 0, ctx);
}
catch (UnsupportedOperationException e) {
throw reportInvalidComparison(this.value, that.value);
}
}

@Override
Expand All @@ -344,8 +347,13 @@ public <V extends IValue> LessThanOrEqualResult lessThanOrEqual(Result<V> that)

@Override
protected LessThanOrEqualResult lessThanOrEqualDateTime(DateTimeResult that) {
checkDateTimeComparison(that);
return new LessThanOrEqualResult(that.value.getInstant() < this.value.getInstant(), that.value.getInstant() == this.value.getInstant(), ctx);
try {
int result = that.value.compareTo(this.value);
return new LessThanOrEqualResult(result < 0, result == 0, ctx);
}
catch (UnsupportedOperationException e) {
throw reportInvalidComparison(this.value, that.value);
}
}

@Override
Expand All @@ -356,20 +364,18 @@ public <U extends IValue, V extends IValue> Result<U> subtract(Result<V> that) {
@Override
protected <U extends IValue> Result<U> subtractDateTime(DateTimeResult that) {
IDateTime dStart = this.getValue();
Calendar startCal = Calendar.getInstance();
startCal.setTimeInMillis(dStart.getInstant());

Temporal tStart = DateTimeConversions.dateTimeToJava(dStart);
IDateTime dEnd = that.getValue();
Calendar endCal = Calendar.getInstance();
endCal.setTimeInMillis(dEnd.getInstant());
Temporal tEnd = DateTimeConversions.dateTimeToJava(dEnd);

if (dStart.isDate()) {
if (dEnd.isDate()) {
Period result = Period.between((LocalDate)tStart, (LocalDate)tEnd);
return makeResult(Duration,
VF.constructor(DateTimeResult.duration,
VF.integer(startCal.fieldDifference(endCal.getTime(), Calendar.YEAR)),
VF.integer(startCal.fieldDifference(endCal.getTime(), Calendar.MONTH)),
VF.integer(startCal.fieldDifference(endCal.getTime(), Calendar.DAY_OF_MONTH)),
VF.integer(result.getYears()),
VF.integer(result.getMonths()),
VF.integer(result.getDays()),
VF.integer(0),
VF.integer(0),
VF.integer(0),
Expand All @@ -382,16 +388,17 @@ protected <U extends IValue> Result<U> subtractDateTime(DateTimeResult that) {
}
} else if (dStart.isTime()) {
if (dEnd.isTime()) {
Duration result = java.time.Duration.between(tStart, tEnd);
return makeResult(Duration,
VF.constructor(DateTimeResult.duration,
VF.integer(0),
VF.integer(0),
VF.integer(0),
VF.integer(startCal.fieldDifference(endCal.getTime(), Calendar.HOUR_OF_DAY)),
VF.integer(startCal.fieldDifference(endCal.getTime(), Calendar.MINUTE)),
VF.integer(startCal.fieldDifference(endCal.getTime(), Calendar.SECOND)),
VF.integer(startCal.fieldDifference(endCal.getTime(), Calendar.MILLISECOND))),
ctx);
VF.integer(result.toHours()),
VF.integer(result.toMinutes() % 60),
VF.integer(result.getSeconds() % 60),
VF.integer(result.toMillis() % 1000)
), ctx);
} else if (dEnd.isDate()) {
throw RuntimeExceptionFactory.invalidUseOfDateException("Cannot determine the duration between a time with no date and a date with no time.", ctx.getCurrentAST(), null);
} else {
Expand All @@ -401,13 +408,12 @@ protected <U extends IValue> Result<U> subtractDateTime(DateTimeResult that) {
if (dEnd.isDateTime()) {
return makeResult(Duration,
VF.constructor(DateTimeResult.duration,
VF.integer(startCal.fieldDifference(endCal.getTime(), Calendar.YEAR)),
VF.integer(startCal.fieldDifference(endCal.getTime(), Calendar.MONTH)),
VF.integer(startCal.fieldDifference(endCal.getTime(), Calendar.DAY_OF_MONTH)),
VF.integer(startCal.fieldDifference(endCal.getTime(), Calendar.HOUR_OF_DAY)),
VF.integer(startCal.fieldDifference(endCal.getTime(), Calendar.MINUTE)),
VF.integer(startCal.fieldDifference(endCal.getTime(), Calendar.SECOND)),
VF.integer(startCal.fieldDifference(endCal.getTime(), Calendar.MILLISECOND))),
VF.integer(ChronoUnit.MONTHS.between(tStart, tEnd) % 12),
VF.integer(ChronoUnit.DAYS.between(tStart, tEnd) % 31), // TODO is this right?
VF.integer(ChronoUnit.HOURS.between(tStart, tEnd) % 24),
VF.integer(ChronoUnit.MINUTES.between(tStart, tEnd) % 60),
VF.integer(ChronoUnit.SECONDS.between(tStart, tEnd) % 60),
VF.integer(ChronoUnit.MILLIS.between(tStart, tEnd) % 1000)),
ctx);
} else if (dEnd.isDate()) {
throw RuntimeExceptionFactory.invalidUseOfDateException("Cannot determine the duration between a datetime and a date with no time.", ctx.getCurrentAST(), null);
Expand Down
Loading