2424
2525package io .questdb .cairo ;
2626
27- import io .questdb .std .LongList ;
28- import io .questdb .std .Numbers ;
29- import io .questdb .std .NumericException ;
30- import io .questdb .std .Unsafe ;
31- import io .questdb .std .datetime .Clock ;
32- import io .questdb .std .datetime .CommonUtils ;
33- import io .questdb .std .datetime .DateFormat ;
34- import io .questdb .std .datetime .DateLocale ;
35- import io .questdb .std .datetime .TimeZoneRules ;
3627import io .questdb .std .datetime .microtime .Micros ;
3728
38- import io .questdb .std .datetime .microtime .MicrosFormatUtils ;
39- import io .questdb .std .datetime .microtime .MicrosecondClockImpl ;
40- import io .questdb .std .str .CharSink ;
41- import io .questdb .std .str .Utf8Sequence ;
42- import org .jetbrains .annotations .NotNull ;
43- import org .jetbrains .annotations .Nullable ;
44- import org .jetbrains .annotations .TestOnly ;
45-
4629import java .time .Duration ;
4730import java .time .Instant ;
4831import java .time .temporal .ChronoUnit ;
4932
50- import static io .questdb .std .datetime .TimeZoneRuleFactory .RESOLUTION_MICROS ;
51- import static io .questdb .std .datetime .microtime .MicrosFormatUtils .*;
52-
5333public class MicrosTimestampDriver implements TimestampDriver {
5434 public static final TimestampDriver INSTANCE = new MicrosTimestampDriver ();
5535
5636 private MicrosTimestampDriver () {
5737 }
5838
59- @ Override
60- public void append (CharSink <?> sink , long timestamp ) {
61- MicrosFormatUtils .appendDateTimeUSec (sink , timestamp );
62- }
63-
64- public boolean append (long fixedAddr , CharSink <?> sink ) {
65- long value = Unsafe .getUnsafe ().getLong (fixedAddr );
66- if (value != Numbers .LONG_NULL ) {
67- MicrosFormatUtils .appendDateTimeUSec (sink , value );
68- return true ;
69- }
70- return false ;
71- }
72-
7339 @ Override
7440 public long from (long value , ChronoUnit unit ) {
7541 switch (unit ) {
@@ -97,143 +63,4 @@ public long from(long value, ChronoUnit unit) {
9763 public long from (Instant instant ) {
9864 return Math .addExact (Math .multiplyExact (instant .getEpochSecond (), Micros .SECOND_MICROS ), instant .getNano () / Micros .MICRO_NANOS );
9965 }
100-
101- @ Override
102- public long parseFloor (CharSequence str , int lo , int hi ) throws NumericException {
103- long ts ;
104- if (hi - lo < 4 ) {
105- throw NumericException .instance ();
106- }
107- int p = lo ;
108- int year = Numbers .parseInt (str , p , p += 4 );
109- boolean l = CommonUtils .isLeapYear (year );
110- if (CommonUtils .checkLen3 (p , hi )) {
111- CommonUtils .checkChar (str , p ++, hi , '-' );
112- int month = Numbers .parseInt (str , p , p += 2 );
113- CommonUtils .checkRange (month , 1 , 12 );
114- if (CommonUtils .checkLen3 (p , hi )) {
115- CommonUtils .checkChar (str , p ++, hi , '-' );
116- int day = Numbers .parseInt (str , p , p += 2 );
117- CommonUtils .checkRange (day , 1 , CommonUtils .getDaysPerMonth (month , l ));
118- if (CommonUtils .checkLen3 (p , hi )) {
119- CommonUtils .checkSpecialChar (str , p ++, hi );
120- int hour = Numbers .parseInt (str , p , p += 2 );
121- CommonUtils .checkRange (hour , 0 , 23 );
122- if (CommonUtils .checkLen3 (p , hi )) {
123- CommonUtils .checkChar (str , p ++, hi , ':' );
124- int min = Numbers .parseInt (str , p , p += 2 );
125- CommonUtils .checkRange (min , 0 , 59 );
126- if (CommonUtils .checkLen3 (p , hi )) {
127- CommonUtils .checkChar (str , p ++, hi , ':' );
128- int sec = Numbers .parseInt (str , p , p += 2 );
129- CommonUtils .checkRange (sec , 0 , 59 );
130- if (p < hi && str .charAt (p ) == '.' ) {
131- p ++;
132- // varlen milli and micros
133- int micrLim = p + 6 ;
134- int mlim = Math .min (hi , micrLim );
135- int micr = 0 ;
136- for (; p < mlim ; p ++) {
137- char c = str .charAt (p );
138- if (Numbers .notDigit (c )) {
139- // Timezone
140- break ;
141- }
142- micr *= 10 ;
143- micr += c - '0' ;
144- }
145- micr *= CommonUtils .tenPow (micrLim - p );
146-
147- // truncate remaining nanos if any
148- for (int nlim = Math .min (hi , p + 3 ); p < nlim ; p ++) {
149- char c = str .charAt (p );
150- if (Numbers .notDigit (c )) {
151- // Timezone
152- break ;
153- }
154- }
155-
156- // micros
157- ts = Micros .yearMicros (year , l )
158- + Micros .monthOfYearMicros (month , l )
159- + (day - 1 ) * Micros .DAY_MICROS
160- + hour * Micros .HOUR_MICROS
161- + min * Micros .MINUTE_MICROS
162- + sec * Micros .SECOND_MICROS
163- + micr
164- + checkTimezoneTail (str , p , hi );
165- } else {
166- // seconds
167- ts = Micros .yearMicros (year , l )
168- + Micros .monthOfYearMicros (month , l )
169- + (day - 1 ) * Micros .DAY_MICROS
170- + hour * Micros .HOUR_MICROS
171- + min * Micros .MINUTE_MICROS
172- + sec * Micros .SECOND_MICROS
173- + checkTimezoneTail (str , p , hi );
174- }
175- } else {
176- // minute
177- ts = Micros .yearMicros (year , l )
178- + Micros .monthOfYearMicros (month , l )
179- + (day - 1 ) * Micros .DAY_MICROS
180- + hour * Micros .HOUR_MICROS
181- + min * Micros .MINUTE_MICROS ;
182-
183- }
184- } else {
185- // year + month + day + hour
186- ts = Micros .yearMicros (year , l )
187- + Micros .monthOfYearMicros (month , l )
188- + (day - 1 ) * Micros .DAY_MICROS
189- + hour * Micros .HOUR_MICROS ;
190-
191- }
192- } else {
193- // year + month + day
194- ts = Micros .yearMicros (year , l )
195- + Micros .monthOfYearMicros (month , l )
196- + (day - 1 ) * Micros .DAY_MICROS ;
197- }
198- } else {
199- // year + month
200- ts = (Micros .yearMicros (year , l ) + Micros .monthOfYearMicros (month , l ));
201- }
202- } else {
203- // year
204- ts = (Micros .yearMicros (year , l ) + Micros .monthOfYearMicros (1 , l ));
205- }
206- return ts ;
207- }
208-
209- private static long checkTimezoneTail (CharSequence seq , int p , int lim ) throws NumericException {
210- if (lim == p ) {
211- return 0 ;
212- }
213-
214- if (lim - p < 2 ) {
215- CommonUtils .checkChar (seq , p , lim , 'Z' );
216- return 0 ;
217- }
218-
219- if (lim - p > 2 ) {
220- int tzSign = CommonUtils .parseSign (seq .charAt (p ++));
221- int hour = Numbers .parseInt (seq , p , p += 2 );
222- CommonUtils .checkRange (hour , 0 , 23 );
223-
224- if (lim - p == 3 ) {
225- // Optional : separator between hours and mins in timezone
226- CommonUtils .checkChar (seq , p ++, lim , ':' );
227- }
228-
229- if (CommonUtils .checkLenStrict (p , lim )) {
230- int min = Numbers .parseInt (seq , p , p + 2 );
231- CommonUtils .checkRange (min , 0 , 59 );
232- return tzSign * (hour * Micros .HOUR_MICROS + min * Micros .MINUTE_MICROS );
233- } else {
234- return tzSign * (hour * Micros .HOUR_MICROS );
235- }
236- }
237- throw NumericException .instance ();
238- }
23966}
0 commit comments