Skip to content

Refactoring of time handling objects #572

Open
elliVM wants to merge 20 commits intoteragrep:mainfrom
elliVM:instant-timestamp-test-fix
Open

Refactoring of time handling objects #572
elliVM wants to merge 20 commits intoteragrep:mainfrom
elliVM:instant-timestamp-test-fix

Conversation

@elliVM
Copy link
Copy Markdown
Contributor

@elliVM elliVM commented Apr 23, 2025

Refactor the responsibilities of time handling objects

Parsing of incoming pure string values

Introduces new way of parsing and handling timestamps.
Incoming pure string values of timestamp and time format are handled by the DPLTimestampString object that accepts the value, accepted parsing formats and the base time, user can provide own timeformat in other case a set list of default time formats is used. Parsing result is accepted only if a single value is matched against the provided formats. DPLTimestampString has asDPLTimestamp method that produces a DPLTimestamp interface that represents the parsed timestamp, if no acceptable parsing result was found the result will be a stub object.

DPL timestamp interface to represent a parsed timestamp

DPLTimestamp interface has a method to produces a Java's ZonedDateTime object for the timestamp that can be used to calculate epoch seconds and various other time values for the timestamp

DPLTimestamp implementing classes

AbsoluteTimestamp is responsible for handling dates eg. 2020-01-01.

RelativeTimestamp calculates relative values e.g. -1day that are calculated from the provided base time.

Test cases are updated to use UTC without reliance on system default and changing of JVM default timezone.

@elliVM elliVM self-assigned this Apr 23, 2025
@elliVM elliVM requested a review from eemhu April 23, 2025 07:39
@kortemik
Copy link
Copy Markdown
Member

this alters the jvm state as setDefault for TimeZone will change the state globally and modifying global state in a test case is a no-go. please see https://docs.oracle.com/javase/8/docs/api/java/util/TimeZone.html#getDefault--

@eemhu
Copy link
Copy Markdown
Contributor

eemhu commented Apr 23, 2025

I wonder if it would be better to add an additional ctor to InstantTimestamp that allows defining the timezone. This ctor could be used in tests. The default ctor would use the system timezone.

@elliVM
Copy link
Copy Markdown
Contributor Author

elliVM commented Apr 24, 2025

Will refactor to have a constructor with a timezone and otherwise use system default timezone

Copy link
Copy Markdown
Contributor

@eemhu eemhu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes look good to me, but should the DefaultTimeFormatTest and DPLTimeFormatTest also be changed to use the new ctor?

@elliVM
Copy link
Copy Markdown
Contributor Author

elliVM commented Apr 25, 2025

yea I will update the other tests also

Comment thread src/test/java/com/teragrep/pth10/DefaultTimeFormatTest.java
Comment thread src/test/java/com/teragrep/pth10/DefaultTimeFormatTest.java
@elliVM
Copy link
Copy Markdown
Contributor Author

elliVM commented Apr 25, 2025

Made #573 for other test cases still using TimeZone.setDefault("Europe/Helsinki")

eemhu
eemhu previously approved these changes Apr 25, 2025
Copy link
Copy Markdown
Contributor

@eemhu eemhu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

builds ok, LGTM

@elliVM elliVM added the review label Apr 25, 2025
Comment thread src/main/java/com/teragrep/pth10/ast/time/InstantTimestamp.java Outdated
@elliVM
Copy link
Copy Markdown
Contributor Author

elliVM commented Apr 29, 2025

Noted that If the value for example 2024-10-31T10:10:10Z contains zone information like Z zulu time (UTC) it will take precedence over SimpleDateFormat.setTimezone when calling SimpleDateFormat.parse(time). Meaning that the resulting instant is always for UTC and the method ZoneId value is ignored. This happens if DefaultTimeFormat is used when time format is empty or null.

Meaning that if timestamp has valid zone info it will overwrite timezone set by setTimezone method

@elliVM
Copy link
Copy Markdown
Contributor Author

elliVM commented May 2, 2025

