OmniSciDB  5ade3759e0
ExtractFromTime.cpp File Reference
#include "ExtractFromTime.h"
#include "../Shared/funcannotations.h"
#include <cstdlib>
+ Include dependency graph for ExtractFromTime.cpp:

Go to the source code of this file.

Functions

NEVER_INLINE DEVICE int32_t extract_hour (const int64_t lcltime)
 
DEVICE int32_t extract_minute (const int64_t lcltime)
 
DEVICE int32_t extract_second (const int64_t lcltime)
 
DEVICE int64_t extract_millisecond (const int64_t lcltime)
 
DEVICE int64_t extract_microsecond (const int64_t lcltime)
 
DEVICE int64_t extract_nanosecond (const int64_t lcltime)
 
DEVICE int32_t extract_dow (const int64_t lcltime)
 
DEVICE int32_t extract_quarterday (const int64_t lcltime)
 
DEVICE int32_t extract_month_fast (const int64_t lcltime)
 
DEVICE int32_t extract_quarter_fast (const int64_t lcltime)
 
DEVICE int32_t extract_year_fast (const int64_t lcltime)
 
DEVICE tm gmtime_r_newlib (const int64_t lcltime, tm &res)
 
NEVER_INLINE DEVICE int64_t ExtractFromTime (ExtractField field, const int64_t timeval)
 
DEVICE int64_t ExtractFromTimeNullable (ExtractField field, const int64_t timeval, const int64_t null_val)
 

Function Documentation

◆ extract_dow()

DEVICE int32_t extract_dow ( const int64_t  lcltime)

Definition at line 63 of file ExtractFromTime.cpp.

References kDaysPerWeek, kEpochAdjustedDays, kEpochAdjustedWDay, and kSecsPerDay.

Referenced by DateTruncate(), and ExtractFromTime().

63  {
64  int64_t days, rem;
65  int32_t weekday;
66  days = lcltime / kSecsPerDay - kEpochAdjustedDays;
67  rem = lcltime % kSecsPerDay;
68  if (rem < 0) {
69  rem += kSecsPerDay;
70  --days;
71  }
72 
73  if ((weekday = ((kEpochAdjustedWDay + days) % kDaysPerWeek)) < 0) {
74  weekday += kDaysPerWeek;
75  }
76  return weekday;
77 }
static constexpr int64_t kSecsPerDay
static constexpr int32_t kEpochAdjustedDays
static constexpr int32_t kDaysPerWeek
static constexpr int32_t kEpochAdjustedWDay
+ Here is the caller graph for this function:

◆ extract_hour()

NEVER_INLINE DEVICE int32_t extract_hour ( const int64_t  lcltime)

Definition at line 24 of file ExtractFromTime.cpp.

References kEpochAdjustedDays, kSecPerHour, and kSecsPerDay.

Referenced by ExtractFromTime().

24  {
25  int64_t days, rem;
26  days = lcltime / kSecsPerDay - kEpochAdjustedDays;
27  rem = lcltime % kSecsPerDay;
28  if (rem < 0) {
29  rem += kSecsPerDay;
30  --days;
31  }
32  return static_cast<int32_t>(rem / kSecPerHour);
33 }
static constexpr int64_t kSecsPerDay
static constexpr int32_t kEpochAdjustedDays
static constexpr int64_t kSecPerHour
+ Here is the caller graph for this function:

◆ extract_microsecond()

DEVICE int64_t extract_microsecond ( const int64_t  lcltime)

Definition at line 55 of file ExtractFromTime.cpp.

References kMicroSecsPerSec, and kSecsPerMin.

Referenced by ExtractFromTime().

55  {
56  return lcltime % (kSecsPerMin * kMicroSecsPerSec);
57 }
static constexpr int64_t kSecsPerMin
static constexpr int64_t kMicroSecsPerSec
+ Here is the caller graph for this function:

◆ extract_millisecond()

DEVICE int64_t extract_millisecond ( const int64_t  lcltime)

Definition at line 51 of file ExtractFromTime.cpp.

References kMilliSecsPerSec, and kSecsPerMin.

Referenced by ExtractFromTime().

51  {
52  return lcltime % (kSecsPerMin * kMilliSecsPerSec);
53 }
static constexpr int64_t kSecsPerMin
static constexpr int64_t kMilliSecsPerSec
+ Here is the caller graph for this function:

◆ extract_minute()

DEVICE int32_t extract_minute ( const int64_t  lcltime)

Definition at line 35 of file ExtractFromTime.cpp.

