OmniSciDB  c07336695a
timegm.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2001-2006, NLnet Labs. All rights reserved.
3  *
4  * This software is open source.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * Redistributions of source code must retain the above copyright notice,
11  * this list of conditions and the following disclaimer.
12  *
13  * Redistributions in binary form must reproduce the above copyright notice,
14  * this list of conditions and the following disclaimer in the documentation
15  * and/or other materials provided with the distribution.
16  *
17  * Neither the name of the NLNET LABS nor the names of its contributors may
18  * be used to endorse or promote products derived from this software without
19  * specific prior written permission.
20 
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
25  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 #include "TimeGM.h"
35 #include <boost/algorithm/string.hpp>
36 #include <cmath>
37 #include <ctime>
38 
39 /* Number of days per month (except for February in leap years). */
40 // static const int monoff[] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
41 
42 int TimeGM::is_leap_year(int year) {
43  return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
44 }
45 
46 int TimeGM::leap_days(int y1, int y2) {
47  --y1;
48  --y2;
49  return (y2 / 4 - y1 / 4) - (y2 / 100 - y1 / 100) + (y2 / 400 - y1 / 400);
50 }
51 
52 time_t TimeGM::parse_fractional_seconds(uint64_t sfrac,
53  const int ntotal,
54  const SQLTypeInfo& ti) {
55  int dimen = ti.get_dimension();
56  int nfrac = log10(sfrac) + 1;
57  if (ntotal - nfrac > dimen) {
58  return 0;
59  }
60  if (ntotal >= 0 && ntotal < dimen) {
61  sfrac *= pow(10, dimen - ntotal);
62  } else if (ntotal > dimen) {
63  sfrac /= pow(10, ntotal - dimen);
64  }
65  return sfrac;
66 }
67 
68 time_t TimeGM::parse_meridians(const time_t& timeval,
69  const char* p,
70  const uint32_t& hour,
71  const SQLTypeInfo& ti) {
72  char meridies[20];
73  if (sscanf(p, "%*d %s", meridies) != 1) {
74  if (sscanf(p, "%s", meridies) != 1) {
75  return timeval;
76  };
77  }
78  if (boost::iequals(std::string(meridies), "pm") ||
79  boost::iequals(std::string(meridies), "p.m.") ||
80  boost::iequals(std::string(meridies), "p.m")) {
81  return hour == 12 ? timeval
82  : timeval + kSecsPerHalfDay *
83  static_cast<int64_t>(pow(10, ti.get_dimension()));
84  } else if (boost::iequals(std::string(meridies), "am") ||
85  boost::iequals(std::string(meridies), "a.m.") ||
86  boost::iequals(std::string(meridies), "a.m")) {
87  return hour == 12 ? timeval - kSecsPerHalfDay *
88  static_cast<int64_t>(pow(10, ti.get_dimension()))
89  : timeval;
90  } else {
91  return timeval;
92  }
93 }
94 
95 /*
96  * Code adapted from Python 2.4.1 sources (Lib/calendar.py).
97  */
98 time_t TimeGM::my_timegm_days(const struct tm* tm) {
99  int32_t year;
100  time_t days;
101  year = 1900 + tm->tm_year;
102  days = 365 * (year - 1970) + leap_days(1970, year);
103  days += monoff[tm->tm_mon];
104  if (tm->tm_mon > 1 && is_leap_year(year)) {
105  ++days;
106  }
107  days += tm->tm_mday - 1;
108  return days;
109 }
110 
111 time_t TimeGM::my_timegm(const struct tm* tm) {
112  time_t days;
113  time_t hours;
114  time_t minutes;
115  time_t seconds;
116 
117  days = my_timegm_days(tm);
118  hours = days * 24 + tm->tm_hour;
119  minutes = hours * 60 + tm->tm_min;
120  seconds = minutes * 60 + tm->tm_sec;
121 
122  seconds -= tm->tm_gmtoff;
123 
124  return seconds;
125 }
126 
127 time_t TimeGM::my_timegm(const struct tm* tm, const time_t& fsc, const SQLTypeInfo& ti) {
128  time_t sec;
129 
130  sec = my_timegm(tm) * static_cast<int64_t>(pow(10, ti.get_dimension()));
131  sec += fsc;
132 
133  return sec;
134 }
int leap_days(int y1, int y2)
Definition: timegm.cpp:46
int is_leap_year(int year)
Definition: timegm.cpp:42
HOST DEVICE int get_dimension() const
Definition: sqltypes.h:321
time_t parse_meridians(const time_t &timeval, const char *p, const uint32_t &hour, const SQLTypeInfo &ti)
Definition: timegm.cpp:68
static constexpr int64_t kSecsPerHalfDay
time_t my_timegm(const struct tm *tm)
Definition: timegm.cpp:111
const int monoff[12]
Definition: TimeGM.h:45
time_t parse_fractional_seconds(uint64_t sfrac, const int ntotal, const SQLTypeInfo &ti)
Definition: timegm.cpp:52
time_t my_timegm_days(const struct tm *tm)
Definition: timegm.cpp:98