-
Notifications
You must be signed in to change notification settings - Fork 29k
[SPARK-26424][SQL] Use java.time API in date/timestamp expressions #23358
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
5ea78cd
162252f
fd6f7cc
0089351
5150615
29e94b4
964780f
9cd8f33
5d52c0e
f444f57
6d90b30
30d9226
e4baad6
c3fe2a7
7212132
5bea17e
e98532e
2851ede
e335cb6
2ac29d5
6bc9f54
fb21d93
d9d3616
d425570
0e1afc3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -17,27 +17,36 @@ | |
|
|
||
| package org.apache.spark.sql.catalyst.util | ||
|
|
||
| import java.time.{Instant, LocalDateTime, ZonedDateTime, ZoneId} | ||
| import java.time.format.{DateTimeFormatter, DateTimeFormatterBuilder} | ||
| import java.time.temporal.{ChronoField, TemporalAccessor} | ||
| import java.time._ | ||
| import java.time.chrono.IsoChronology | ||
| import java.time.format.{DateTimeFormatter, DateTimeFormatterBuilder, ResolverStyle} | ||
| import java.time.temporal.{ChronoField, TemporalAccessor, TemporalQueries} | ||
| import java.util.Locale | ||
|
|
||
| trait DateTimeFormatterHelper { | ||
|
|
||
| protected def buildFormatter(pattern: String, locale: Locale): DateTimeFormatter = { | ||
| new DateTimeFormatterBuilder() | ||
| .parseCaseInsensitive() | ||
| .appendPattern(pattern) | ||
| .parseDefaulting(ChronoField.YEAR_OF_ERA, 1970) | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Year must always present in timestamps/dates. Probability of an user is satisfied to default value |
||
| .parseDefaulting(ChronoField.ERA, 1) | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Era is required in
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think so. This is our current era: https://docs.oracle.com/javase/8/docs/api/java/time/temporal/ChronoField.html#ERA : "The value of the era that was active on 1970-01-01 (ISO) must be assigned the value 1." |
||
| .parseDefaulting(ChronoField.MONTH_OF_YEAR, 1) | ||
| .parseDefaulting(ChronoField.DAY_OF_MONTH, 1) | ||
| .parseDefaulting(ChronoField.HOUR_OF_DAY, 0) | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hours must always present in the time part. The default value causes conflict if the timestamp pattern has |
||
| .parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0) | ||
| .parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0) | ||
| .toFormatter(locale) | ||
| .withChronology(IsoChronology.INSTANCE) | ||
| .withResolverStyle(ResolverStyle.STRICT) | ||
MaxGekk marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| protected def toInstantWithZoneId(temporalAccessor: TemporalAccessor, zoneId: ZoneId): Instant = { | ||
| val localDateTime = LocalDateTime.from(temporalAccessor) | ||
| val localTime = if (temporalAccessor.query(TemporalQueries.localTime) == null) { | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If parsed timestamp does not have the time part at all, set all (hours, minutes, seconds and etc.) to zeros. |
||
| LocalTime.ofNanoOfDay(0) | ||
| } else { | ||
| LocalTime.from(temporalAccessor) | ||
| } | ||
| val localDate = LocalDate.from(temporalAccessor) | ||
| val localDateTime = LocalDateTime.of(localDate, localTime) | ||
| val zonedDateTime = ZonedDateTime.of(localDateTime, zoneId) | ||
| Instant.from(zonedDateTime) | ||
| } | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.