muduo date

文章目录
  1. 1. 参考资料
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#ifndef MUDUO_BASE_DATE_H
#define MUDUO_BASE_DATE_H

#include "muduo/base/copyable.h"
#include "muduo/base/Types.h"

struct tm;

namespace muduo
{

///
/// Date in Gregorian calendar.
///
/// This class is immutable.
/// It's recommended to pass it by value, since it's passed in register on x64.
///
class Date : public muduo::copyable
// public boost::less_than_comparable<Date>,
// public boost::equality_comparable<Date>
{
public:

struct YearMonthDay
{
int year; // [1900..2500]
int month; // [1..12]
int day; // [1..31]
};

static const int kDaysPerWeek = 7;
static const int kJulianDayOf1970_01_01;

///
/// Constucts an invalid Date.
///
Date()
: julianDayNumber_(0)
{}

///
/// Constucts a yyyy-mm-dd Date.
///
/// 1 <= month <= 12
Date(int year, int month, int day);

///
/// Constucts a Date from Julian Day Number.
///
explicit Date(int julianDayNum)
: julianDayNumber_(julianDayNum)
{}

///
/// Constucts a Date from struct tm
///
explicit Date(const struct tm&);

// default copy/assignment/dtor are Okay

void swap(Date& that)
{
std::swap(julianDayNumber_, that.julianDayNumber_);
}

bool valid() const { return julianDayNumber_ > 0; }

///
/// Converts to yyyy-mm-dd format.
///
string toIsoString() const;

struct YearMonthDay yearMonthDay() const;

int year() const
{
return yearMonthDay().year;
}

int month() const
{
return yearMonthDay().month;
}

int day() const
{
return yearMonthDay().day;
}

// [0, 1, ..., 6] => [Sunday, Monday, ..., Saturday ]
int weekDay() const
{
return (julianDayNumber_+1) % kDaysPerWeek;
}

int julianDayNumber() const { return julianDayNumber_; }

private:
int julianDayNumber_;
};

inline bool operator<(Date x, Date y)
{
return x.julianDayNumber() < y.julianDayNumber();
}

inline bool operator==(Date x, Date y)
{
return x.julianDayNumber() == y.julianDayNumber();
}

} // namespace muduo

#endif // MUDUO_BASE_DATE_H
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
namespace muduo
{
namespace detail
{

char require_32_bit_integer_at_least[sizeof(int) >= sizeof(int32_t) ? 1 : -1];

// algorithm and explanation see:
// http://www.faqs.org/faqs/calendars/faq/part2/
// http://blog.csdn.net/Solstice

int getJulianDayNumber(int year, int month, int day)
{
(void) require_32_bit_integer_at_least; // no warning please
int a = (14 - month) / 12;
int y = year + 4800 - a;
int m = month + 12 * a - 3;
return day + (153*m + 2) / 5 + y*365 + y/4 - y/100 + y/400 - 32045;
}

struct Date::YearMonthDay getYearMonthDay(int julianDayNumber)
{
int a = julianDayNumber + 32044;
int b = (4 * a + 3) / 146097;
int c = a - ((b * 146097) / 4);
int d = (4 * c + 3) / 1461;
int e = c - ((1461 * d) / 4);
int m = (5 * e + 2) / 153;
Date::YearMonthDay ymd;
ymd.day = e - ((153 * m + 2) / 5) + 1;
ymd.month = m + 3 - 12 * (m / 10);
ymd.year = b * 100 + d - 4800 + (m / 10);
return ymd;
}
} // namespace detail
const int Date::kJulianDayOf1970_01_01 = detail::getJulianDayNumber(1970, 1, 1);
} // namespace muduo

using namespace muduo;
using namespace muduo::detail;

Date::Date(int y, int m, int d)
: julianDayNumber_(getJulianDayNumber(y, m, d))
{
}

Date::Date(const struct tm& t)
: julianDayNumber_(getJulianDayNumber(
t.tm_year+1900,
t.tm_mon+1,
t.tm_mday))
{
}

string Date::toIsoString() const
{
char buf[32];
YearMonthDay ymd(yearMonthDay());
snprintf(buf, sizeof buf, "%4d-%02d-%02d", ymd.year, ymd.month, ymd.day);
return buf;
}

Date::YearMonthDay Date::yearMonthDay() const
{
return getYearMonthDay(julianDayNumber_);
}

参考资料