References kEpochAdjustedDays, kSecPerHour, kSecsPerDay, and kSecsPerMin.

Referenced by ExtractFromTime().

35  {
36  int64_t days, rem;
37  days = lcltime / kSecsPerDay - kEpochAdjustedDays;
38  rem = lcltime % kSecsPerDay;
39  if (rem < 0) {
40  rem += kSecsPerDay;
41  --days;
42  }
43  rem %= kSecPerHour;
44  return static_cast<int32_t>(rem / kSecsPerMin);
45 }
static constexpr int64_t kSecsPerDay
static constexpr int64_t kSecsPerMin
static constexpr int32_t kEpochAdjustedDays
static constexpr int64_t kSecPerHour
+ Here is the caller graph for this function:

◆ extract_month_fast()

DEVICE int32_t extract_month_fast ( const int64_t  lcltime)

Definition at line 85 of file ExtractFromTime.cpp.

References kEpochOffsetYear1900, kMonsPerYear, kSecondsPer4YearCycle, kSecondsPerNonLeapYear, kSecsJanToMar1900, kUSecsPerDay, and STATIC_QUAL.

Referenced by ExtractFromTime().

85  {
86  STATIC_QUAL const uint32_t cumulative_month_epoch_starts[kMonsPerYear] = {0,
87  2678400,
88  5270400,
89  7948800,
90  10540800,
91  13219200,
92  15897600,
93  18489600,
94  21168000,
95  23760000,
96  26438400,
97  29116800};
98  uint32_t seconds_march_1900 = lcltime + kEpochOffsetYear1900 - kSecsJanToMar1900;
99  uint32_t seconds_past_4year_period = seconds_march_1900 % kSecondsPer4YearCycle;
100  uint32_t year_seconds_past_4year_period =
101  (seconds_past_4year_period / kSecondsPerNonLeapYear) * kSecondsPerNonLeapYear;
102  if (seconds_past_4year_period >=
103  kSecondsPer4YearCycle - kUSecsPerDay) { // if we are in Feb 29th
104  year_seconds_past_4year_period -= kSecondsPerNonLeapYear;
105  }
106  uint32_t seconds_past_march =
107  seconds_past_4year_period - year_seconds_past_4year_period;
108  uint32_t month =
109  seconds_past_march / (30 * kUSecsPerDay); // Will make the correct month either be
110  // the guessed month or month before
111  month = month <= 11 ? month : 11;
112  if (cumulative_month_epoch_starts[month] > seconds_past_march) {
113  month--;
114  }
115  return (month + 2) % 12 + 1;
116 }
static constexpr uint32_t kSecsJanToMar1900
static constexpr uint32_t kUSecsPerDay
#define STATIC_QUAL
static constexpr uint32_t kEpochOffsetYear1900
static constexpr uint32_t kSecondsPer4YearCycle
static constexpr uint32_t kSecondsPerNonLeapYear
static constexpr int32_t kMonsPerYear
+ Here is the caller graph for this function:

◆ extract_nanosecond()

DEVICE int64_t extract_nanosecond ( const int64_t  lcltime)

Definition at line 59 of file ExtractFromTime.cpp.

References kNanoSecsPerSec, and kSecsPerMin.

Referenced by ExtractFromTime().

59  {
60  return lcltime % (kSecsPerMin * kNanoSecsPerSec);
61 }
static constexpr int64_t kSecsPerMin
static constexpr int64_t kNanoSecsPerSec
+ Here is the caller graph for this function:

◆ extract_quarter_fast()

DEVICE int32_t extract_quarter_fast ( const int64_t  lcltime)

Definition at line 118 of file ExtractFromTime.cpp.

References kEpochOffsetYear1900, kSecondsPer4YearCycle, kSecondsPerNonLeapYear, kSecsJanToMar1900, kSecsPerDay, kUSecsPerDay, and STATIC_QUAL.

Referenced by ExtractFromTime().

