muduo 库解析之三:Date

源码

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_);
    }
}
上一篇:初中生C++笔记(二)


下一篇:循环队列--搬书问题