MiniOB 1
MiniOB is one mini database, helping developers to learn how database works.
载入中...
搜索中...
未找到
datetime.h
1/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved.
2miniob is licensed under Mulan PSL v2.
3You can use this software according to the terms and conditions of the Mulan PSL v2.
4You may obtain a copy of Mulan PSL v2 at:
5 http://license.coscl.org.cn/MulanPSL2
6THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
7EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
8MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
9See the Mulan PSL v2 for more details. */
10
11//
12// Created by Longda on 2010
13//
14
15#pragma once
16
17#include <math.h>
18#include <stdint.h>
19#include <sys/time.h>
20#include <time.h>
21
22#include <iomanip>
23#include <iostream>
24
25#include "common/defs.h"
26#include "common/lang/string.h"
27
28namespace common {
29
30/*
31 * \brief Date and time are represented as integer for ease of
32 * calculation and comparison.
33 *
34 * Julian day number is the integer number of days that have elapsed since
35 * the defined as noon Universal Time (UT) Monday, January 1, 4713 BC.
36 *
37 * Date and Time stored as a Julian day number and number of
38 * milliseconds since midnight. Does not perform any timezone
39 * calculations. All magic numbers and related calculations
40 * have been taken from:
41 *
42 * \sa http://www.faqs.org/faqs/calendars.faq
43 * \sa http://scienceworld.wolfram.com/astronomy/JulianDate.html
44 * \sa http://scienceworld.wolfram.com/astronomy/GregorianCalendar.html
45 * \sa http://scienceworld.wolfram.com/astronomy/Weekday.html
46 */
47
49{
50 int m_date;
51 int m_time;
52
53 enum
54 {
55 SECONDS_PER_DAY = 86400,
56 SECONDS_PER_HOUR = 3600,
57 SECONDS_PER_MIN = 60,
58 MINUTES_PER_HOUR = 60,
59
60 MILLIS_PER_DAY = 86400000,
61 MILLIS_PER_HOUR = 3600000,
62 MILLIS_PER_MIN = 60000,
63 MILLIS_PER_SEC = 1000,
64
65 // time_t epoch (1970-01-01) as a Julian date
66 JULIAN_19700101 = 2440588
67 };
68 enum
69 {
70 MON_JAN = 1,
71 MON_FEB = 2,
72 MON_MAR = 3,
73 MON_APR = 4,
74 MON_MAY = 5,
75 MON_JUN = 6,
76 MON_JUL = 7,
77 MON_AUG = 8,
78 MON_SEP = 9,
79 MON_OCT = 10,
80 MON_NOV = 11,
81 MON_DEC = 12
82 };
83
84 // Default constructor - initializes to zero
85 DateTime() : m_date(0), m_time(0) {}
86
87 // Construct from a Julian day number and time in millis
88 DateTime(int date, int time) : m_date(date), m_time(time) {}
89
90 // Construct from the specified components
91 DateTime(int year, int month, int day, int hour, int minute, int second, int millis)
92 {
93 m_date = julian_date(year, month, day);
94 m_time = make_hms(hour, minute, second, millis);
95 }
96
97 // Construct from the xml datetime format
98 DateTime(string &xml_time);
99
100 // check whether a string is valid with a xml datetime format
101 static bool is_valid_xml_datetime(const string &str);
102
103 // Load the referenced values with the year, month and day
104 // portions of the date in a single operation
105 inline void get_ymd(int &year, int &month, int &day) const { get_ymd(m_date, year, month, day); }
106
107 // Load the referenced values with the hour, minute, second and
108 // millisecond portions of the time in a single operation
109 inline void get_hms(int &hour, int &minute, int &second, int &millis) const
110 {
111 int ticks = m_time / MILLIS_PER_SEC;
112 hour = ticks / SECONDS_PER_HOUR;
113 minute = (ticks / SECONDS_PER_MIN) % MINUTES_PER_HOUR;
114 second = ticks % SECONDS_PER_MIN;
115 millis = m_time % MILLIS_PER_SEC;
116 }
117
118 // Convert the DateTime to a time_t. Note that this operation
119 // can overflow on 32-bit platforms when we go beyond year 2038.
120 inline time_t to_time_t() const { return (SECONDS_PER_DAY * (m_date - JULIAN_19700101) + m_time / MILLIS_PER_SEC); }
121
122 // Convert the DateTime to a struct tm which is in UTC
123 tm to_tm() const
124 {
125 int year, month, day;
126 int hour, minute, second, millis;
127 tm result = {0};
128
129 get_ymd(year, month, day);
130 get_hms(hour, minute, second, millis);
131
132 result.tm_year = year - 1900;
133 result.tm_mon = month - 1;
134 result.tm_mday = day;
135 result.tm_hour = hour;
136 result.tm_min = minute;
137 result.tm_sec = second;
138 result.tm_isdst = -1;
139
140 return result;
141 }
142
143 // Set the date portion of the DateTime
144 void set_ymd(int year, int month, int day) { m_date = julian_date(year, month, day); }
145
146 // Set the time portion of the DateTime
147 void set_hms(int hour, int minute, int second, int millis) { m_time = make_hms(hour, minute, second, millis); }
148
149 // Clear the date portion of the DateTime
150 void clear_date() { m_date = 0; }
151
152 // Clear the time portion of the DateTime
153 void clear_time() { m_time = 0; }
154
155 // Set the internal date and time members
156 void set(int date, int time)
157 {
158 m_date = date;
159 m_time = time;
160 }
161
162 // Initialize from another DateTime
163 void set(const DateTime &other)
164 {
165 m_date = other.m_date;
166 m_time = other.m_time;
167 }
168
169 // Add a number of seconds to this
170 void operator+=(int seconds)
171 {
172 int d = seconds / SECONDS_PER_DAY;
173 int s = seconds % SECONDS_PER_DAY;
174
175 m_date += d;
176 m_time += s * MILLIS_PER_SEC;
177
178 if (m_time > MILLIS_PER_DAY) {
179 m_date++;
180 m_time %= MILLIS_PER_DAY;
181 } else if (m_time < 0) {
182 m_date--;
183 m_time += MILLIS_PER_DAY;
184 }
185 }
186
187 // Return date and time as a string in XML Schema Date-Time format
188 string to_xml_date_time();
189
190 // Return time_t from XML schema date-time format.
191 time_t str_to_time_t(string &xml_str);
192
193 // Return xml time str from time_t.
194 string time_t_to_xml_str(time_t timet);
195
196 // Return time_t str from time_t.
197 string time_t_to_str(int timet);
198
199 // Return time_t string from XML schema date-time format.
200 string str_to_time_t_str(string &xml_str);
201
202 // Helper method to convert a broken down time to a number of
203 // milliseconds since midnight
204 static int make_hms(int hour, int minute, int second, int millis)
205 {
206 return MILLIS_PER_SEC * (SECONDS_PER_HOUR * hour + SECONDS_PER_MIN * minute + second) + millis;
207 }
208
209 // Return the current wall-clock time as a DateTime
210 static DateTime now();
211
212 // Return the current wall-clock time as time_t
213 time_t nowtimet();
214
215 // Convert a time_t and optional milliseconds to a DateTime
216 static DateTime from_time_t(time_t t, int millis = 0)
217 {
218 struct tm tmbuf;
219 tm *tm = gmtime_r(&t, &tmbuf);
220 return from_tm(*tm, millis);
221 }
222
223 // Convert a tm and optional milliseconds to a DateTime. \note
224 // the tm structure is assumed to contain a date specified in UTC
225 static DateTime from_tm(const tm &tm, int millis = 0)
226 {
227 return DateTime(
228 julian_date(tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday), make_hms(tm.tm_hour, tm.tm_min, tm.tm_sec, millis));
229 }
230
231 // Helper method to calculate a Julian day number.
232 static int julian_date(int year, int month, int day)
233 {
234 int a = (14 - month) / 12;
235 int y = year + 4800 - a;
236 int m = month + 12 * a - 3;
237 return (day + int((153 * m + 2) / 5) + y * 365 + int(y / 4) - int(y / 100) + int(y / 400) - 32045);
238 }
239
240 // Convert a Julian day number to a year, month and day
241 static void get_ymd(int jday, int &year, int &month, int &day)
242 {
243 int a = jday + 32044;
244 int b = (4 * a + 3) / 146097;
245 int c = a - int((b * 146097) / 4);
246 int d = (4 * c + 3) / 1461;
247 int e = c - int((1461 * d) / 4);
248 int m = (5 * e + 2) / 153;
249 day = e - int((153 * m + 2) / 5) + 1;
250 month = m + 3 - 12 * int(m / 10);
251 year = b * 100 + d - 4800 + int(m / 10);
252 }
253
254 // Return a human-friendly string representation of the timestamp,
255 // expressed in terms of the local timezone
256 string to_string_local()
257 {
258 const time_t tt = to_time_t();
259 // 'man asctime' specifies that buffer must be at least 26 bytes
260 char buffer[32];
261 struct tm tm;
262 asctime_r(localtime_r(&tt, &tm), &(buffer[0]));
263 string s(buffer);
264 return s;
265 }
266
267 // Return a human-friendly string representation of the timestamp,
268 // expressed in terms of Coordinated Universal Time (UTC)
269 string to_string_utc()
270 {
271 const time_t tt = to_time_t();
272 // 'man asctime' specifies that buffer must be at least 26 bytes
273 char buffer[32];
274 struct tm tm;
275 asctime_r(gmtime_r(&tt, &tm), &(buffer[0]));
276 string s(buffer);
277 return s;
278 }
279
280 // add duration to this time
281 time_t add_duration(string xml_dur);
282
283 // add duration to this time
284 void add_duration_date_time(string xml_dur);
285
286 // add duration to this time
287 int max_day_in_month_for(int year, int month);
288
289 // parse the duration string and convert it to struct tm
290 void parse_duration(string dur_str, struct tm &tm_t);
291};
292
293inline bool operator==(const DateTime &lhs, const DateTime &rhs)
294{
295 return lhs.m_date == rhs.m_date && lhs.m_time == rhs.m_time;
296}
297
298inline bool operator!=(const DateTime &lhs, const DateTime &rhs) { return !(lhs == rhs); }
299
300inline bool operator<(const DateTime &lhs, const DateTime &rhs)
301{
302 if (lhs.m_date < rhs.m_date)
303 return true;
304 else if (lhs.m_date > rhs.m_date)
305 return false;
306 else if (lhs.m_time < rhs.m_time)
307 return true;
308 return false;
309}
310
311inline bool operator>(const DateTime &lhs, const DateTime &rhs) { return !(lhs == rhs || lhs < rhs); }
312
313inline bool operator<=(const DateTime &lhs, const DateTime &rhs) { return lhs == rhs || lhs < rhs; }
314
315inline bool operator>=(const DateTime &lhs, const DateTime &rhs) { return lhs == rhs || lhs > rhs; }
316
317// Calculate the difference between two DateTime values and return
318// the result as a number of seconds
319inline int operator-(const DateTime &lhs, const DateTime &rhs)
320{
321 return (DateTime::SECONDS_PER_DAY * (lhs.m_date - rhs.m_date) +
322 // Truncate the millis before subtracting
323 lhs.m_time / 1000 - rhs.m_time / 1000);
324}
325
326// Date and Time represented in UTC.
327class TimeStamp : public DateTime
328{
329public:
330 // Defaults to the current date and time
331 TimeStamp() : DateTime(DateTime::now()) {}
332
333 // Defaults to the current date
334 TimeStamp(int hour, int minute, int second, int millisecond = 0) : DateTime(DateTime::now())
335 {
336 set_hms(hour, minute, second, millisecond);
337 }
338
339 TimeStamp(int hour, int minute, int second, int date, int month, int year)
340 : DateTime(year, month, date, hour, minute, second, 0)
341 {}
342
343 TimeStamp(int hour, int minute, int second, int millisecond, int date, int month, int year)
344 : DateTime(year, month, date, hour, minute, second, millisecond)
345 {}
346
347 TimeStamp(time_t time, int millisecond = 0) : DateTime(from_time_t(time, millisecond)) {}
348
349 TimeStamp(const tm *time, int millisecond = 0) : DateTime(from_tm(*time, millisecond)) {}
350
351 void set_current() { set(DateTime::now()); }
352};
353
354// Time only represented in UTC.
355class Time : public DateTime
356{
357public:
358 // Defaults to the current time
359 Time() { set_current(); }
360
361 Time(const DateTime &val) : DateTime(val) { clear_date(); }
362
363 Time(int hour, int minute, int second, int millisecond = 0) { set_hms(hour, minute, second, millisecond); }
364
365 Time(time_t time, int millisecond = 0) : DateTime(from_time_t(time, millisecond)) { clear_date(); }
366
367 Time(const tm *time, int millisecond = 0) : DateTime(from_tm(*time, millisecond)) { clear_date(); }
368
369 // Set to the current time.
370 void set_current()
371 {
372 DateTime d = now();
373 m_time = d.m_time;
374 }
375};
376
377// Date only represented in UTC.
378class Date : public DateTime
379{
380public:
381 // Defaults to the current date
382 Date() { set_current(); }
383
384 Date(const DateTime &val) : DateTime(val) { clear_time(); }
385
386 Date(int date, int month, int year) : DateTime(year, month, date, 0, 0, 0, 0) {}
387
388 Date(long sec) : DateTime(sec / DateTime::SECONDS_PER_DAY, 0) {}
389
390 Date(const tm *time) : DateTime(from_tm(*time)) { clear_time(); }
391
392 // Set to the current time.
393 void set_current()
394 {
395 DateTime d = now();
396 m_date = d.m_date;
397 }
398};
399
400class Now
401{
402public:
403 static inline int64_t sec()
404 {
405 struct timeval tv;
406 gettimeofday(&tv, 0);
407 time_t sec = tv.tv_sec;
408 // Round up if necessary
409 if (tv.tv_usec > 500 * 1000)
410 sec++;
411 return sec;
412 }
413
414 static inline int64_t usec()
415 {
416 struct timeval tv;
417 gettimeofday(&tv, 0);
418 return (int64_t)tv.tv_sec * 1000000 + tv.tv_usec;
419 }
420
421 static inline int64_t msec()
422 {
423 struct timeval tv;
424 gettimeofday(&tv, 0);
425 int64_t msec = (int64_t)tv.tv_sec * 1000 + tv.tv_usec / 1000;
426 if (tv.tv_usec % 1000 >= 500)
427 msec++;
428 return msec;
429 }
430
431 static string unique();
432};
433
434} // namespace common
Definition: datetime.h:379
Definition: datetime.h:401
Definition: datetime.h:328
Definition: datetime.h:356
Definition: datetime.h:49
string to_xml_date_time()
Return date and time as a string in Xml Schema date-time format
Definition: datetime.cpp:125