118  {
119  STATIC_QUAL const uint32_t cumulative_quarter_epoch_starts[4] = {
120  0, 7776000, 15638400, 23587200};
121  STATIC_QUAL const uint32_t cumulative_quarter_epoch_starts_leap_year[4] = {
122  0, 7862400, 15724800, 23673600};
123  uint32_t seconds_1900 = lcltime + kEpochOffsetYear1900;
124  uint32_t leap_years = (seconds_1900 - kSecsJanToMar1900) / kSecondsPer4YearCycle;
125  uint32_t year = (seconds_1900 - leap_years * kSecsPerDay) / kSecondsPerNonLeapYear;
126  uint32_t base_year_leap_years = (year - 1) / 4;
127  uint32_t base_year_seconds =
128  year * kSecondsPerNonLeapYear + base_year_leap_years * kUSecsPerDay;
129  bool is_leap_year = year % 4 == 0 && year != 0;
130  const uint32_t* quarter_offsets = is_leap_year
131  ? cumulative_quarter_epoch_starts_leap_year
132  : cumulative_quarter_epoch_starts;
133  uint32_t partial_year_seconds = seconds_1900 % base_year_seconds;
134  uint32_t quarter = partial_year_seconds / (90 * kUSecsPerDay);
135  quarter = quarter <= 3 ? quarter : 3;
136  if (quarter_offsets[quarter] > partial_year_seconds) {
137  quarter--;
138  }
139  return quarter + 1;
140 }
static constexpr int64_t kSecsPerDay
static constexpr uint32_t kSecsJanToMar1900
static constexpr uint32_t kUSecsPerDay
#define STATIC_QUAL
static constexpr uint32_t kEpochOffsetYear1900
static constexpr uint32_t kSecondsPer4YearCycle
static constexpr uint32_t kSecondsPerNonLeapYear
+ Here is the caller graph for this function:

◆ extract_quarterday()

DEVICE int32_t extract_quarterday ( const int64_t  lcltime)

Definition at line 79 of file ExtractFromTime.cpp.

References kSecsPerQuarterDay.

Referenced by ExtractFromTime().

79  {
80  int64_t quarterdays;
81  quarterdays = lcltime / kSecsPerQuarterDay;
82  return static_cast<int32_t>(quarterdays % 4) + 1;
83 }
static constexpr int64_t kSecsPerQuarterDay
+ Here is the caller graph for this function:

◆ extract_second()

DEVICE int32_t extract_second ( const int64_t  lcltime)

Definition at line 47 of file ExtractFromTime.cpp.

References kSecsPerMin.

Referenced by ExtractFromTime().

47  {
48  return static_cast<int32_t>(lcltime % kSecsPerMin);
49 }
static constexpr int64_t kSecsPerMin
+ Here is the caller graph for this function:

◆ extract_year_fast()

DEVICE int32_t extract_year_fast ( const int64_t  lcltime)

Definition at line 142 of file ExtractFromTime.cpp.

References kEpochOffsetYear1900, kSecondsPer4YearCycle, kSecondsPerNonLeapYear, kSecsJanToMar1900, and kUSecsPerDay.

Referenced by ExtractFromTime().

142  {
143  const uint32_t seconds_1900 = lcltime + kEpochOffsetYear1900;
144  const uint32_t leap_years = (seconds_1900 - kSecsJanToMar1900) / kSecondsPer4YearCycle;
145  const uint32_t year =
146  (seconds_1900 - leap_years * kUSecsPerDay) / kSecondsPerNonLeapYear + 1900;
147  return year;
148 }
static constexpr uint32_t kSecsJanToMar1900
static constexpr uint32_t kUSecsPerDay
static constexpr uint32_t kEpochOffsetYear1900
static constexpr uint32_t kSecondsPer4YearCycle
static constexpr uint32_t kSecondsPerNonLeapYear
+ Here is the caller graph for this function:

◆ ExtractFromTime()

NEVER_INLINE DEVICE int64_t ExtractFromTime ( ExtractField  field,
const int64_t  timeval 
)

Definition at line 247 of file ExtractFromTime.cpp.

References extract_dow(), extract_hour(), extract_microsecond(), extract_millisecond(), extract_minute(), extract_month_fast(), extract_nanosecond(), extract_quarter_fast(), extract_quarterday(), extract_second(), extract_year_fast(), gmtime_r_newlib(), kDAY, kDOW, kDOY, kEPOCH, kEpochOffsetYear1900, kHOUR, kISODOW, kMICROSECOND, kMILLISECOND, kMINUTE, kMONTH, kNANOSECOND, kQUARTER, kQUARTERDAY, kSECOND, kWEEK, and kYEAR.

Referenced by ExtractFromTimeNullable(), getExpressionRange(), and DateTimeTranslator::getExtractFromTimeConstantValue().

