Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions jmeos-core/src/main/java/types/collections/time/tstzset.java
Original file line number Diff line number Diff line change
Expand Up @@ -591,9 +591,9 @@ public boolean is_over_or_before(TemporalObject other) throws Exception {
public Duration distance(Object other) throws Exception {
Duration answer = null;
if (other instanceof LocalDateTime) {
answer= Duration.ofSeconds((long)GeneratedFunctions.distance_set_timestamptz(this._inner, ConversionUtils.datetimeToTimestampTz((LocalDateTime) other)));
answer= ConversionUtils.interval_to_timedelta(GeneratedFunctions.distance_set_timestamptz(this._inner, ConversionUtils.datetimeToTimestampTz((LocalDateTime) other)));
} else if (other instanceof tstzset) {
answer= Duration.ofSeconds((long)GeneratedFunctions.distance_tstzset_tstzset(this._inner, ((tstzset) other)._inner));
answer= ConversionUtils.interval_to_timedelta(GeneratedFunctions.distance_tstzset_tstzset(this._inner, ((tstzset) other)._inner));
} else if (other instanceof tstzspan) {
answer= Duration.ofSeconds((long)this.to_span().distance((TemporalObject) other));
// Duration.ofSeconds((long)GeneratedFunctions.distance_tstzspanset_tstzspan(this.to_spanset(tstzspan.class).get_inner(), ((tstzspan) other).get_inner()));
Expand Down
11 changes: 8 additions & 3 deletions jmeos-core/src/main/java/types/collections/time/tstzspan.java
Original file line number Diff line number Diff line change
Expand Up @@ -787,15 +787,20 @@ public boolean is_over_or_after(TemporalObject other) throws Exception {
public double distance(TemporalObject other) throws Exception {
double returnValue;
switch (other){
case tstzspan p -> returnValue = GeneratedFunctions.distance_tstzspan_tstzspan(this._inner,p.get_inner());
case tstzspanset ps -> returnValue = GeneratedFunctions.distance_tstzspanset_tstzspan(ps.get_inner(),this._inner);
case tstzspan p -> returnValue = seconds(GeneratedFunctions.distance_tstzspan_tstzspan(this._inner,p.get_inner()));
case tstzspanset ps -> returnValue = seconds(GeneratedFunctions.distance_tstzspanset_tstzspan(ps.get_inner(),this._inner));
case tstzset ts -> returnValue = ts.to_span().distance(other);
case Box b -> returnValue = GeneratedFunctions.distance_tstzspan_tstzspan(this._inner, b.to_period().get_inner());
case Box b -> returnValue = seconds(GeneratedFunctions.distance_tstzspan_tstzspan(this._inner, b.to_period().get_inner()));
default -> throw new TypeNotPresentException(other.getClass().toString(), new Throwable("Operation not supported with this type"));
}
return returnValue;
}

/** The seconds, with their fraction, of the interval MEOS answers as a distance of times. */
private static double seconds(Pointer interval) {
return ConversionUtils.interval_to_timedelta(interval).toNanos() / 1e9;
}

/*------------------------ Set Operations ------------------------*/

/**
Expand Down
39 changes: 10 additions & 29 deletions jmeos-core/src/main/java/utils/ConversionUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@
import java.sql.SQLException;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


/**
Expand Down Expand Up @@ -73,34 +71,17 @@ public static Pointer timedelta_to_interval(Duration td){
}

public static Duration interval_to_timedelta(Pointer p){
String res= GeneratedFunctions.interval_out(p);
Pattern pattern = Pattern.compile("(\\d+)\\s+days(?:\\s+(\\d{2}):(\\d{2}):(\\d{2}))?");
Matcher matcher = pattern.matcher(res);

if (matcher.matches()) {
// Extract days from the string
int days = Integer.parseInt(matcher.group(1));

// Initialize hours, minutes, and seconds to zero
int hours = 0;
int minutes = 0;
int seconds = 0;

// If the time component is present, extract hours, minutes, and seconds
if (matcher.group(2) != null) {
hours = Integer.parseInt(matcher.group(2));
minutes = Integer.parseInt(matcher.group(3));
seconds = Integer.parseInt(matcher.group(4));
}

// Calculate the total duration in seconds
long totalSeconds = days * 86400L + hours * 3600L + minutes * 60L + seconds;

// Create and return the Duration object
return Duration.ofSeconds(totalSeconds);
} else {
throw new IllegalArgumentException("Invalid interval format");
// The fields of MEOS's Interval, laid out as the catalog states it: the microseconds
// `time` at byte 0, `day` at byte 8 and `month` at byte 12. A month has no fixed length,
// so an interval holding one has no Duration.
long time = p.getLongLong(0);
int day = p.getInt(8);
int month = p.getInt(12);
if (month != 0) {
throw new IllegalArgumentException("an interval of " + month
+ " month(s) has no fixed duration");
}
return Duration.ofDays(day).plus(Duration.of(time, java.time.temporal.ChronoUnit.MICROS));
}

public static Pointer intrange_to_intspan(Range<Integer> intrange) throws SQLException {
Expand Down
4 changes: 2 additions & 2 deletions jmeos-core/src/test/java/collections/time/TsTzSetTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -193,8 +193,8 @@ public void testIsOverOrAfterFunction() throws Exception {
public void testDistanceFunction() throws Exception {
GeneratedFunctions.meos_initialize_timezone("UTC");
tstzset tmp_set = new tstzset("{2020-01-01 00:00:00+0, 2020-01-31 00:00:00+0}");
System.out.println(Duration.ofSeconds((long) GeneratedFunctions.distance_tstzset_tstzset(tset.get_inner(), tmp_set.get_inner())));
tset.distance(tmp_set);
// From 2019-09-03, the last instant of tset, to 2020-01-01
assertEquals(Duration.ofDays(120), tset.distance(tmp_set));
}


Expand Down
19 changes: 19 additions & 0 deletions jmeos-core/src/test/java/utils/ConversionUtilsIntervalTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;

/**
* Verifies that a {@link Duration} survives conversion to a MEOS interval and back.
Expand All @@ -31,6 +32,24 @@ void durationRoundTripsThroughAMeosInterval() {
}
}

@Test
void everyIntervalWithoutMonthsIsItsDuration() {
// One day, a time below a day, a fraction of a second, and days with a time
String[] texts = {"1 day", "03:04:05", "00:00:01.25", "2 days 00:00:00.000001"};
Duration[] durations = {Duration.ofDays(1), Duration.ofSeconds(3 * 3600 + 4 * 60 + 5),
Duration.ofMillis(1250), Duration.ofDays(2).plusNanos(1000)};
for (int i = 0; i < texts.length; i++)
assertEquals(durations[i], ConversionUtils.interval_to_timedelta(
GeneratedFunctions.interval_in(texts[i], -1)), texts[i]);
}

@Test
void anIntervalOfMonthsHasNoDuration() {
Pointer interval = GeneratedFunctions.interval_in("1 mon", -1);
assertThrows(IllegalArgumentException.class,
() -> ConversionUtils.interval_to_timedelta(interval));
}

@Test
void wholeDaysProduceTheExpectedIntervalText() {
Pointer interval = ConversionUtils.timedelta_to_interval(Duration.ofDays(2));
Expand Down
Loading