OmniSciDB  72c90bc290
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DateTruncate.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2022 HEAVY.AI, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 /*
18  * Thank you Howard Hinnant for public domain date algorithms
19  * http://howardhinnant.github.io/date_algorithms.html
20  */
21 
22 #include "DateTruncate.h"
23 #include "ExtractFromTime.h"
24 
25 #ifndef __CUDACC__
26 #include <cstdlib> // abort()
27 #endif
28 
29 #include <cmath>
30 #include <ctime>
31 #include <iostream>
32 #include <limits>
33 
34 extern "C" RUNTIME_EXPORT ALWAYS_INLINE DEVICE int64_t datetrunc_minute(int64_t timeval) {
35  return timeval - unsigned_mod(timeval, kSecsPerMin);
36 }
37 
38 extern "C" RUNTIME_EXPORT ALWAYS_INLINE DEVICE int64_t datetrunc_hour(int64_t timeval) {
39  return timeval - unsigned_mod(timeval, kSecsPerHour);
40 }
41 
42 extern "C" RUNTIME_EXPORT ALWAYS_INLINE DEVICE int64_t
43 datetrunc_quarterday(int64_t timeval) {
44  return timeval - unsigned_mod(timeval, kSecsPerQuarterDay);
45 }
46 
47 extern "C" RUNTIME_EXPORT ALWAYS_INLINE DEVICE int64_t datetrunc_day(int64_t timeval) {
48  return timeval - unsigned_mod(timeval, kSecsPerDay);
49 }
50 
51 namespace {
52 // Days before Thursday (since 1 Jan 1970 is a Thursday.)
53 constexpr unsigned dtMONDAY = 3;
54 constexpr unsigned dtSUNDAY = 4;
55 constexpr unsigned dtSATURDAY = 5;
56 } // namespace
57 
58 template <unsigned OFFSET>
59 ALWAYS_INLINE DEVICE int64_t datetrunc_week(int64_t timeval) {
60  // Truncate to OFFSET.
61  return timeval - unsigned_mod(timeval + OFFSET * kSecsPerDay, 7 * kSecsPerDay);
62 }
63 
64 extern "C" RUNTIME_EXPORT ALWAYS_INLINE DEVICE int64_t
65 datetrunc_week_monday(int64_t timeval) {
66  return datetrunc_week<dtMONDAY>(timeval);
67 }
68 
69 extern "C" RUNTIME_EXPORT ALWAYS_INLINE DEVICE int64_t
70 datetrunc_week_sunday(int64_t timeval) {
71  return datetrunc_week<dtSUNDAY>(timeval);
72 }
73 
74 extern "C" RUNTIME_EXPORT ALWAYS_INLINE DEVICE int64_t
75 datetrunc_week_saturday(int64_t timeval) {
76  return datetrunc_week<dtSATURDAY>(timeval);
77 }
78 
79 extern "C" RUNTIME_EXPORT ALWAYS_INLINE DEVICE int64_t datetrunc_month(int64_t timeval) {
80  if (timeval >= 0LL && timeval <= UINT32_MAX - (kEpochOffsetYear1900)) {
81  STATIC_QUAL const uint32_t cumulative_month_epoch_starts[kMonsPerYear] = {0,
82  2678400,
83  5270400,
84  7948800,
85  10540800,
86  13219200,
87  15897600,
88  18489600,
89  21168000,
90  23760000,
91  26438400,
92  29116800};
93  // Handles times from Thu 01 Jan 1970 00:00:00 - Thu 07 Feb 2036 06:28:15.
94  uint32_t seconds_march_1900 = timeval + kEpochOffsetYear1900 - kSecsJanToMar1900;
95  uint32_t seconds_past_4year_period = seconds_march_1900 % kSecondsPer4YearCycle;
96  uint32_t four_year_period_seconds =
97  (seconds_march_1900 / kSecondsPer4YearCycle) * kSecondsPer4YearCycle;
98  uint32_t year_seconds_past_4year_period =
99  (seconds_past_4year_period / kSecondsPerNonLeapYear) * kSecondsPerNonLeapYear;
100  if (seconds_past_4year_period >=
101  kSecondsPer4YearCycle - kUSecsPerDay) { // if we are in Feb 29th
102  year_seconds_past_4year_period -= kSecondsPerNonLeapYear;
103  }
104  uint32_t seconds_past_march =
105  seconds_past_4year_period - year_seconds_past_4year_period;
106  uint32_t month =
107  seconds_past_march / (30 * kUSecsPerDay); // Will make the correct month either
108  // be the guessed month or month before
109  month = month <= 11 ? month : 11;
110  if (cumulative_month_epoch_starts[month] > seconds_past_march) {
111  month--;
112  }
113  return (static_cast<int64_t>(four_year_period_seconds) +
114  year_seconds_past_4year_period + cumulative_month_epoch_starts[month] -
116  } else {
117  int64_t const day = floor_div(timeval, kSecsPerDay);
118  unsigned const doe = unsigned_mod(day - kEpochAdjustedDays, kDaysPer400Years);
119  unsigned const yoe = (doe - doe / 1460 + doe / 36524 - (doe == 146096)) / 365;
120  unsigned const doy = doe - (365 * yoe + yoe / 4 - yoe / 100);
121  unsigned const moy = (5 * doy + 2) / 153;
122  unsigned const dom = doy - (153 * moy + 2) / 5;
123  return (day - dom) * kSecsPerDay;
124  }
125 }
126 
127 extern "C" RUNTIME_EXPORT ALWAYS_INLINE DEVICE int64_t
128 datetrunc_quarter(int64_t timeval) {
129  if (timeval >= 0LL && timeval <= UINT32_MAX - kEpochOffsetYear1900) {
130  STATIC_QUAL const uint32_t cumulative_quarter_epoch_starts[4] = {
131  0, 7776000, 15638400, 23587200};
132  STATIC_QUAL const uint32_t cumulative_quarter_epoch_starts_leap_year[4] = {
133  0, 7862400, 15724800, 23673600};
134  // Handles times from Thu 01 Jan 1970 00:00:00 - Thu 07 Feb 2036 06:28:15.
135  uint32_t seconds_1900 = timeval + kEpochOffsetYear1900;
136  uint32_t leap_years = (seconds_1900 - kSecsJanToMar1900) / kSecondsPer4YearCycle;
137  uint32_t year = (seconds_1900 - leap_years * kUSecsPerDay) / kSecondsPerNonLeapYear;
138  uint32_t base_year_leap_years = (year - 1) / 4;
139  uint32_t base_year_seconds =
140  year * kSecondsPerNonLeapYear + base_year_leap_years * kUSecsPerDay;
141  const bool is_leap_year = year % 4 == 0 && year != 0;
142  const uint32_t* quarter_offsets = is_leap_year
143  ? cumulative_quarter_epoch_starts_leap_year
144  : cumulative_quarter_epoch_starts;
145  uint32_t partial_year_seconds = seconds_1900 % base_year_seconds;
146  uint32_t quarter = partial_year_seconds / (90 * kUSecsPerDay);
147  quarter = quarter <= 3 ? quarter : 3;
148  if (quarter_offsets[quarter] > partial_year_seconds) {
149  quarter--;
150  }
151  return (static_cast<int64_t>(base_year_seconds) + quarter_offsets[quarter] -
153  } else {
154  int64_t const day = floor_div(timeval, kSecsPerDay);
155  unsigned const doe = unsigned_mod(day - kEpochAdjustedDays, kDaysPer400Years);
156  unsigned const yoe = (doe - doe / 1460 + doe / 36524 - (doe == 146096)) / 365;
157  unsigned const doy = doe - (365 * yoe + yoe / 4 - yoe / 100);
158  constexpr unsigned apr1 = 31; // Days in march
159  unsigned doq; // Day-of-quarter = Days since last Apr1, Jul1, Oct1, Jan1.
160  if (doy < apr1) {
161  bool const leap = yoe % 4 == 0 && (yoe % 100 != 0 || yoe == 0);
162  doq = JANMAR + leap + doy; // Q1
163  } else {
164  unsigned const q = (3 * (doy - apr1) + 2) / 275; // quarter = 0, 1, 2
165  doq = doy - (apr1 + q * 92 - (q != 0)); // Q2, Q3, Q4
166  }
167  return (day - doq) * kSecsPerDay;
168  }
169 }
170 
171 extern "C" RUNTIME_EXPORT ALWAYS_INLINE DEVICE int64_t datetrunc_year(int64_t timeval) {
172  if (timeval >= 0LL && timeval <= UINT32_MAX - kEpochOffsetYear1900) {
173  // Handles times from Thu 01 Jan 1970 00:00:00 - Thu 07 Feb 2036 06:28:15.
174  uint32_t seconds_1900 = static_cast<uint32_t>(timeval) + kEpochOffsetYear1900;
175  uint32_t leap_years = (seconds_1900 - kSecsJanToMar1900) / kSecondsPer4YearCycle;
176  uint32_t year = (seconds_1900 - leap_years * kUSecsPerDay) / kSecondsPerNonLeapYear;
177  uint32_t base_year_leap_years = (year - 1) / 4;
178  return (static_cast<int64_t>(year) * kSecondsPerNonLeapYear +
179  base_year_leap_years * kUSecsPerDay - kEpochOffsetYear1900);
180  } else {
181  int64_t const day = floor_div(timeval, kSecsPerDay);
182  unsigned const doe = unsigned_mod(day - kEpochAdjustedDays, kDaysPer400Years);
183  unsigned const yoe = (doe - doe / 1460 + doe / 36524 - (doe == 146096)) / 365;
184  unsigned const doy = doe - (365 * yoe + yoe / 4 - yoe / 100);
185  unsigned docy; // Day-of-calendar-year = Days since last Jan1.
186  if (doy < MARJAN) {
187  bool const leap = yoe % 4 == 0 && (yoe == 0 || yoe % 100 != 0);
188  docy = JANMAR + leap + doy;
189  } else {
190  docy = doy - MARJAN;
191  }
192  return (day - docy) * kSecsPerDay;
193  }
194 }
195 
196 extern "C" RUNTIME_EXPORT ALWAYS_INLINE DEVICE int64_t datetrunc_decade(int64_t timeval) {
197  // Number of days from x00301 to (x+1)00101. Always includes exactly two leap days.
198  constexpr unsigned decmarjan = MARJAN + 9 * 365 + 2;
199  int64_t const day = floor_div(timeval, kSecsPerDay);
200  unsigned const doe = unsigned_mod(day - kEpochAdjustedDays, kDaysPer400Years);
201  unsigned const yoe = (doe - doe / 1460 + doe / 36524 - (doe == 146096)) / 365;
202  unsigned const decoe = yoe - yoe % 10; // Decade-of-era
203  // Initialize to days after mar1 of decade, then adjust to after jan1 below.
204  unsigned days_after_decade = doe - (365 * decoe + decoe / 4 - decoe / 100);
205  if (days_after_decade < decmarjan) {
206  bool const leap = decoe % 4 == 0 && (decoe == 0 || decoe % 100 != 0);
207  days_after_decade += JANMAR + leap;
208  } else {
209  days_after_decade -= decmarjan;
210  }
211  return (day - days_after_decade) * kSecsPerDay;
212 }
213 
214 extern "C" RUNTIME_EXPORT ALWAYS_INLINE DEVICE int64_t
215 datetrunc_century(int64_t timeval) {
216  int64_t const day = floor_div(timeval, kSecsPerDay);
217  unsigned const doe = unsigned_mod(day - kEpochAdjustedDays, kDaysPer400Years);
218  // Day-of-century = Days since last 010101 (Jan 1 1901, 2001, 2101, etc.)
219  unsigned const doc = doe < MARJAN ? doe + (36525 - MARJAN) : (doe - MARJAN) % 36524;
220  return (day - doc) * kSecsPerDay;
221 }
222 
223 extern "C" RUNTIME_EXPORT ALWAYS_INLINE DEVICE int64_t
224 datetrunc_millennium(int64_t timeval) {
225  constexpr unsigned millennium2001 = 365242; // Days from Jan 1 2001 to 3001.
226  int64_t const day = floor_div(timeval, kSecsPerDay);
227  // lcm(400, 1000) = 2000 so use 5*400-year eras at a time.
228  unsigned dom = unsigned_mod(day - kEpochAdjustedDays, 5 * kDaysPer400Years);
229  if (dom < MARJAN) {
230  dom += millennium2001 + 1 - MARJAN;
231  } else if (dom < MARJAN + millennium2001) {
232  dom -= MARJAN;
233  } else {
234  dom -= MARJAN + millennium2001;
235  }
236  return (day - dom) * kSecsPerDay;
237 }
238 
239 /*
240  * @brief support the SQL DATE_TRUNC function
241  */
242 DEVICE int64_t DateTruncate(DatetruncField field, const int64_t timeval) {
243  switch (field) {
244  case dtNANOSECOND:
245  case dtMICROSECOND:
246  case dtMILLISECOND:
247  case dtSECOND:
248  return timeval;
249  case dtMINUTE:
250  return datetrunc_minute(timeval);
251  case dtHOUR:
252  return datetrunc_hour(timeval);
253  case dtQUARTERDAY:
254  return datetrunc_quarterday(timeval);
255  case dtDAY:
256  return datetrunc_day(timeval);
257  case dtWEEK:
258  return datetrunc_week_monday(timeval);
259  case dtWEEK_SUNDAY:
260  return datetrunc_week_sunday(timeval);
261  case dtWEEK_SATURDAY:
262  return datetrunc_week_saturday(timeval);
263  case dtMONTH:
264  return datetrunc_month(timeval);
265  case dtQUARTER:
266  return datetrunc_quarter(timeval);
267  case dtYEAR:
268  return datetrunc_year(timeval);
269  case dtDECADE:
270  return datetrunc_decade(timeval);
271  case dtCENTURY:
272  return datetrunc_century(timeval);
273  case dtMILLENNIUM:
274  return datetrunc_millennium(timeval);
275  default:
276 #ifdef __CUDACC__
277  return std::numeric_limits<int64_t>::min();
278 #else
279  abort();
280 #endif
281  }
282 }
283 
284 // scale is 10^{3,6,9}
285 extern "C" RUNTIME_EXPORT ALWAYS_INLINE DEVICE int64_t
286 DateTruncateHighPrecisionToDate(const int64_t timeval, const int64_t scale) {
287  return floor_div(timeval, scale * kSecsPerDay) * kSecsPerDay;
288 }
289 
290 extern "C" RUNTIME_EXPORT ALWAYS_INLINE DEVICE int64_t
292  const int64_t scale,
293  const int64_t null_val) {
294  if (timeval == null_val) {
295  return null_val;
296  }
297  return DateTruncateHighPrecisionToDate(timeval, scale);
298 }
299 
300 namespace {
301 
302 struct EraTime {
303  int64_t const era;
304  int const yoe; // year-of-era
305  int const moy; // month-of-year (March = 0)
306  int const dom; // day-of-month
307  int const sod; // second-of-day
308 
309  DEVICE static EraTime make(int64_t const time) {
310  int64_t const day = floor_div(time, kSecsPerDay);
311  int64_t const era = floor_div(day - kEpochAdjustedDays, kDaysPer400Years);
312  int const sod = time - day * kSecsPerDay;
313  int const doe = day - kEpochAdjustedDays - era * kDaysPer400Years;
314  int const yoe = (doe - doe / 1460 + doe / 36524 - doe / 146096) / 365;
315  int const doy = doe - (365 * yoe + yoe / 4 - yoe / 100);
316  int const moy = (5 * doy + 2) / 153;
317  int const dom = doy - (153 * moy + 2) / 5;
318  return {era, yoe, moy, dom, sod};
319  }
320 
321  DEVICE EraTime operator-() const { return {-era, -yoe, -moy, -dom, -sod}; }
322 
324  return {era - rhs.era, yoe - rhs.yoe, moy - rhs.moy, dom - rhs.dom, sod - rhs.sod};
325  }
326 
327  enum Field { ERA, YOE, MOY, DOM, SOD };
328  // Sign of EraTime starting at field.
329  DEVICE int sign(Field const field) const {
330  switch (field) {
331  case ERA:
332  if (era != 0) {
333  return era < 0 ? -1 : 1;
334  }
335  case YOE:
336  if (yoe != 0) {
337  return yoe < 0 ? -1 : 1;
338  }
339  case MOY:
340  if (moy != 0) {
341  return moy < 0 ? -1 : 1;
342  }
343  case DOM:
344  if (dom != 0) {
345  return dom < 0 ? -1 : 1;
346  }
347  case SOD:
348  if (sod != 0) {
349  return sod < 0 ? -1 : 1;
350  }
351  default:
352  return 0;
353  }
354  }
355 
356  DEVICE int64_t count(DatetruncField const field) const {
357  int const sgn = sign(ERA);
358  EraTime const ut = sgn == -1 ? -*this : *this; // Unsigned time
359  switch (field) {
360  case dtMONTH:
361  return sgn * (12 * (400 * ut.era + ut.yoe) + ut.moy - (ut.sign(DOM) == -1));
362  case dtQUARTER: {
363  int const quarters = ut.moy / 3;
364  int const rem = ut.moy % 3;
365  return sgn * (4 * (400 * ut.era + ut.yoe) + quarters -
366  (rem < 0 || (rem == 0 && ut.sign(DOM) == -1)));
367  }
368  case dtYEAR:
369  return sgn * (400 * ut.era + ut.yoe - (ut.sign(MOY) == -1));
370  case dtDECADE: {
371  uint64_t const decades = (400 * ut.era + ut.yoe) / 10;
372  unsigned const rem = (400 * ut.era + ut.yoe) % 10;
373  return sgn * (decades - (rem == 0 && ut.sign(MOY) == -1));
374  }
375  case dtCENTURY: {
376  uint64_t const centuries = (400 * ut.era + ut.yoe) / 100;
377  unsigned const rem = (400 * ut.era + ut.yoe) % 100;
378  return sgn * (centuries - (rem == 0 && ut.sign(MOY) == -1));
379  }
380  case dtMILLENNIUM: {
381  uint64_t const millennia = (400 * ut.era + ut.yoe) / 1000;
382  unsigned const rem = (400 * ut.era + ut.yoe) % 1000;
383  return sgn * (millennia - (rem == 0 && ut.sign(MOY) == -1));
384  }
385  default:
386 #ifdef __CUDACC__
387  return std::numeric_limits<int64_t>::min();
388 #else
389  abort();
390 #endif
391  }
392  }
393 };
394 
395 } // namespace
396 
397 extern "C" RUNTIME_EXPORT DEVICE int64_t DateDiff(const DatetruncField datepart,
398  const int64_t startdate,
399  const int64_t enddate) {
400  switch (datepart) {
401  case dtNANOSECOND:
402  return (enddate - startdate) * kNanoSecsPerSec;
403  case dtMICROSECOND:
404  return (enddate - startdate) * kMicroSecsPerSec;
405  case dtMILLISECOND:
406  return (enddate - startdate) * kMilliSecsPerSec;
407  case dtSECOND:
408  return enddate - startdate;
409  case dtMINUTE:
410  return (enddate - startdate) / kSecsPerMin;
411  case dtHOUR:
412  return (enddate - startdate) / kSecsPerHour;
413  case dtQUARTERDAY:
414  return (enddate - startdate) / (kSecsPerDay / 4);
415  case dtDAY:
416  return (enddate - startdate) / kSecsPerDay;
417  case dtWEEK:
418  case dtWEEK_SUNDAY:
419  case dtWEEK_SATURDAY:
420  return (enddate - startdate) / (7 * kSecsPerDay);
421  default:
422  return (EraTime::make(enddate) - EraTime::make(startdate)).count(datepart);
423  }
424 }
425 
426 extern "C" RUNTIME_EXPORT DEVICE int64_t
428  const int64_t startdate,
429  const int64_t enddate,
430  const int32_t start_dim,
431  const int32_t end_dim) {
432  // Return pow(10,i). Only valid for i = 0, 3, 6, 9.
433  constexpr int pow10[10]{1, 0, 0, 1000, 0, 0, 1000 * 1000, 0, 0, 1000 * 1000 * 1000};
434  switch (datepart) {
435  case dtNANOSECOND:
436  case dtMICROSECOND:
437  case dtMILLISECOND: {
438  static_assert(dtMILLISECOND + 1 == dtMICROSECOND, "Please keep these consecutive.");
439  static_assert(dtMICROSECOND + 1 == dtNANOSECOND, "Please keep these consecutive.");
440  int const target_dim = (datepart - (dtMILLISECOND - 1)) * 3; // 3, 6, or 9.
441  int const delta_dim = end_dim - start_dim; // in [-9,9] multiple of 3
442  int const adj_dim = target_dim - (delta_dim < 0 ? start_dim : end_dim);
443  int64_t const numerator = delta_dim < 0 ? enddate * pow10[-delta_dim] - startdate
444  : enddate - startdate * pow10[delta_dim];
445  return adj_dim < 0 ? numerator / pow10[-adj_dim] : numerator * pow10[adj_dim];
446  }
447  default:
448  int64_t const end_seconds = floor_div(enddate, pow10[end_dim]);
449  int delta_ns = (enddate - end_seconds * pow10[end_dim]) * pow10[9 - end_dim];
450  int64_t const start_seconds = floor_div(startdate, pow10[start_dim]);
451  delta_ns -= (startdate - start_seconds * pow10[start_dim]) * pow10[9 - start_dim];
452  int64_t const delta_s = end_seconds - start_seconds;
453  // sub-second values must be accounted for when calling DateDiff. Examples:
454  // 2000-02-15 12:00:00.006 to 2000-03-15 12:00:00.005 is 0 months.
455  // 2000-02-15 12:00:00.006 to 2000-03-15 12:00:00.006 is 1 month.
456  int const adj_sec = 0 < delta_s && delta_ns < 0 ? -1
457  : delta_s < 0 && 0 < delta_ns ? 1
458  : 0;
459  return DateDiff(datepart, start_seconds, end_seconds + adj_sec);
460  }
461 }
462 
463 extern "C" RUNTIME_EXPORT DEVICE int64_t DateDiffNullable(const DatetruncField datepart,
464  const int64_t startdate,
465  const int64_t enddate,
466  const int64_t null_val) {
467  if (startdate == null_val || enddate == null_val) {
468  return null_val;
469  }
470  return DateDiff(datepart, startdate, enddate);
471 }
472 
473 extern "C" RUNTIME_EXPORT DEVICE int64_t
475  const int64_t startdate,
476  const int64_t enddate,
477  const int32_t start_dim,
478  const int32_t end_dim,
479  const int64_t null_val) {
480  if (startdate == null_val || enddate == null_val) {
481  return null_val;
482  }
483  return DateDiffHighPrecision(datepart, startdate, enddate, start_dim, end_dim);
484 }
RUNTIME_EXPORT ALWAYS_INLINE DEVICE int64_t datetrunc_millennium(int64_t timeval)
static constexpr int64_t kSecsPerDay
static constexpr uint32_t kSecsJanToMar1900
static constexpr uint32_t kUSecsPerDay
DEVICE int sign(Field const field) const
RUNTIME_EXPORT DEVICE int64_t DateDiffHighPrecisionNullable(const DatetruncField datepart, const int64_t startdate, const int64_t enddate, const int32_t start_dim, const int32_t end_dim, const int64_t null_val)
static constexpr int64_t kSecsPerHour
static constexpr int64_t kSecsPerMin
static constexpr int64_t kNanoSecsPerSec
RUNTIME_EXPORT ALWAYS_INLINE DEVICE int64_t datetrunc_quarter(int64_t timeval)
constexpr unsigned JANMAR
RUNTIME_EXPORT ALWAYS_INLINE DEVICE int64_t datetrunc_quarterday(int64_t timeval)
DEVICE int64_t DateTruncate(DatetruncField field, const int64_t timeval)
static constexpr int64_t kSecsPerQuarterDay
static DEVICE EraTime make(int64_t const time)
#define STATIC_QUAL
RUNTIME_EXPORT DEVICE int64_t DateDiff(const DatetruncField datepart, const int64_t startdate, const int64_t enddate)
DEVICE int64_t floor_div(int64_t const dividend, int64_t const divisor)
RUNTIME_EXPORT DEVICE int64_t DateDiffHighPrecision(const DatetruncField datepart, const int64_t startdate, const int64_t enddate, const int32_t start_dim, const int32_t end_dim)
static constexpr uint32_t kEpochOffsetYear1900
#define DEVICE
static constexpr int64_t kMilliSecsPerSec
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
Definition: JsonAccessors.h:33
RUNTIME_EXPORT ALWAYS_INLINE DEVICE int64_t datetrunc_day(int64_t timeval)
static constexpr int32_t kEpochAdjustedDays
DatetruncField
Definition: DateTruncate.h:27
RUNTIME_EXPORT ALWAYS_INLINE DEVICE int64_t DateTruncateHighPrecisionToDateNullable(const int64_t timeval, const int64_t scale, const int64_t null_val)
DEVICE EraTime operator-(EraTime const &rhs)
RUNTIME_EXPORT ALWAYS_INLINE DEVICE int64_t datetrunc_century(int64_t timeval)
RUNTIME_EXPORT ALWAYS_INLINE DEVICE int64_t datetrunc_decade(int64_t timeval)
RUNTIME_EXPORT ALWAYS_INLINE DEVICE int64_t datetrunc_week_saturday(int64_t timeval)
ALWAYS_INLINE DEVICE int64_t datetrunc_week(int64_t timeval)
static constexpr uint32_t kSecondsPer4YearCycle
#define RUNTIME_EXPORT
RUNTIME_EXPORT ALWAYS_INLINE DEVICE int64_t datetrunc_hour(int64_t timeval)
static constexpr int64_t kDaysPer400Years
constexpr unsigned MARJAN
DEVICE int64_t unsigned_mod(int64_t const dividend, int64_t const divisor)
DEVICE int64_t count(DatetruncField const field) const
RUNTIME_EXPORT ALWAYS_INLINE DEVICE int64_t DateTruncateHighPrecisionToDate(const int64_t timeval, const int64_t scale)
RUNTIME_EXPORT ALWAYS_INLINE DEVICE int64_t datetrunc_month(int64_t timeval)
RUNTIME_EXPORT ALWAYS_INLINE DEVICE int64_t datetrunc_week_sunday(int64_t timeval)
RUNTIME_EXPORT ALWAYS_INLINE DEVICE int64_t datetrunc_minute(int64_t timeval)
static constexpr uint32_t kSecondsPerNonLeapYear
RUNTIME_EXPORT ALWAYS_INLINE DEVICE int64_t datetrunc_week_monday(int64_t timeval)
#define ALWAYS_INLINE
static constexpr int64_t kMicroSecsPerSec
RUNTIME_EXPORT ALWAYS_INLINE DEVICE int64_t datetrunc_year(int64_t timeval)
RUNTIME_EXPORT DEVICE int64_t DateDiffNullable(const DatetruncField datepart, const int64_t startdate, const int64_t enddate, const int64_t null_val)
static constexpr int32_t kMonsPerYear