1717
1818package org .apache .spark .sql .util
1919
20- import java .time .{DateTimeException , LocalDate }
20+ import java .time .{DateTimeException , LocalDate , ZoneId }
21+ import java .util .{Calendar , TimeZone }
2122
2223import org .apache .spark .{SparkFunSuite , SparkUpgradeException }
2324import org .apache .spark .sql .catalyst .plans .SQLHelper
@@ -28,26 +29,35 @@ import org.apache.spark.sql.internal.SQLConf
2829import org .apache .spark .sql .internal .SQLConf .LegacyBehaviorPolicy
2930
3031class DateFormatterSuite extends SparkFunSuite with SQLHelper {
31- test(" parsing dates" ) {
32- outstandingTimezonesIds.foreach { timeZone =>
33- withSQLConf(SQLConf .SESSION_LOCAL_TIMEZONE .key -> timeZone) {
34- val formatter = DateFormatter (getZoneId(timeZone))
35- val daysSinceEpoch = formatter.parse(" 2018-12-02" )
36- assert(daysSinceEpoch === 17867 )
32+ private def withOutstandingZoneIds (f : ZoneId => Unit ): Unit = {
33+ for {
34+ jvmZoneId <- outstandingZoneIds
35+ sessionZoneId <- outstandingZoneIds
36+ } {
37+ withDefaultTimeZone(jvmZoneId) {
38+ withSQLConf(SQLConf .SESSION_LOCAL_TIMEZONE .key -> sessionZoneId.getId) {
39+ f(sessionZoneId)
40+ }
3741 }
3842 }
3943 }
4044
45+ test(" parsing dates" ) {
46+ withOutstandingZoneIds { zoneId =>
47+ val formatter = DateFormatter (zoneId)
48+ val daysSinceEpoch = formatter.parse(" 2018-12-02" )
49+ assert(daysSinceEpoch === 17867 )
50+ }
51+ }
52+
4153 test(" format dates" ) {
42- outstandingTimezonesIds.foreach { timeZone =>
43- withSQLConf(SQLConf .SESSION_LOCAL_TIMEZONE .key -> timeZone) {
44- val formatter = DateFormatter (getZoneId(timeZone))
45- val (days, expected) = (17867 , " 2018-12-02" )
46- val date = formatter.format(days)
47- assert(date === expected)
48- assert(formatter.format(daysToLocalDate(days)) === expected)
49- assert(formatter.format(toJavaDate(days)) === expected)
50- }
54+ withOutstandingZoneIds { zoneId =>
55+ val formatter = DateFormatter (zoneId)
56+ val (days, expected) = (17867 , " 2018-12-02" )
57+ val date = formatter.format(days)
58+ assert(date === expected)
59+ assert(formatter.format(daysToLocalDate(days)) === expected)
60+ assert(formatter.format(toJavaDate(days, TimeZone .getTimeZone(zoneId))) === expected)
5161 }
5262 }
5363
@@ -66,18 +76,16 @@ class DateFormatterSuite extends SparkFunSuite with SQLHelper {
6676 " 2018-12-12" ,
6777 " 2038-01-01" ,
6878 " 5010-11-17" ).foreach { date =>
69- outstandingTimezonesIds.foreach { timeZone =>
70- withSQLConf(SQLConf .SESSION_LOCAL_TIMEZONE .key -> timeZone) {
71- val formatter = DateFormatter (
72- DateFormatter .defaultPattern,
73- getZoneId(timeZone),
74- DateFormatter .defaultLocale,
75- legacyFormat)
76- val days = formatter.parse(date)
77- assert(date === formatter.format(days))
78- assert(date === formatter.format(daysToLocalDate(days)))
79- assert(date === formatter.format(toJavaDate(days)))
80- }
79+ withOutstandingZoneIds { zoneId =>
80+ val formatter = DateFormatter (
81+ DateFormatter .defaultPattern,
82+ zoneId,
83+ DateFormatter .defaultLocale,
84+ legacyFormat)
85+ val days = formatter.parse(date)
86+ assert(date === formatter.format(days))
87+ assert(date === formatter.format(daysToLocalDate(days)))
88+ assert(date === formatter.format(toJavaDate(days, TimeZone .getTimeZone(zoneId))))
8189 }
8290 }
8391 }
@@ -100,17 +108,15 @@ class DateFormatterSuite extends SparkFunSuite with SQLHelper {
100108 17877 ,
101109 24837 ,
102110 1110657 ).foreach { days =>
103- outstandingTimezonesIds.foreach { timeZone =>
104- withSQLConf(SQLConf .SESSION_LOCAL_TIMEZONE .key -> timeZone) {
105- val formatter = DateFormatter (
106- DateFormatter .defaultPattern,
107- getZoneId(timeZone),
108- DateFormatter .defaultLocale,
109- legacyFormat)
110- val date = formatter.format(days)
111- val parsed = formatter.parse(date)
112- assert(days === parsed)
113- }
111+ withOutstandingZoneIds { zoneId =>
112+ val formatter = DateFormatter (
113+ DateFormatter .defaultPattern,
114+ zoneId,
115+ DateFormatter .defaultLocale,
116+ legacyFormat)
117+ val date = formatter.format(days)
118+ val parsed = formatter.parse(date)
119+ assert(days === parsed)
114120 }
115121 }
116122 }
@@ -167,18 +173,21 @@ class DateFormatterSuite extends SparkFunSuite with SQLHelper {
167173 test(" SPARK-31557: rebasing in legacy formatters/parsers" ) {
168174 withSQLConf(SQLConf .LEGACY_TIME_PARSER_POLICY .key -> LegacyBehaviorPolicy .LEGACY .toString) {
169175 LegacyDateFormats .values.foreach { legacyFormat =>
170- outstandingTimezonesIds.foreach { timeZone =>
171- withSQLConf(SQLConf .SESSION_LOCAL_TIMEZONE .key -> timeZone) {
172- val formatter = DateFormatter (
173- DateFormatter .defaultPattern,
174- getZoneId(timeZone),
175- DateFormatter .defaultLocale,
176- legacyFormat)
177- assert(LocalDate .ofEpochDay(formatter.parse(" 1000-01-01" )) === LocalDate .of(1000 , 1 , 1 ))
178- assert(formatter.format(LocalDate .of(1000 , 1 , 1 )) === " 1000-01-01" )
179- assert(formatter.format(localDateToDays(LocalDate .of(1000 , 1 , 1 ))) === " 1000-01-01" )
180- assert(formatter.format(java.sql.Date .valueOf(" 1000-01-01" )) === " 1000-01-01" )
181- }
176+ withOutstandingZoneIds { zoneId =>
177+ val formatter = DateFormatter (
178+ DateFormatter .defaultPattern,
179+ zoneId,
180+ DateFormatter .defaultLocale,
181+ legacyFormat)
182+ assert(LocalDate .ofEpochDay(formatter.parse(" 1000-01-01" )) === LocalDate .of(1000 , 1 , 1 ))
183+ assert(formatter.format(LocalDate .of(1000 , 1 , 1 )) === " 1000-01-01" )
184+ assert(formatter.format(localDateToDays(LocalDate .of(1000 , 1 , 1 ))) === " 1000-01-01" )
185+ val cal = new Calendar .Builder ()
186+ .setCalendarType(" gregory" )
187+ .setTimeZone(TimeZone .getTimeZone(zoneId))
188+ .setDate(1000 , 0 , 1 )
189+ .build()
190+ assert(formatter.format(cal.getTime) === " 1000-01-01" )
182191 }
183192 }
184193 }
0 commit comments