248  {
249  // We have fast paths for the 5 fields below - do not need to do full gmtime
250  switch (field) {
251  case kEPOCH:
252  return timeval;
253  case kQUARTERDAY:
254  return extract_quarterday(timeval);
255  case kHOUR:
256  return extract_hour(timeval);
257  case kMINUTE:
258  return extract_minute(timeval);
259  case kSECOND:
260  return extract_second(timeval);
261  case kMILLISECOND:
262  return extract_millisecond(timeval);
263  case kMICROSECOND:
264  return extract_microsecond(timeval);
265  case kNANOSECOND:
266  return extract_nanosecond(timeval);
267  case kDOW:
268  return extract_dow(timeval);
269  case kISODOW: {
270  int64_t dow = extract_dow(timeval);
271  return (dow == 0 ? 7 : dow);
272  }
273  case kMONTH: {
274  if (timeval >= 0L && timeval <= UINT32_MAX - kEpochOffsetYear1900) {
275  return extract_month_fast(timeval);
276  }
277  break;
278  }
279  case kQUARTER: {
280  if (timeval >= 0L && timeval <= UINT32_MAX - kEpochOffsetYear1900) {
281  return extract_quarter_fast(timeval);
282  }
283  break;
284  }
285  case kYEAR: {
286  if (timeval >= 0L && timeval <= UINT32_MAX - kEpochOffsetYear1900) {
287  return extract_year_fast(timeval);
288  }
289  break;
290  }
291  default:
292  break;
293  }
294 
295  tm tm_struct;
296  gmtime_r_newlib(timeval, tm_struct);
297  switch (field) {
298  case kYEAR:
299  return 1900 + tm_struct.tm_year;
300  case kQUARTER:
301  return (tm_struct.tm_mon) / 3 + 1;
302  case kMONTH:
303  return tm_struct.tm_mon + 1;
304  case kDAY:
305  return tm_struct.tm_mday;
306  case kDOY:
307  return tm_struct.tm_yday + 1;
308  case kWEEK: {
309  int32_t doy = tm_struct.tm_yday; // numbered from 0
310  int32_t dow = extract_dow(timeval) + 1; // use Sunday 1 - Saturday 7
311  int32_t week = (doy / 7) + 1;
312  // now adjust for offset at start of year
313  // S M T W T F S
314  // doy 0 1 2 3 4
315  // doy 5 6
316  // mod 5 6 0 1 2 3 4
317  // dow 1 2 3 4 5 6 7
318  // week 2 2 1 1 1 1 1
319  if (dow > (doy % 7)) {
320  return week;
321  }
322  return week + 1;
323  }
324  default:
325 #ifdef __CUDACC__
326  return -1;
327 #else
328  abort();
329 #endif
330  }
331 }
NEVER_INLINE DEVICE int32_t extract_hour(const int64_t lcltime)
DEVICE int32_t extract_quarter_fast(const int64_t lcltime)
DEVICE int64_t extract_nanosecond(const int64_t lcltime)
static constexpr uint32_t kEpochOffsetYear1900
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
Definition: JsonAccessors.h:31
DEVICE int32_t extract_dow(const int64_t lcltime)
DEVICE int32_t extract_second(const int64_t lcltime)
DEVICE int64_t extract_millisecond(const int64_t lcltime)
DEVICE tm gmtime_r_newlib(const int64_t lcltime, tm &res)
DEVICE int32_t extract_quarterday(const int64_t lcltime)
DEVICE int32_t extract_minute(const int64_t lcltime)
DEVICE int32_t extract_month_fast(const int64_t lcltime)
DEVICE int64_t extract_microsecond(const int64_t lcltime)
DEVICE int32_t extract_year_fast(const int64_t lcltime)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ExtractFromTimeNullable()

DEVICE int64_t ExtractFromTimeNullable ( ExtractField  field,
const int64_t  timeval,
const int64_t  null_val 
)

Definition at line 333 of file ExtractFromTime.cpp.

References ExtractFromTime().

335  {
336  if (timeval == null_val) {
337  return null_val;
338  }
339  return ExtractFromTime(field, timeval);
340 }
const rapidjson::Value & field(const rapidjson::Value &obj, const char field[]) noexcept
Definition: JsonAccessors.h:31
NEVER_INLINE DEVICE int64_t ExtractFromTime(ExtractField field, const int64_t timeval)
+ Here is the call graph for this function:

◆ gmtime_r_newlib()

DEVICE tm gmtime_r_newlib ( const int64_t  lcltime,
tm &  res 
)

Definition at line 150 of file ExtractFromTime.cpp.

References kDaysInFebruary, kDaysInJanuary, kDaysPer100Years, kDaysPer400Years, kDaysPer4Years, kDaysPerWeek, kDaysPerYear, kEpochAdjustedDays, kEpochAdjustedWDay, kEpochAdjustedYears, kMonsPerYear, kSecPerHour, kSecsPerDay, kSecsPerMin, kYearBase, and run-benchmark-import::res.

