|
1 | 1 | package org.duckdb;
|
2 | 2 |
|
3 | 3 | import java.sql.Date;
|
| 4 | +import java.sql.SQLException; |
4 | 5 | import java.sql.Time;
|
5 | 6 | import java.sql.Timestamp;
|
6 |
| -import java.time.Instant; |
7 |
| -import java.time.LocalDate; |
8 |
| -import java.time.LocalDateTime; |
9 |
| -import java.time.LocalTime; |
10 |
| -import java.time.OffsetDateTime; |
11 |
| -import java.time.OffsetTime; |
12 |
| -import java.time.ZoneOffset; |
| 7 | +import java.time.*; |
13 | 8 | import java.time.temporal.ChronoUnit;
|
14 | 9 |
|
15 | 10 | public class DuckDBTimestamp {
|
@@ -38,18 +33,47 @@ public DuckDBTimestamp(Timestamp sqlTimestamp) {
|
38 | 33 | final static LocalDateTime RefLocalDateTime;
|
39 | 34 | protected long timeMicros;
|
40 | 35 |
|
41 |
| - public static Timestamp toSqlTimestamp(long timeMicros) { |
42 |
| - return Timestamp.valueOf( |
43 |
| - LocalDateTime.ofEpochSecond(micros2seconds(timeMicros), nanosPartMicros(timeMicros), ZoneOffset.UTC)); |
| 36 | + private static Instant createInstant(long value, ChronoUnit unit) throws SQLException { |
| 37 | + switch (unit) { |
| 38 | + case SECONDS: |
| 39 | + return Instant.ofEpochSecond(value); |
| 40 | + case MILLIS: |
| 41 | + return Instant.ofEpochMilli(value); |
| 42 | + case MICROS: { |
| 43 | + long epochSecond = value / 1_000_000; |
| 44 | + int nanoAdjustment = nanosPartMicros(value); |
| 45 | + return Instant.ofEpochSecond(epochSecond, nanoAdjustment); |
| 46 | + } |
| 47 | + case NANOS: { |
| 48 | + long epochSecond = value / 1_000_000_000; |
| 49 | + long nanoAdjustment = nanosPartNanos(value); |
| 50 | + return Instant.ofEpochSecond(epochSecond, nanoAdjustment); |
| 51 | + } |
| 52 | + default: |
| 53 | + throw new SQLException("Unsupported unit type: [" + unit + "]"); |
| 54 | + } |
44 | 55 | }
|
45 | 56 |
|
46 |
| - public static Timestamp toSqlTimestampNanos(long timeNanos) { |
47 |
| - return Timestamp.valueOf( |
48 |
| - LocalDateTime.ofEpochSecond(nanos2seconds(timeNanos), nanosPartNanos(timeNanos), ZoneOffset.UTC)); |
| 57 | + public static LocalDateTime localDateTimeFromTimestampWithTimezone(long value, ChronoUnit unit, |
| 58 | + ZoneId zoneIdNullable) throws SQLException { |
| 59 | + Instant instant = createInstant(value, unit); |
| 60 | + ZoneId zoneId = zoneIdNullable != null ? zoneIdNullable : ZoneId.systemDefault(); |
| 61 | + return LocalDateTime.ofInstant(instant, zoneId); |
49 | 62 | }
|
50 | 63 |
|
51 |
| - public static LocalDateTime toLocalDateTime(long timeMicros) { |
52 |
| - return LocalDateTime.ofEpochSecond(micros2seconds(timeMicros), nanosPartMicros(timeMicros), ZoneOffset.UTC); |
| 64 | + public static LocalDateTime localDateTimeFromTimestamp(long value, ChronoUnit unit, ZoneId zoneIdNullable) |
| 65 | + throws SQLException { |
| 66 | + Instant instant = createInstant(value, unit); |
| 67 | + LocalDateTime ldt = LocalDateTime.ofInstant(instant, ZoneOffset.UTC); |
| 68 | + if (null == zoneIdNullable) { |
| 69 | + return ldt; |
| 70 | + } |
| 71 | + ZoneId zoneIdDefault = ZoneId.systemDefault(); |
| 72 | + LocalDateTime ldtDefault = LocalDateTime.ofInstant(instant, zoneIdDefault); |
| 73 | + LocalDateTime ldtZoned = LocalDateTime.ofInstant(instant, zoneIdNullable); |
| 74 | + Duration duration = Duration.between(ldtZoned, ldtDefault); |
| 75 | + LocalDateTime ldtAdjusted = ldt.plus(duration); |
| 76 | + return ldtAdjusted; |
53 | 77 | }
|
54 | 78 |
|
55 | 79 | public static OffsetTime toOffsetTime(long timeBits) {
|
@@ -78,26 +102,6 @@ private static LocalTime toLocalTime(long timeMicros) {
|
78 | 102 | return LocalTime.ofNanoOfDay(timeMicros * 1000);
|
79 | 103 | }
|
80 | 104 |
|
81 |
| - public static OffsetDateTime toOffsetDateTime(long timeMicros) { |
82 |
| - return OffsetDateTime.of(toLocalDateTime(timeMicros), ZoneOffset.UTC); |
83 |
| - } |
84 |
| - |
85 |
| - public static Timestamp fromSecondInstant(long seconds) { |
86 |
| - return fromMilliInstant(seconds * 1_000); |
87 |
| - } |
88 |
| - |
89 |
| - public static Timestamp fromMilliInstant(long millis) { |
90 |
| - return new Timestamp(millis); |
91 |
| - } |
92 |
| - |
93 |
| - public static Timestamp fromMicroInstant(long micros) { |
94 |
| - return Timestamp.from(Instant.ofEpochSecond(micros / 1_000_000, nanosPartMicros(micros))); |
95 |
| - } |
96 |
| - |
97 |
| - public static Timestamp fromNanoInstant(long nanos) { |
98 |
| - return Timestamp.from(Instant.ofEpochSecond(nanos / 1_000_000_000, nanosPartNanos(nanos))); |
99 |
| - } |
100 |
| - |
101 | 105 | public static long localDateTime2Micros(LocalDateTime localDateTime) {
|
102 | 106 | return DuckDBTimestamp.RefLocalDateTime.until(localDateTime, ChronoUnit.MICROS);
|
103 | 107 | }
|
@@ -130,7 +134,7 @@ public LocalDateTime toLocalDateTime() {
|
130 | 134 | }
|
131 | 135 |
|
132 | 136 | public OffsetDateTime toOffsetDateTime() {
|
133 |
| - return OffsetDateTime.of(toLocalDateTime(this.timeMicros), ZoneOffset.UTC); |
| 137 | + return OffsetDateTime.of(toLocalDateTime(), ZoneOffset.UTC); |
134 | 138 | }
|
135 | 139 |
|
136 | 140 | public static long getMicroseconds(Timestamp sqlTimestamp) {
|
|
0 commit comments