OmniSciDB  2e3a973ef4
misc.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2020 OmniSci, 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 // Credits: Howard Hinnant for open source date calculations.
18 
19 #include "misc.h"
20 
21 #include <cstdio>
22 
23 namespace shared {
24 
25 size_t formatDate(char* buf, size_t const max, int64_t const unixtime) {
26  DivUMod const div_day = divUMod(unixtime, 24 * 60 * 60);
27  DivUMod const div_era = divUMod(div_day.quot - 11017, 146097);
28  unsigned const doe = static_cast<unsigned>(div_era.rem);
29  unsigned const yoe = (doe - doe / 1460 + doe / 36524 - (doe == 146096)) / 365;
30  unsigned const doy = doe - (365 * yoe + yoe / 4 - yoe / 100);
31  unsigned const moy = (5 * doy + 2) / 153;
32  static_assert(8 <= sizeof(long long)); // long long needed for snprintf()
33  long long const y = 2000 + div_era.quot * 400 + yoe + (9 < moy);
34  unsigned const m = moy + (9 < moy ? -9 : 3);
35  unsigned const d = doy - (153 * moy + 2) / 5 + 1;
36  int const len = snprintf(buf, max, "%04lld-%02u-%02u", y, m, d);
37  if (0 <= len && static_cast<size_t>(len) < max) {
38  return static_cast<size_t>(len);
39  }
40  return 0;
41 }
42 
43 size_t formatDateTime(char* buf,
44  size_t const max,
45  int64_t const timestamp,
46  int const dimension) {
47  constexpr int pow10[10]{
48  1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000};
49  DivUMod const div_hip = divUMod(timestamp, pow10[dimension]);
50  DivUMod const div_day = divUMod(div_hip.quot, 24 * 60 * 60);
51  DivUMod const div_era = divUMod(div_day.quot - 11017, 146097);
52  unsigned const doe = static_cast<unsigned>(div_era.rem);
53  unsigned const yoe = (doe - doe / 1460 + doe / 36524 - (doe == 146096)) / 365;
54  unsigned const doy = doe - (365 * yoe + yoe / 4 - yoe / 100);
55  unsigned const moy = (5 * doy + 2) / 153;
56  static_assert(8 <= sizeof(long long)); // long long needed for snprintf()
57  long long const y = 2000 + div_era.quot * 400 + yoe + (9 < moy);
58  unsigned const m = moy + (9 < moy ? -9 : 3);
59  unsigned const d = doy - (153 * moy + 2) / 5 + 1;
60  unsigned const minutes = static_cast<unsigned>(div_day.rem) / 60;
61  unsigned const ss = div_day.rem % 60;
62  unsigned const hh = minutes / 60;
63  unsigned const mm = minutes % 60;
64  int const len =
65  snprintf(buf, max, "%04lld-%02u-%02u %02u:%02u:%02u", y, m, d, hh, mm, ss);
66  if (0 <= len && static_cast<size_t>(len) < max) {
67  if (dimension) {
68  int const len_frac = snprintf(
69  buf + len, max - len, ".%0*d", dimension, static_cast<int>(div_hip.rem));
70  if (0 <= len_frac && static_cast<size_t>(len + len_frac) < max) {
71  return static_cast<size_t>(len + len_frac);
72  }
73  } else {
74  return static_cast<size_t>(len);
75  }
76  }
77  return 0;
78 }
79 
80 size_t formatHMS(char* buf, size_t const max, int64_t const unixtime) {
81  unsigned const seconds = static_cast<unsigned>(unsignedMod(unixtime, 24 * 60 * 60));
82  unsigned const minutes = seconds / 60;
83  unsigned const ss = seconds % 60;
84  unsigned const hh = minutes / 60;
85  unsigned const mm = minutes % 60;
86  int const len = snprintf(buf, max, "%02u:%02u:%02u", hh, mm, ss);
87  if (0 <= len && static_cast<size_t>(len) < max) {
88  return static_cast<size_t>(len);
89  }
90  return 0;
91 }
92 
93 } // namespace shared
int64_t quot
Definition: misc.h:123
size_t formatDateTime(char *buf, size_t const max, int64_t const timestamp, int const dimension)
Definition: misc.cpp:43
size_t formatHMS(char *buf, size_t const max, int64_t const unixtime)
Definition: misc.cpp:80
size_t formatDate(char *buf, size_t const max, int64_t const unixtime)
Definition: misc.cpp:25
uint64_t unsignedMod(int64_t num, int64_t den)
Definition: misc.h:138
int64_t rem
Definition: misc.h:124
DivUMod divUMod(int64_t num, int64_t den)
Definition: misc.h:128