Skip to content

Commit 7c00fc5

Browse files
committed
set the expected timezone for InstantTimestampTest class before running test methods
add timezone member field for DPLTimeFormat, DefaultTimeFormat, InstantTimestamp. set InstantTimestampTest timezone to gmt+2 remove enforced timezone and set timezone in test constructors, update test results to expect GMT+2 add atZone method for InstantTimestamp and separate string to instant logic to a new class InstantFromString clean up InstantTimestampTest, replace missing 'z' from testEmptyFallsToDefaultTimeformat value add javadoc to DefaultTimeFormat parseDate method to explain varying results that depend on possible zone information contained in input string refactor absolute timestamps logic and replace legacy java time handling objects revert CatalystVisitorTest, change done in another PR fix unwanted change to CatalystVisitorTest from rebasing apply spotless support zone information from value for dates, add AbsoluteTimestampTest use AbsoluteTimestamp class when trying default formats Refactoring of relative timestamps objects WIP working refactor of relational timestamps code cleanup and remove unused old objects
1 parent 7c78cf3 commit 7c00fc5

36 files changed

Lines changed: 2746 additions & 1198 deletions

src/main/java/com/teragrep/pth10/ast/DPLParserConfig.java

Lines changed: 3 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,10 @@
4545
*/
4646
package com.teragrep.pth10.ast;
4747

48-
import com.teragrep.pth10.ast.time.RelativeTimeParser;
49-
import com.teragrep.pth10.ast.time.RelativeTimestamp;
48+
import com.teragrep.pth10.ast.time.DPLTimestampImpl;
5049
import org.slf4j.Logger;
5150
import org.slf4j.LoggerFactory;
5251

53-
import java.sql.Timestamp;
5452
import java.util.LinkedHashMap;
5553
import java.util.Map;
5654

