diff --git a/core/src/test/java/org/opensearch/sql/expression/datetime/DateTimeFunctionTest.java b/core/src/test/java/org/opensearch/sql/expression/datetime/DateTimeFunctionTest.java index c820c97196..ad15dadfb7 100644 --- a/core/src/test/java/org/opensearch/sql/expression/datetime/DateTimeFunctionTest.java +++ b/core/src/test/java/org/opensearch/sql/expression/datetime/DateTimeFunctionTest.java @@ -5,7 +5,8 @@ package org.opensearch.sql.expression.datetime; -import static java.time.temporal.ChronoField.ALIGNED_WEEK_OF_YEAR; +import static java.time.DayOfWeek.SUNDAY; +import static java.time.temporal.TemporalAdjusters.nextOrSame; import static org.junit.jupiter.api.Assertions.assertAll; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -24,6 +25,7 @@ import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; +import java.time.temporal.ChronoUnit; import java.util.List; import java.util.stream.Stream; import lombok.AllArgsConstructor; @@ -1228,30 +1230,34 @@ public void testWeekFormats( expectedInteger); } - // subtracting 1 as a temporary fix for year 2024. - // Issue: https://github.com/opensearch-project/sql/issues/2477 @Test public void testWeekOfYearWithTimeType() { + LocalDate today = LocalDate.now(functionProperties.getQueryStartClock()); + + // week is based on the first sunday of the year + LocalDate firstSundayOfYear = today.withDayOfYear(1).with(nextOrSame(SUNDAY)); + int week = + today.isBefore(firstSundayOfYear) + ? 0 + : (int) ChronoUnit.WEEKS.between(firstSundayOfYear, today) + 1; + assertAll( () -> validateStringFormat( DSL.week( functionProperties, DSL.literal(new ExprTimeValue("12:23:34")), DSL.literal(0)), "week(TIME '12:23:34', 0)", - LocalDate.now(functionProperties.getQueryStartClock()).get(ALIGNED_WEEK_OF_YEAR) - - 1), + week), () -> validateStringFormat( DSL.week_of_year(functionProperties, DSL.literal(new ExprTimeValue("12:23:34"))), "week_of_year(TIME '12:23:34')", - LocalDate.now(functionProperties.getQueryStartClock()).get(ALIGNED_WEEK_OF_YEAR) - - 1), + week), () -> validateStringFormat( DSL.weekofyear(functionProperties, DSL.literal(new ExprTimeValue("12:23:34"))), "weekofyear(TIME '12:23:34')", - LocalDate.now(functionProperties.getQueryStartClock()).get(ALIGNED_WEEK_OF_YEAR) - - 1)); + week)); } @Test diff --git a/core/src/test/java/org/opensearch/sql/expression/datetime/YearweekTest.java b/core/src/test/java/org/opensearch/sql/expression/datetime/YearweekTest.java index 47225ac601..d944f7c85c 100644 --- a/core/src/test/java/org/opensearch/sql/expression/datetime/YearweekTest.java +++ b/core/src/test/java/org/opensearch/sql/expression/datetime/YearweekTest.java @@ -5,7 +5,8 @@ package org.opensearch.sql.expression.datetime; -import static java.time.temporal.ChronoField.ALIGNED_WEEK_OF_YEAR; +import static java.time.DayOfWeek.SUNDAY; +import static java.time.temporal.TemporalAdjusters.nextOrSame; import static org.junit.jupiter.api.Assertions.assertAll; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -13,6 +14,7 @@ import static org.opensearch.sql.data.type.ExprCoreType.INTEGER; import java.time.LocalDate; +import java.time.temporal.ChronoUnit; import java.util.stream.Stream; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; @@ -97,13 +99,9 @@ public void testYearweekWithoutMode() { assertEquals(eval(expression), eval(expressionWithoutMode)); } - // subtracting 1 as a temporary fix for year 2024. - // Issue: https://github.com/opensearch-project/sql/issues/2477 @Test public void testYearweekWithTimeType() { - int week = LocalDate.now(functionProperties.getQueryStartClock()).get(ALIGNED_WEEK_OF_YEAR) - 1; - int year = LocalDate.now(functionProperties.getQueryStartClock()).getYear(); - int expected = Integer.parseInt(String.format("%d%02d", year, week)); + int expected = getYearWeekBeforeSunday(LocalDate.now(functionProperties.getQueryStartClock())); FunctionExpression expression = DSL.yearweek( @@ -112,9 +110,27 @@ public void testYearweekWithTimeType() { FunctionExpression expressionWithoutMode = DSL.yearweek(functionProperties, DSL.literal(new ExprTimeValue("10:11:12"))); - assertAll( - () -> assertEquals(expected, eval(expression).integerValue()), - () -> assertEquals(expected, eval(expressionWithoutMode).integerValue())); + assertEquals( + expected, + eval(expression).integerValue(), + String.format( + "Expected year week: %d, got %s (test with mode)", expected, eval(expression))); + assertEquals( + expected, + eval(expressionWithoutMode).integerValue(), + String.format( + "Expected year week: %d, got %s (test without mode)", expected, eval(expression))); + } + + private int getYearWeekBeforeSunday(LocalDate date) { + LocalDate firstSundayOfYear = date.withDayOfYear(1).with(nextOrSame(SUNDAY)); + if (date.isBefore(firstSundayOfYear)) { + return getYearWeekBeforeSunday(date.minusDays(1)); + } + + int week = (int) ChronoUnit.WEEKS.between(firstSundayOfYear, date) + 1; + int year = date.getYear(); + return Integer.parseInt(String.format("%d%02d", year, week)); } @Test diff --git a/docs/user/ppl/functions/datetime.rst b/docs/user/ppl/functions/datetime.rst index c0d42297ac..9af02f3bde 100644 --- a/docs/user/ppl/functions/datetime.rst +++ b/docs/user/ppl/functions/datetime.rst @@ -2169,7 +2169,7 @@ YEARWEEK Description >>>>>>>>>>> -Usage: yearweek(date) returns the year and week for date as an integer. It accepts and optional mode arguments aligned with those available for the `WEEK`_ function. +Usage: yearweek(date[, mode]) returns the year and week for date as an integer. It accepts and optional mode arguments aligned with those available for the `WEEK`_ function. Argument type: STRING/DATE/TIME/TIMESTAMP @@ -2185,4 +2185,3 @@ Example:: | 202034 | 201901 | +------------------------+---------------------------+ -