源码
Date.h
#include "Copyable.h"
#include <time.h>
#include <string>
namespace muduo
{
class Date : public Copyable
{
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;
Date():julian_day_number_(0){}
explicit Date(int julianDayNum):julian_day_number_(julianDayNum){}
Date(int year,int month,int day);
explicit Date(const struct tm&);
void swap(Date& that)
{
std::swap(julian_day_number_,that.julian_day_number_);
}
bool valid() const {return julian_day_number_ > 0;}
//@ convert to yyyy-mm-dd format
std::string to_iso_string() const;
struct YearMonthDay year_month_day() const;
int year()const
{
return year_month_day().year;
}
int month()const
{
return year_month_day().month;
}
//@ [0,1...6] => [Sunday,Monday...Saturday]
int week_day() const
{
return (julian_day_number_ + 1) % kDaysPerWeek;
}
int julian_day_number() const
{
return julian_day_number_;
}
private:
int julian_day_number_;
};
inline bool operator<(Date x,Date y)
{
return x.julian_day_number() < y.julian_day_number();
}
inline bool operator==(Date x,Date y)
{
return x.julian_day_number() == y.julian_day_number();
}
}
Date.cc
#include "Date.h"
namespace muduo
{
namespace detail
{
char require_32_bit_interger_at_least[sizeof(int) >= sizeof(int32_t) ? 1 : -1];
//@ algorithm reference:http://www.faqs.org/faqs/calendars/faq/part2/
int get_julian_day_number(int year,int month,int day)
{
(void) require_32_bit_interger_at_least;
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 get_year_month_day(int julian_day_number)
{
int a = julian_day_number + 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;
}
}
const int Date::kJulianDayOf1970_01_01 = detail::get_julian_day_number(1970,1,1);
Date::Date(int year,int month,int day):julian_day_number_(detail::get_julian_day_number(year,month,day))
{
}
Date::Date(const struct tm& t):julian_day_number_(detail::get_julian_day_number(t.tm_year+1900,t.tm_mon+1,t .tm_mday))
{
}
std::string Date::to_iso_string() const
{
char buf[32];
YearMonthDay ymd(year_month_day());
snprintf(buf,sizeof(buf),"%04d-%02d-%02d",ymd.year,ymd.month,ymd.day);
return buf;
}
Date::YearMonthDay Date::year_month_day() const
{
return detail::get_year_month_day(julian_day_number_);
}
}