1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.shardingsphere.db.protocol.firebird.packet.command.query.statement.execute.protocol.util;
19
20 import lombok.Getter;
21 import lombok.Setter;
22
23 import java.sql.Timestamp;
24 import java.time.LocalDateTime;
25
26
27
28
29 @Getter
30 @Setter
31 public final class FirebirdDateTimeUtil {
32
33 static final int NANOSECONDS_PER_FRACTION = 100 * 1000;
34
35 static final int FRACTIONS_PER_MILLISECOND = 10;
36
37 static final int FRACTIONS_PER_SECOND = 1000 * FRACTIONS_PER_MILLISECOND;
38
39 static final int FRACTIONS_PER_MINUTE = 60 * FRACTIONS_PER_SECOND;
40
41 static final int FRACTIONS_PER_HOUR = 60 * FRACTIONS_PER_MINUTE;
42
43 private int year;
44
45 private int month;
46
47 private int day;
48
49 private int hour;
50
51 private int minute;
52
53 private int second;
54
55 private int fractions;
56
57 public FirebirdDateTimeUtil(final LocalDateTime localDateTime) {
58 year = localDateTime.getYear();
59 month = localDateTime.getMonthValue();
60 day = localDateTime.getDayOfMonth();
61 hour = localDateTime.getHour();
62 minute = localDateTime.getMinute();
63 second = localDateTime.getSecond();
64 fractions = (localDateTime.getNano() / NANOSECONDS_PER_FRACTION) % FRACTIONS_PER_SECOND;
65 }
66
67 public FirebirdDateTimeUtil() {
68 year = 0;
69 month = 1;
70 day = 1;
71 hour = 0;
72 minute = 0;
73 second = 0;
74 fractions = 0;
75 }
76
77
78
79
80
81
82 public int getEncodedDate() {
83 int cpMonth = month;
84 int cpYear = year;
85 if (cpMonth > 2) {
86 cpMonth -= 3;
87 } else {
88 cpMonth += 9;
89 cpYear -= 1;
90 }
91 int c = cpYear / 100;
92 int ya = cpYear - 100 * c;
93 return convertDate(c, ya, cpMonth);
94 }
95
96
97
98
99
100
101
102 public static int getEncodedDate(final LocalDateTime localDateTime) {
103 return new FirebirdDateTimeUtil(localDateTime).getEncodedDate();
104 }
105
106 private int convertDate(final int c, final int ya, final int cpMonth) {
107 return (146097 * c) / 4
108 + (1461 * ya) / 4
109 + (153 * cpMonth + 2) / 5
110 + day + 1721119 - 2400001;
111 }
112
113
114
115
116
117
118
119 public FirebirdDateTimeUtil setDate(final int encodedDate) {
120 int sqldate = encodedDate - 1721119 + 2400001;
121 int century = (4 * sqldate - 1) / 146097;
122 sqldate = 4 * sqldate - 1 - 146097 * century;
123 day = sqldate / 4;
124 sqldate = (4 * day + 3) / 1461;
125 day = 4 * day + 3 - 1461 * sqldate;
126 day = (day + 5) / 5;
127 month = (5 * day - 3) / 153;
128 day = 5 * day - 3 - 153 * month;
129 day = (day + 5) / 5;
130 year = 100 * century + sqldate;
131 if (month < 10) {
132 month += 3;
133 } else {
134 month -= 9;
135 year += 1;
136 }
137 return this;
138 }
139
140 public int getEncodedTime() {
141 return hour * FRACTIONS_PER_HOUR
142 + minute * FRACTIONS_PER_MINUTE
143 + second * FRACTIONS_PER_SECOND
144 + fractions;
145 }
146
147
148
149
150
151
152
153 public FirebirdDateTimeUtil setTime(final int encodedTime) {
154 int fractionsInDay = encodedTime;
155 hour = fractionsInDay / FRACTIONS_PER_HOUR;
156 fractionsInDay -= hour * FRACTIONS_PER_HOUR;
157 minute = fractionsInDay / FRACTIONS_PER_MINUTE;
158 fractionsInDay -= minute * FRACTIONS_PER_MINUTE;
159 second = fractionsInDay / FRACTIONS_PER_SECOND;
160 fractions = fractionsInDay - second * FRACTIONS_PER_SECOND;
161 return this;
162 }
163
164
165
166
167
168
169 public Timestamp asTimestamp() {
170 return Timestamp.valueOf(LocalDateTime.of(year, month, day, hour, minute, second, fractions));
171 }
172
173
174
175
176
177
178
179 public static Timestamp getDate(final int encodedDate) {
180 return new FirebirdDateTimeUtil().setDate(encodedDate).asTimestamp();
181 }
182
183
184
185
186
187
188
189 public static Timestamp getTime(final int encodedTime) {
190 return new FirebirdDateTimeUtil().setTime(encodedTime).asTimestamp();
191 }
192
193
194
195
196
197
198
199
200 public static Timestamp getDateTime(final int encodedDate, final int encodedTime) {
201 return new FirebirdDateTimeUtil().setDate(encodedDate).setTime(encodedTime).asTimestamp();
202 }
203
204
205
206
207
208
209
210
211
212 public static Timestamp getDateTimeWithOffset(final int encodedDate, final int encodedTime, final int offset) {
213
214 return new FirebirdDateTimeUtil().setDate(encodedDate).setTime(encodedTime).asTimestamp();
215 }
216 }