简述
定义星期的枚举
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=((y−x)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+2∗month+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+2∗month+3∗(month+1)/5+year+year/4−year/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);
}
}