Some DPL tests have time value with lower case z at the end, e.g. earliest=2020-12-12T00:00:00z. I suspect it was meant to set a timezone like UTC? This was ignored by the old SimpleDateFormat when parsing the value. In the documentation z was used only in the format as a "general time zone" but in a parsed value it has no function.
Replaced the legacy SimpleDateFormat with a DateTimeFormatter, this means that the z input now throws an exception instead of being ignored.

This happens only if the default absolute timestamp formats are used to parse the value.

Fix?

  • Change lowercase z to Z in java and this would apply a UTC to these values and ignore the system default. z would be an alias to Z (non ISO 8601).

  • Change test cases to use Z instead of z , only accept Zin the query and have z throw an exception (ISO 8601).

  • Enforce the zone from the class member field (System default timezone outside of test cases). This would remove the ability to set time zones in the values when no time format is given.

  • Treat all values as uppercased

@elliVM elliVM changed the title InstantTimestampTest test timezone fix Refactoring of time handling objects May 2, 2025
@elliVM elliVM marked this pull request as draft May 2, 2025 09:40
@elliVM elliVM removed the review label May 2, 2025
@elliVM elliVM force-pushed the instant-timestamp-test-fix branch from 743fff7 to cbd07aa Compare May 2, 2025 12:18
@elliVM
Copy link
Copy Markdown
Contributor Author

elliVM commented May 2, 2025

rebased

@elliVM
Copy link
Copy Markdown
Contributor Author

elliVM commented May 12, 2025

Refactoring time relative objects

@elliVM elliVM force-pushed the instant-timestamp-test-fix branch from a2a1884 to 7c00fc5 Compare May 16, 2025 10:37
@elliVM
Copy link
Copy Markdown
Contributor Author

elliVM commented May 16, 2025

rebased

@elliVM
Copy link
Copy Markdown
Contributor Author

elliVM commented May 19, 2025

Refactored relative time objects

Comment thread src/main/java/com/teragrep/pth10/ast/time/DefaultFormatAbsoluteTimestamp.java Outdated
Comment on lines +173 to +179
private long offsetAmount() {
final String validAmountString = new ValidOffsetAmountText(offsetText).read();
return Long.parseLong(validAmountString);
}

private OffsetUnit offsetUnit() {
final String validUnitString = new ValidOffsetUnitText(offsetText).read();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe these two should be their own objects?

List<String> expectedResults = Collections
.singletonList(
"978303661" // +0300 timezone
"978310861" // +0300 timezone
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

expected result changed?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tests default timezone changed to UTC I updated the comment

}

@Test
public void testUserDefinedFormat() {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test invalid user defined format also

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added invalid input test

// Assert equals with expected
Assertions.assertEquals(1644487237L, lstA.get(0).getLong(0));
Assertions.assertEquals(1645048800L, lstB.get(0).getLong(0));
Assertions.assertEquals(1645056000L, lstB.get(0).getLong(0));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

expected changed?

Instant now = timestamp.toInstant().plus(-3, ChronoUnit.HOURS);

String expected = String.valueOf(now.getEpochSecond()).substring(0, 7); // don't check the seconds within a minute, as the query takes some time and might be a few seconds off
long latestEpoch = ZonedDateTime.now(utcZone).minusHours(3).toEpochSecond();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be able to define startTime now so no substring trickery needed

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cleaned up the relativeTimeTest all tests now directly assert the expected epochs against the actualy epochs in the query

@elliVM elliVM force-pushed the instant-timestamp-test-fix branch 2 times, most recently from 8857d24 to 9764a82 Compare September 29, 2025 07:37
@elliVM
Copy link
Copy Markdown
Contributor Author

elliVM commented Sep 29, 2025

Rebased

elliVM added 20 commits October 7, 2025 09:32
…d of find() to force matching from start of string
…rt time to dpl context used by relative timestamps
…mes and add equals + hashcode + contract tests where missing
…rserConfig, update tests to set query start time before earliest
…is no user defined provided + cleanup and fixes from review
…e assertions to DPLTimeFormatString and to DPLFormat implementing classes.
…use system default timezone, add zone id to Relative_time UDF
… now. update time stamps tests to use UTC and set query start time
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Better define the responsibilities of time handling objects InstantTimestampTest test depends on system timezone

3 participants