5
5
6
6
package org .opensearch .sql .expression .datetime ;
7
7
8
- import static java .time .temporal .ChronoField .ALIGNED_WEEK_OF_YEAR ;
9
8
import static org .junit .jupiter .api .Assertions .assertEquals ;
10
9
import static org .opensearch .sql .data .type .ExprCoreType .LONG ;
11
10
11
+ import java .time .Instant ;
12
12
import java .time .LocalDate ;
13
+ import java .time .LocalDateTime ;
14
+ import java .time .LocalTime ;
15
+ import java .time .ZoneId ;
16
+ import java .time .temporal .IsoFields ;
13
17
import java .util .stream .Stream ;
14
18
import org .junit .jupiter .api .Test ;
15
19
import org .junit .jupiter .params .ParameterizedTest ;
16
20
import org .junit .jupiter .params .provider .Arguments ;
17
21
import org .junit .jupiter .params .provider .MethodSource ;
22
+ import org .junit .jupiter .params .provider .ValueSource ;
18
23
import org .opensearch .sql .data .model .ExprDateValue ;
19
24
import org .opensearch .sql .data .model .ExprTimeValue ;
20
25
import org .opensearch .sql .data .model .ExprTimestampValue ;
23
28
import org .opensearch .sql .expression .Expression ;
24
29
import org .opensearch .sql .expression .ExpressionTestBase ;
25
30
import org .opensearch .sql .expression .FunctionExpression ;
31
+ import org .opensearch .sql .expression .function .FunctionProperties ;
26
32
27
33
class ExtractTest extends ExpressionTestBase {
28
34
@@ -82,9 +88,14 @@ public void testExtractWithDatetime(String part, long expected) {
82
88
}
83
89
84
90
private void datePartWithTimeArgQuery (String part , String time , long expected ) {
91
+ datePartWithTimeArgQuery (functionProperties , part , time , expected );
92
+ }
93
+
94
+ private void datePartWithTimeArgQuery (
95
+ FunctionProperties properties , String part , String time , long expected ) {
85
96
ExprTimeValue timeValue = new ExprTimeValue (time );
86
97
FunctionExpression datetimeExpression =
87
- DSL .extract (functionProperties , DSL .literal (part ), DSL .literal (timeValue ));
98
+ DSL .extract (properties , DSL .literal (part ), DSL .literal (timeValue ));
88
99
89
100
assertEquals (LONG , datetimeExpression .type ());
90
101
assertEquals (expected , eval (datetimeExpression ).longValue ());
@@ -96,21 +107,49 @@ public void testExtractDatePartWithTimeType() {
96
107
97
108
datePartWithTimeArgQuery ("DAY" , timeInput , now .getDayOfMonth ());
98
109
99
- // To avoid flaky test, skip the testing in December and January because the WEEK is ISO 8601
100
- // week-of-week-based-year which is considered to start on a Monday and week 1 is the first week
101
- // with >3 days. it is possible for early-January dates to be part of the 52nd or 53rd week of
102
- // the previous year, and for late-December dates to be part of the first week of the next year.
103
- // For example, 2005-01-02 is part of the 53rd week of year 2004, while 2012-12-31 is part of
104
- // the first week of 2013
105
- if (now .getMonthValue () != 1 && now .getMonthValue () != 12 ) {
106
- datePartWithTimeArgQuery ("WEEK" , datetimeInput , now .get (ALIGNED_WEEK_OF_YEAR ));
107
- }
108
-
109
110
datePartWithTimeArgQuery ("MONTH" , timeInput , now .getMonthValue ());
110
111
111
112
datePartWithTimeArgQuery ("YEAR" , timeInput , now .getYear ());
112
113
}
113
114
115
+ @ ParameterizedTest (name = "{0}" )
116
+ @ ValueSource (
117
+ strings = {
118
+ "2009-12-26" ,
119
+ "2009-12-27" ,
120
+ "2008-12-28" , // Week 52 of week-based-year 2008
121
+ "2009-12-29" ,
122
+ "2008-12-29" , // Week 1 of week-based-year 2009
123
+ "2008-12-31" , // Week 1 of week-based-year 2009
124
+ "2009-01-01" , // Week 1 of week-based-year 2009
125
+ "2009-01-04" , // Week 1 of week-based-year 2009
126
+ "2009-01-05" , // Week 2 of week-based-year 2009
127
+ "2025-12-27" , // year with 52 weeks
128
+ "2026-01-01" , // year starts on a THURSDAY
129
+ "2028-12-30" , // year with 53 weeks
130
+ "2028-12-31" , // year starts in December
131
+ "2029-01-01" ,
132
+ "2033-12-31" , // year with 53 weeks
133
+ "2034-01-01" , // January 1st on a SUNDAY
134
+ "2034-12-30" , // year with 52 weeks
135
+ "2034-12-31"
136
+ })
137
+ public void testExtractWeekPartWithTimeType (String arg ) {
138
+
139
+ // setup default date/time properties for the extract function
140
+ ZoneId currentZoneId = ZoneId .systemDefault ();
141
+ Instant nowInstant =
142
+ LocalDate .parse (arg ).atTime (LocalTime .parse (timeInput )).atZone (currentZoneId ).toInstant ();
143
+ FunctionProperties properties = new FunctionProperties (nowInstant , currentZoneId );
144
+
145
+ // Expected WEEK value should be formated from week-of-week-based-year
146
+ LocalDateTime localDateTime = LocalDateTime .ofInstant (nowInstant , currentZoneId );
147
+ int expected = localDateTime .get (IsoFields .WEEK_OF_WEEK_BASED_YEAR );
148
+
149
+ // verify
150
+ datePartWithTimeArgQuery (properties , "WEEK" , timeInput , expected );
151
+ }
152
+
114
153
@ ParameterizedTest (name = "{0}" )
115
154
@ MethodSource ("getDateResultsForExtractFunction" )
116
155
public void testExtractWithDate (String part , long expected ) {
0 commit comments