Referenced by DateTruncate(), and ExtractFromTime().

150  {
151  const int32_t month_lengths[2][kMonsPerYear] = {
152  {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
153  {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};
154  int64_t days, rem;
155  int32_t year, month, yearday, weekday;
156  int32_t years400, years100, years4, remainingyears;
157  int32_t yearleap;
158  const int32_t* ip;
159 
160  days = lcltime / kSecsPerDay - kEpochAdjustedDays;
161  rem = lcltime % kSecsPerDay;
162  if (rem < 0) {
163  rem += kSecsPerDay;
164  --days;
165  }
166 
167  /* compute hour, min, and sec */
168  res.tm_hour = static_cast<int32_t>(rem / kSecPerHour);
169  rem %= kSecPerHour;
170  res.tm_min = static_cast<int32_t>(rem / kSecsPerMin);
171  res.tm_sec = static_cast<int32_t>(rem % kSecsPerMin);
172 
173  /* compute day of week */
174  if ((weekday = ((kEpochAdjustedWDay + days) % kDaysPerWeek)) < 0) {
175  weekday += kDaysPerWeek;
176  }
177  res.tm_wday = weekday;
178 
179  /* compute year & day of year */
180  years400 = static_cast<int32_t>(days / kDaysPer400Years);
181  days -= years400 * kDaysPer400Years;
182  /* simplify by making the values positive */
183  if (days < 0) {
184  days += kDaysPer400Years;
185  --years400;
186  }
187 
188  years100 = static_cast<int32_t>(days / kDaysPer100Years);
189  if (years100 == 4) { /* required for proper day of year calculation */
190  --years100;
191  }
192  days -= years100 * kDaysPer100Years;
193  years4 = days / kDaysPer4Years;
194  days -= years4 * kDaysPer4Years;
195  remainingyears = days / kDaysPerYear;
196  if (remainingyears == 4) { /* required for proper day of year calculation */
197  --remainingyears;
198  }
199  days -= remainingyears * kDaysPerYear;
200 
201  year =
202  kEpochAdjustedYears + years400 * 400 + years100 * 100 + years4 * 4 + remainingyears;
203 
204  /* If remainingyears is zero, it means that the years were completely
205  * "consumed" by modulo calculations by 400, 100 and 4, so the year is:
206  * 1. a multiple of 4, but not a multiple of 100 or 400 - it's a leap year,
207  * 2. a multiple of 4 and 100, but not a multiple of 400 - it's not a leap
208  * year,
209  * 3. a multiple of 4, 100 and 400 - it's a leap year.
210  * If years4 is non-zero, it means that the year is not a multiple of 100 or
211  * 400 (case 1), so it's a leap year. If years100 is zero (and years4 is zero
212  * - due to short-circuiting), it means that the year is a multiple of 400
213  * (case 3), so it's also a leap year. */
214  yearleap = remainingyears == 0 && (years4 != 0 || years100 == 0);
215 
216  /* adjust back to 1st January */
217  yearday = days + kDaysInJanuary + kDaysInFebruary + yearleap;
218  if (yearday >= kDaysPerYear + yearleap) {
219  yearday -= kDaysPerYear + yearleap;
220  ++year;
221  }
222  res.tm_yday = yearday;
223  res.tm_year = year - kYearBase;
224 
225  /* Because "days" is the number of days since 1st March, the additional leap
226  * day (29th of February) is the last possible day, so it doesn't matter much
227  * whether the year is actually leap or not. */
228  ip = month_lengths[1];
229  month = 2;
230  while (days >= ip[month]) {
231  days -= ip[month];
232  if (++month >= kMonsPerYear) {
233  month = 0;
234  }
235  }
236  res.tm_mon = month;
237  res.tm_mday = days + 1;
238 
239  res.tm_isdst = 0;
240 
241  return res;
242 }
static constexpr int64_t kSecsPerDay
static constexpr int32_t kDaysPerYear
static constexpr int64_t kSecsPerMin
static constexpr int32_t kDaysInJanuary
static constexpr int32_t kYearBase
static constexpr int32_t kEpochAdjustedDays
static constexpr int32_t kDaysPerWeek
static constexpr int32_t kDaysInFebruary
static constexpr int32_t kEpochAdjustedYears
static constexpr int64_t kDaysPer400Years
static constexpr int64_t kSecPerHour
static constexpr int32_t kDaysPer4Years
static constexpr int32_t kEpochAdjustedWDay
static constexpr int32_t kMonsPerYear
static constexpr int64_t kDaysPer100Years
+ Here is the caller graph for this function: