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
Prev Previous commit
Next Next commit
Fixed bugs in parsing time values
DavyLandman committed Jun 15, 2021
commit 68562706bcfcefcef728cc1bde2ba451d883fe91
54 changes: 46 additions & 8 deletions src/org/rascalmpl/semantics/dynamic/JustTime.java
Original file line number Diff line number Diff line change
@@ -15,12 +15,16 @@

import java.io.IOException;
import java.io.StringReader;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.rascalmpl.exceptions.ImplementationError;
import org.rascalmpl.interpreter.IEvaluator;
import org.rascalmpl.interpreter.result.Result;
import org.rascalmpl.interpreter.staticErrors.DateTimeSyntax;

import io.usethesource.vallang.IConstructor;
import io.usethesource.vallang.IDateTime;
import io.usethesource.vallang.ISourceLocation;
import io.usethesource.vallang.IValue;
import io.usethesource.vallang.exceptions.FactParseError;
@@ -39,22 +43,56 @@ public Lexical(ISourceLocation __param1, IConstructor tree, String __param2) {
public Result<IValue> interpret(IEvaluator<Result<IValue>> __eval) {
// Time is of the form $T<time>
String timePart = this.getString().substring(2);
return createVisitedTime(__eval, timePart, this);
return createVisitedTime(__eval, timePart.substring(0, timePart.length() - 1), this);
}

private static final Pattern MILLI_SECONDS = Pattern.compile("\\.([0-9]+)");
private static final Pattern ZONE_OFFSET = Pattern.compile("([\\-+]([0-9][0-9]):?([0-9][0-9])?|Z)");

private Result<IValue> createVisitedTime(IEvaluator<Result<IValue>> eval, String timePart, org.rascalmpl.ast.JustTime.Lexical x) {
try {
timePart = timePart.replaceAll(":","");
int hourPart;
int minutePart;
int secondsPart;
if (!timePart.contains(":")) {
hourPart = Integer.parseInt(timePart.substring(0, 2));
minutePart = Integer.parseInt(timePart.substring(2, 4));
secondsPart = Integer.parseInt(timePart.substring(4, 6));
}
else {
hourPart = Integer.parseInt(timePart.substring(0, 2));
minutePart = Integer.parseInt(timePart.substring(3, 5));
secondsPart = Integer.parseInt(timePart.substring(6, 8));
}
int millisecondsPart = 0;
Matcher milliMatcher = MILLI_SECONDS.matcher(timePart);
if (milliMatcher.find()) {
String subPart = milliMatcher.group(1);
// we have to right pad with zeros
subPart = String.format("%-3s", subPart).replace(' ', '0');
millisecondsPart = Integer.parseInt(subPart);
}
IDateTime result;
Matcher zoneMatcher = ZONE_OFFSET.matcher(timePart);
if (zoneMatcher.find()) {
int factor = timePart.contains("-") ? -1 : 1;

StandardTextReader parser = new StandardTextReader();
IValue result = parser.read(VF, new StringReader("$T" + timePart));
int timeZoneHours = 0;
int timeZoneSeconds = 0;
if (zoneMatcher.groupCount() >= 2) {
timeZoneHours = factor * Integer.parseInt(zoneMatcher.group(2));
}
if (zoneMatcher.groupCount() == 3) {
timeZoneSeconds = factor * Integer.parseInt(zoneMatcher.group(3));
}
result = VF.time(hourPart, minutePart, secondsPart, millisecondsPart, timeZoneHours, timeZoneSeconds);
}
else {
result = VF.time(hourPart, minutePart, secondsPart, millisecondsPart);
}
return makeResult(TF.dateTimeType(), result, eval);
} catch (FactTypeUseException e) {
throw new DateTimeSyntax(e.getMessage(), eval.getCurrentAST().getLocation());
} catch (FactParseError e){
throw new DateTimeSyntax(e.getMessage(), eval.getCurrentAST().getLocation());
} catch (IOException e) {
throw new ImplementationError(e.getMessage());
}
}
}