0
点赞
收藏
分享

微信扫一扫

算法 - 日期处理

目标践行者 2022-04-16 阅读 62
c++算法

简述

定义星期的枚举

namesapce dttm {

enum week_t
{
    Sunday = 7 % 7,
    Monday = 1 % 7,
    Tuesday = 2 % 7,
    Wednesday = 3 % 7,
    Thursday = 4 % 7,
    Friday = 5 % 7,
    Saturday = 6 % 7
};

}

计算其他日子的星期

知道今天是星期 y y y,知道一个日子距离今天 x x x天,那天是星期 z z z
如果是今天之后的日子 z = ( y + x ) m o d    7 z = (y + x) \mod 7 z=(y+x)mod7.
如果是今天之前的日子 z = ( ( y − x ) m o d    7 + 7 ) m o d    7 z = ((y - x) \mod 7 + 7) \mod 7 z=((yx)mod7+7)mod7

注:

计算今天的星期

知道年月日,计算昨天星期几
跟据蔡勒公式:
1752年9月3日之前:
w e e k = ( ( d a y + 2 ∗ m o n t h + 3 ∗ ( m o n t h + 1 ) / 5 + y e a r + y e a r / 4 + 5 ) m o d    7 + 1 ) m o d    7 week =((day + 2 * month + 3 * (month + 1) / 5 + year + year / 4 + 5) \mod 7 + 1) \mod 7 week=((day+2month+3(month+1)/5+year+year/4+5)mod7+1)mod7
1752年9月4日,及之后
w e e k = ( ( d a y + 2 ∗ m o n t h + 3 ∗ ( m o n t h + 1 ) / 5 + y e a r + y e a r / 4 − y e a r / 100 + y e a r / 400 ) m o d    7 + 1 ) m o d    7 week = ((day + 2 * month + 3 * (month + 1) / 5 + year + year / 4 - year / 100 + year / 400) \mod 7 + 1) \mod 7 week=((day+2month+3(month+1)/5+year+year/4year/100+year/400)mod7+1)mod7

日期相隔的天数

转成公历天数,再作减法即可

代码示例

#include <cinttypes>
#include <cmath>

namespace dttm
{
constexpr uint16_t DAYS = 365;
const uint8_t MONTHS[] =
{
    0,31,28,31,30,31,30,31,31,30,31,30,31
};

inline int leap(const int y)
{
    if(!y) return 0;
    return y/4 - y/100 + y/400;
}

constexpr bool isleap(const int year)
{
    return (year % 400 == 0) ||
           (year % 100 ) &&
           (year % 4 == 0);
}

struct datetime
{
    uint16_t year;
    uint8_t month;
    uint8_t day;
    uint8_t hour;
    uint8_t minute;
    uint8_t second;
    datetime(int Y,int M,int D,int h,int m,int s)
        :year(Y),month(M),day(D),hour(h),minute(m),second(s) {}
    datetime(int Y,int M,int D)
        :datetime(Y,M,D,0,0,0) {}
    datetime():datetime(1970,1,1) {}

    size_t days() const
    {
        size_t ans = (year - 1) * DAYS + leap(year - 1);
        for (int i = 0; i < month; ++i)
            ans += MONTHS[i];
        if(isleap(year) && month > 2) ++ans;
        ans += day;
        return ans;
    }

    size_t dist_day(const datetime& o) {
        return std::abs(this->days() - o.days());
    }

    bool operator == (const datetime& o) const
    {
        return (this->year == o.year) &&
               (this->month == o.month) &&
               (this->day == o.day) &&
               (this->hour == o.hour) &&
               (this->minute == o.minute) &&
               (this->second == o.second);
    }

    bool operator != (const datetime& o) const
    {
        return !(*this == o);
    }

    bool operator<(const datetime& o) const
    {
        if (this->year < o.year) return true;
        else if (this->year > o.year) return false;

        if (this->month < o.month) return true;
        else if (this->month > o.month) return false;

        if (this->day < o.day) return true;
        else if (this->day > o.day) return false;

        if (this->hour < o.hour) return true;
        else if (this->hour > o.hour) return false;

        if (this->minute < o.minute) return true;
        else if (this->minute > o.minute) return false;

        if (this->second < o.second) return true;
        else if (this->second > o.second) return false;

        return false;
    }

    bool operator <= (const datetime& o) const
    {
        return (*this < o) || (*this == o);
    }

    bool operator >= (const datetime& o) const
    {
        return !(*this < o);
    }

    bool operator > (const datetime& o) const
    {
        return !(*this <= o);
    }


};

enum week_t
{
    Sunday = 7 % 7,
    Monday = 1 % 7,
    Tuesday = 2 % 7,
    Wednesday = 3 % 7,
    Thursday = 4 % 7,
    Friday = 5 % 7,
    Saturday = 6 % 7
};



week_t next_week(const week_t today,const int dist)
{
    const int y = int(today);
    if (dist >= 0)
    {
        const int x = dist;
        return static_cast<week_t>((y + x) % 7);
    }
    else
    {
        const int x = -dist;
        return static_cast<week_t>(((y - x) % 7 + 7) % 7);
    }
}

week_t weekday(const datetime& date)
{
    int y = date.year;
    int m = date.month;
    int d = date.day;
    if (m == 1 || m == 2)
    {
        m +=12;
        --y;
    }
    int res = 0;
    if (date >= datetime(1752,9,3))
    {
        res =  (d + 2*m + 3*(m + 1)/5 + y + y/4 - y/100 + y/400) % 7;
    }
    else
    {
        res = (d + 2*m + 3*(m + 1)/5 + y + y/4 + 5) % 7;
    }
    return static_cast<week_t>((res + 1)%7);
}
}

举报

相关推荐

0 条评论