@@ -104,20 +102,7 @@ public String getEarliest() {
104102
* @param earliest string value like -1h or actual timestamp
105103
*/
106104
public void setEarliest(String earliest) {
107-
long earliestEpoch = 0;
108-
Timestamp now = new Timestamp(System.currentTimeMillis());
109-
RelativeTimeParser rtParser = new RelativeTimeParser();
110-
111-
// Try to check if it is relative and catch exception
112-
try {
113-
RelativeTimestamp rtTimestamp = rtParser.parse(earliest); // can throw error if not relative timestamp
114-
earliestEpoch = rtTimestamp.calculate(now).getEpochSecond();
115-
}
116-
catch (NumberFormatException ne) {
117-
// absolute time
118-
earliestEpoch = new DefaultTimeFormat().getEpoch(earliest);
119-
}
120-
105+
final long earliestEpoch = new DPLTimestampImpl(earliest).zonedDateTime().toEpochSecond();
121106
config.put("earliest", earliest);
122107
config.put("earliestEpoch", earliestEpoch);
123108
}
@@ -138,20 +123,7 @@ public String getLatest() {
138123
* @param latest string value like -1h or actual timestamp
139124
*/
140125
public void setLatest(String latest) {
141-
long latestEpoch = 0;
142-
Timestamp now = new Timestamp(System.currentTimeMillis());
143-
RelativeTimeParser rtParser = new RelativeTimeParser();
144-
145-
// Try to check if it is relative and catch exception
146-
try {
147-
RelativeTimestamp rtTimestamp = rtParser.parse(latest); // can throw exception if not relative timestamp
148-
latestEpoch = rtTimestamp.calculate(now).getEpochSecond();
149-
}
150-
catch (NumberFormatException ne) {
151-
// absolute time
152-
latestEpoch = new DefaultTimeFormat().getEpoch(latest);
153-
}
154-
126+
final long latestEpoch = new DPLTimestampImpl(latest).zonedDateTime().toEpochSecond();
155127
config.put("latest", latest);
156128
config.put("latestEpoch", latestEpoch);
157129
}

src/main/java/com/teragrep/pth10/ast/DPLTimeFormat.java

Lines changed: 18 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -46,28 +46,35 @@
4646
package com.teragrep.pth10.ast;
4747

4848
import java.text.ParseException;
49-
import java.text.SimpleDateFormat;
5049
import java.time.Instant;
50+
import java.time.ZonedDateTime;
51+
import java.time.format.DateTimeFormatter;
52+
import java.util.TimeZone;
5153

5254
/**
5355
* For using the DPL custom timeformat like Java's SimpleDateFormat. Get a Date object with parse -function for example.
5456
*/
5557
public final class DPLTimeFormat {
5658

57-
private final String format;
59+
private final DPLTimeFormatText format;
60+
private final TimeZone timeZone;
5861

5962
public DPLTimeFormat(String format) {
63+
this(format, TimeZone.getDefault());
64+
}
65+
66+
public DPLTimeFormat(String format, TimeZone timeZone) {
67+
this(new DPLTimeFormatText(new UnquotedText(new TextString(format))), timeZone);
68+
}
69+
70+
public DPLTimeFormat(DPLTimeFormatText format, TimeZone timeZone) {
6071
this.format = format;
72+
this.timeZone = timeZone;
6173
}
6274

63-
/**
64-
* Create a SimpleDateFormat object from the given DPL specific timeformat. Allows all sorts of parsing and
65-
* tampering with the time.
66-
*
67-
* @return SimpleDateFormat created from the DPLTimeFormat
68-
*/
69-
public SimpleDateFormat createSimpleDateFormat() {
70-
return new SimpleDateFormat(convertDplTimeFormatToJava(this.format));
75+
private DateTimeFormatter dateTimeFormatter() {
76+
String javaFormat = format.read();
77+
return DateTimeFormatter.ofPattern(javaFormat).withZone(timeZone.toZoneId());
7178
}
7279

7380
/**
@@ -80,38 +87,6 @@ public SimpleDateFormat createSimpleDateFormat() {
8087
* @throws ParseException when dplTime doesn't have the correct format
8188
*/
8289
public Instant instantOf(String dplTime) throws ParseException {
83-
return createSimpleDateFormat().parse(dplTime).toInstant();
84-
}
85-
86-
// replace dpl time units with java-compatible time units
87-
private String convertDplTimeFormatToJava(String dplTf) {
88-
dplTf = new UnquotedText(new TextString(dplTf)).read();
89-
return dplTf
90-
// Date
91-
.replaceAll("%F", "y-MM-dd") // ISO 8601 %Y-%m-%d
92-
.replaceAll("%y", "yy") // year without century (00-99)
93-
.replaceAll("%Y", "y") // full year
94-
.replaceAll("%m", "MM") // month 1-12
95-
.replaceAll("%d", "dd") // day 1-31
96-
.replaceAll("%b", "MMM") // abbrv. month name
97-
.replaceAll("%B", "MMMM") // full month name
98-
.replaceAll("%A", "EE") // full weekday name, e.g. "sunday"
99-
.replaceAll("%a", "E") // abbrv. weekday name, e.g. "Sun"
100-
.replaceAll("%j", "D") // day of year, 001-366
101-
.replaceAll("%w", "F") // weekday as decimal 0=sun 6=sat
102-
// Time
103-
.replaceAll("%H", "HH") // hour 0-23
104-
.replaceAll("%k", "H") // hour without leading zeroes
105-
.replaceAll("%M", "mm") // minute 0-59
106-
.replaceAll("%S", "ss") // second 0-59
107-
.replaceAll("%I", "hh") // hour 1-12
108-
.replaceAll("%p", "a") // am/pm
109-
.replaceAll("%T", "HH:mm:ss") // hour:min:sec
110-
.replaceAll("%f", "SSS") // microsecs
111-
// Time zone
112-
.replaceAll("%Z", "zz") // timezone abbreviation
113-
.replaceAll("%z", "X") // timezone offset +00:00
114-
// Other
115-
.replaceAll("%%", "%"); // percent sign
90+
return ZonedDateTime.parse(dplTime, dateTimeFormatter()).toInstant();
11691
}
11792
}
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
/*
2+
* Teragrep Data Processing Language (DPL) translator for Apache Spark (pth_10)
3+
* Copyright (C) 2019-2024 Suomen Kanuuna Oy
4+
*
5+
* This program is free software: you can redistribute it and/or modify
6+
* it under the terms of the GNU Affero General Public License as published by
7+
* the Free Software Foundation, either version 3 of the License, or
8+
* (at your option) any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU Affero General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU Affero General Public License
16+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
17+
*
18+
*
19+
* Additional permission under GNU Affero General Public License version 3
20+
* section 7
21+
*
22+
* If you modify this Program, or any covered work, by linking or combining it
23+
* with other code, such other code is not for that reason alone subject to any
24+
* of the requirements of the GNU Affero GPL version 3 as long as this Program
25+
* is the same Program as licensed from Suomen Kanuuna Oy without any additional
26+
* modifications.
27+
*
28+
* Supplemented terms under GNU Affero General Public License version 3
29+
* section 7
30+
*
31+
* Origin of the software must be attributed to Suomen Kanuuna Oy. Any modified
32+
* versions must be marked as "Modified version of" The Program.
33+
*
34+
* Names of the licensors and authors may not be used for publicity purposes.
35+
*
36+
* No rights are granted for use of trade names, trademarks, or service marks
37+
* which are in The Program if any.
38+
*
39+
* Licensee must indemnify licensors and authors for any liability that these
40+
* contractual assumptions impose on licensors and authors.
41+
*
42+
* To the extent this program is licensed as part of the Commercial versions of
43+
* Teragrep, the applicable Commercial License may apply to this file if you as
44+
* a licensee so wish it.
45+
*/
46+
package com.teragrep.pth10.ast;
47+
48+
/** replaces dpl time units with java-compatible time units */
49+
public class DPLTimeFormatText implements Text {
50+
51+
private final Text origin;
52+
53+
public DPLTimeFormatText(final Text origin) {
54+
this.origin = origin;
55+
}
56+
57+
@Override
58+
public String read() {
59+
String read = origin.read();
60+
if ("%s".equals(read)) {
61+
return read;
62+
}
63+
return read
64+
.replaceAll("%F", "yyyy-MM-dd") // ISO 8601 %Y-%m-%d
65+
.replaceAll("%y", "yy") // year without century (00-99)
66+
.replaceAll("%Y", "yyyy") // full year
67+
.replaceAll("%m", "MM") // month 1-12
68+
.replaceAll("%d", "dd") // day 1-31
69+
.replaceAll("%b", "MMM") // abbrv. month name
70+
.replaceAll("%B", "MMMM") // full month name
71+
.replaceAll("%A", "EEEE") // full weekday name, e.g. "sunday"
72+
.replaceAll("%a", "E") // abbrv. weekday name, e.g. "Sun"
73+
.replaceAll("%j", "D") // day of year, 001-366
74+
.replaceAll("%w", "e") // weekday as decimal 0=sun 6=sat
75+
// Time
76+
.replaceAll("%H", "HH") // hour 0-23
77+
.replaceAll("%k", "H") // hour without leading zeroes
78+
.replaceAll("%M", "mm") // minute 0-59
79+
.replaceAll("%S", "ss") // second 0-59
80+
.replaceAll("%I", "hh") // hour 1-12
81+
.replaceAll("%p", "a") // am/pm
82+
.replaceAll("%T", "HH:mm:ss") // hour:min:sec
83+
.replaceAll("%f", "SSS") // microsecs
84+
// Time zone
85+
.replaceAll("%Z", "zzz") // timezone abbreviation
86+
.replaceAll("%z", "XXX") // timezone offset +00:00
87+
// Other
88+
.replaceAll("%%", "%") // percent sign
89+
// remove unsupported
90+
.replaceAll("%c", "")
91+
.replaceAll("%x", "");
92+
}
93+
}

src/main/java/com/teragrep/pth10/ast/commands/evalstatement/UDFs/Mvrange.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,13 @@
4545
*/
4646
package com.teragrep.pth10.ast.commands.evalstatement.UDFs;
4747

48-
import com.teragrep.pth10.ast.time.RelativeTimeParser;
4948
import com.teragrep.pth10.ast.time.RelativeTimestamp;
5049
import org.apache.spark.sql.api.java.UDF3;
5150

5251
import java.io.Serializable;
53-
import java.sql.Timestamp;
52+
import java.time.Instant;
53+
import java.time.ZoneId;
54+
import java.time.ZonedDateTime;
5455
import java.util.ArrayList;
5556
import java.util.List;
5657

@@ -102,11 +103,11 @@ else if (stepObj instanceof String) {
102103
long time = start;
103104
rv.add(String.valueOf(time));
104105

105-
RelativeTimeParser rtParser = new RelativeTimeParser();
106-
RelativeTimestamp rtTimestamp = rtParser.parse("+" + stepStr);
107106
// Go until incremented past end
108107
while (time < end) {
109-
time = rtTimestamp.calculate(new Timestamp(time * 1000L)).getEpochSecond();
108+
final ZonedDateTime startTime = ZonedDateTime.ofInstant(Instant.ofEpochSecond(time), ZoneId.of("UTC"));
109+
final RelativeTimestamp relativeTimestamp = new RelativeTimestamp("+" + stepStr, startTime);
110+
time = relativeTimestamp.zonedDateTime().toEpochSecond();
110111

111112
// If time went past end, stop incrementing and don't add to mv field
112113
if (time > end) {

src/main/java/com/teragrep/pth10/ast/commands/evalstatement/UDFs/Relative_time.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,13 @@
4545
*/
4646
package com.teragrep.pth10.ast.commands.evalstatement.UDFs;
4747

48-
import com.teragrep.pth10.ast.time.RelativeTimeParser;
4948
import com.teragrep.pth10.ast.time.RelativeTimestamp;
5049
import org.apache.spark.sql.api.java.UDF2;
5150

5251
import java.io.Serializable;
53-
import java.sql.Timestamp;
52+
import java.time.Instant;
53+
import java.time.ZoneId;
54+
import java.time.ZonedDateTime;
5455

5556
/**
5657
* UDF for command relative_time(unixtime, modifier)<br>
@@ -63,9 +64,10 @@ public class Relative_time implements UDF2<Long, String, Long>, Serializable {
6364

6465
@Override
6566
public Long call(Long unixtime, String modifier) throws Exception {
66-
RelativeTimeParser rtParser = new RelativeTimeParser();
67-
RelativeTimestamp rtTimestamp = rtParser.parse(modifier);
68-
return rtTimestamp.calculate(new Timestamp(unixtime * 1000L)).getEpochSecond();
67+
final ZonedDateTime startTime = ZonedDateTime
68+
.ofInstant(Instant.ofEpochSecond(unixtime), ZoneId.systemDefault());
69+
final RelativeTimestamp relativeTimestamp = new RelativeTimestamp(modifier, startTime);
70+
return relativeTimestamp.zonedDateTime().toEpochSecond();
6971
}
7072

7173
}

src/main/java/com/teragrep/pth10/ast/commands/transformstatement/convert/Ctime.java

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,15 @@
4545
*/
4646
package com.teragrep.pth10.ast.commands.transformstatement.convert;
4747

48-
import com.teragrep.pth10.ast.DPLTimeFormat;
48+
import com.teragrep.pth10.ast.DPLTimeFormatText;
49+
import com.teragrep.pth10.ast.TextString;
50+
import com.teragrep.pth10.ast.UnquotedText;
4951
import org.apache.spark.sql.api.java.UDF2;
5052

51-
import java.text.DateFormat;
52-
import java.util.Date;
53-
import java.util.TimeZone;
53+
import java.time.Instant;
54+
import java.time.ZoneId;
55+
import java.time.ZonedDateTime;
56+
import java.time.format.DateTimeFormatter;
5457

5558
/**
5659
* UDF for convert command 'ctime'<br>
@@ -63,15 +66,14 @@ public class Ctime implements UDF2<String, String, String> {
6366
private static final long serialVersionUID = 1L;
6467

6568
@Override
66-
public String call(String epoch, String tf) throws Exception {
67-
Long e = Long.valueOf(epoch);
68-
69-
Date date = new Date(e * 1000L);
70-
DateFormat format = new DPLTimeFormat(tf).createSimpleDateFormat();
71-
format.setTimeZone(TimeZone.getTimeZone("Etc/UTC"));
72-
String formatted = format.format(date);
73-
74-
return formatted;
69+
public String call(String epoch, String timeformat) throws Exception {
70+
final ZoneId utcZoneId = ZoneId.of("UTC");
71+
final long seconds = Long.parseLong(epoch);
72+
final Instant instant = Instant.ofEpochSecond(seconds);
73+
final ZonedDateTime zonedDateTime = instant.atZone(utcZoneId);
74+
final String dplTimeFormatString = new DPLTimeFormatText(new UnquotedText(new TextString(timeformat))).read();
75+
final DateTimeFormatter formatter = DateTimeFormatter.ofPattern(dplTimeFormatString).withZone(utcZoneId);
76+
return formatter.format(zonedDateTime);
7577
}
7678

7779
}

src/main/java/com/teragrep/pth10/ast/commands/transformstatement/convert/Mktime.java

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
*/
4646
package com.teragrep.pth10.ast.commands.transformstatement.convert;
4747

48-
import com.teragrep.pth10.ast.DPLTimeFormat;
48+
import com.teragrep.pth10.ast.time.DPLTimestampImpl;
4949
import org.apache.spark.sql.api.java.UDF2;
5050

5151
/**
@@ -60,10 +60,8 @@ public class Mktime implements UDF2<String, String, String> {
6060

6161
@Override
6262
public String call(String hrt, String tf) throws Exception {
63-
DPLTimeFormat format = new DPLTimeFormat(tf);
64-
Long rv = format.instantOf(hrt).getEpochSecond();
65-
66-
return rv.toString();
63+
final DPLTimestampImpl timestamp = new DPLTimestampImpl(hrt, tf);
64+
return Long.toString(timestamp.zonedDateTime().toEpochSecond());
6765
}
6866

6967
}

0 commit comments

Comments
 (0)