日期问题

求任意两个日期间的天数

思路

从公元元年(即1年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
115
#include <iostream>
using namespace std;
class Date //创建一个日期Date类
{
private: //数据成员
int year;
int month;
int day;
public: //成员函数
Date(); //构造函数
void setDate(); //输入日期
void isLeapYear(); //判断是否为闰年
int getSkip(Date date); //计算从公元元年(即1年1月1日)到给定日期的天数
void month1(int i, int &count); //闰年的12个月的天数
void month2(int i, int &count); //非闰年的12个月的天数
};
Date::Date() //构造函数的定义
{
year = 0;
month = 0;
day = 0;
}
void Date::setDate() //输入日期的函数定义
{
cin >> year;
cin >> month;
cin >> day;
}
void Date::isLeapYear() //判断是否为闰年的函数定义
{
if (year % 400 == 0 || year % 4 == 0 && year % 100 != 0)
cout << year << " is leap year." << endl;
else cout << year << " is not leap year." << endl;
}
void Date::month1(int i, int &count) //闰年的12个月的天数的函数定义
{
switch (i)
{
case 1:count += 31; break;
case 2:count += 29; break;
case 3:count += 31; break;
case 4:count += 30; break;
case 5:count += 31; break;
case 6:count += 30; break;
case 7:count += 31; break;
case 8:count += 31; break;
case 9:count += 30; break;
case 10:count += 31; break;
case 11:count += 30; break;
case 12:count += 31; break;
}
}
void Date::month2(int i, int &count) //非闰年的12个月的天数的函数定义
{
switch (i)
{
case 1:count += 31; break;
case 2:count += 28; break;
case 3:count += 31; break;
case 4:count += 30; break;
case 5:count += 31; break;
case 6:count += 30; break;
case 7:count += 31; break;
case 8:count += 31; break;
case 9:count += 30; break;
case 10:count += 31; break;
case 11:count += 30; break;
case 12:count += 31; break;
}
}
int Date::getSkip(Date date) //计算从公元元年(即1年1月1日)到给定日期的天数的函数定义
{
int i;
int year = date.year, month = date.month, day = date.day;
int count = 0; //count用来表示该日期到公元元年的天数差
for (i = 1; i < year; i++)
{
if ((i % 4 == 0 && i % 100 != 0) || (i % 400 == 0))
{
count += 366;
}
else
{
count += 365;
}
}
for (i = 1; i < month; i++)
{
if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))
{
month1(i, count);
}
else
{
month2(i, count);
}
}
count += day;
return count;
}
int main()
{
int date1_day = 0, date2_day = 0; //date1_day和 date2_day用来存储从从公元元年(即1年1月1日)到给定日期的天数
Date date1; //创建date1类
date1.setDate(); //输入类date1的日期
Date date2; //创建date2类
date2.setDate(); //输入类date2的日期
date1.isLeapYear(); //判断date1的日期是否是闰年
date2.isLeapYear(); //判断date2的日期是否是闰年
date1_day = date1.getSkip(date1);
date2_day = date2.getSkip(date2);
cout << "The skip of two date is " << abs(date1_day - date2_day) << endl;
return 0;
}

公元元年法

求两个日期相差的天数(从公元元年到一个日期的暴力求解法)

分析

首先考虑将日期转化成编号,使得编号差就是日期的天数差
对于y年m月d日来说,令其编号为从公元1年1月1日到这天(包括这天)的天数前y-1年的天数就是

1
(y-1)*365+(y-1)/4-(y-1)/100+(y-1)/400

第y年的前m-1个月的天数可以暴力求出(注意判断闰年的2月)第y年第m个月的天数就是d了。

代码

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
#include <iostream>
using namespace std;
bool isLeap(int x) //判断是否是闰年
{
if (x % 400 == 0)
return true;
if (x % 100 == 0)
return false;
if (x % 4 == 0)
return true;
return false;
}
long days(int y, int m, int d)
{
int num[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; //平年每月的天数 y--;
long ret = 365 * y + y / 4 - y / 100 + y / 400 + d;
for (int i = 1; i < m; i++)
{
ret += num[i];
if (i == 2 && isLeap(y + 1))
ret++; //符合闰年且月份大于2月
}
return ret;
}

int main()
{
int year1, month1, day1;
int year2, month2, day2;
cin >> year1 >> month1 >> day1;
cin >> year2 >> month2 >> day2;
long num1 = days(year1, month1, day1);
long num2 = days(year2, month2, day2);
cout << num2 - num1 << endl;
return 0;
}

暴力求解法

求两个日期之间相差的天数

分析

//历法规定,四年一闰,四百年闰,例如2000年是闰年,2100年不闰年,
公历年份是整百数的,必须是400的倍数的才是闰年,不是400的倍数的就是平年
//计算两个日期之间的天数(C++)
//定义变量year1, month1, day1, year2, month2, day2
//取出2个日期中的年 月 日
//如果年相同,月也相同
//return day1- day2

代码

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
#include <iostream>
using namespace std;
//IsLeap函数判断一个年份是否为闰年,方法如下:
bool IsLeap(int year)
{
return (year % 4 == 0 || year % 400 == 0) && (year % 100 != 0);
}

//上面的StringToDate函数用于取出日期中的年月日并判断日期是否合法
//从字符中最得年月日 规定日期的格式是yyyy-mm-dd
bool StringToDate(string date, int& year, int& month, int& day)
{
year = atoi((date.substr(0, 4)).c_str());
month = atoi((date.substr(5, 2)).c_str());
day = atoi((date.substr(8, 2)).c_str());
int DAY[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
if (IsLeap(year)) {
DAY[1] = 29;
}
return year >= 0 && month <= 12 && month > 0 && day <= DAY[month-1] && day > 0;
}

//DayInYear能根据给定的日期,求出它在该年的第几天,代码如下
int DayInYear(int year, int month, int day)
{
//int _day = 0;
int DAY[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
if (IsLeap(year))
DAY[1] = 29;
for (int i = 0; i < month - 1; ++i)
{
day += DAY[i];
}
return day;
}

int DaysBetween2Date(string date1, string date2)
{
//取出日期中的年月日
int year1, month1, day1; int year2, month2, day2;
if (!StringToDate(date1, year1, month1, day1) || !StringToDate(date2, year2, month2, day2))
{
cout << "输入的日期格式不正确";
return -1;
}
if (year1 == year2 && month1 == month2) //如果年月相同
{
return day1 > day2 ? day1 - day2 : day2 - day1;
}
else if (year1 == year2) //如果年相同
{
int d1, d2;
d1 = DayInYear(year1, month1, day1);
d2 = DayInYear(year2, month2, day2);
return d1 > d2 ? d1 - d2 : d2 - d1;
}
else { //年月都不相同
//确保year1年份比year2早
if (year1 > year2)
{
//swap进行两个值的交换
swap(year1, year2);
swap(month1, month2);
swap(day1, day2);
}
int d1, d2, d3;
if (IsLeap(year1))
d1 = 366 - DayInYear(year1, month1, day1); //取得在该年还于下多少天
else
d1 = 365 - DayInYear(year1, month1, day1);
d2 = DayInYear(year2, month2, day2); //取得在当年中的第几天
d3 = 0;
for (int year = year1 + 1; year < year2; year++)
{
if (IsLeap(year))
d3 += 366;
else
d3 += 365;
}
d3 += 365;
return d1 + d2 + d3;
}
}
int main()
{
int a = DaysBetween2Date("1997-9-2", "1998-6-30");
cout << "1997-9-2到1998-6-30相差 " << a << " 天"<<endl;
system("pause");
return 0;
}


求解日期差

具体日期时间点加上一段时间后所得的日期时间点

描述

如果一个日期时间为1999-12-3123:59:59,将其增加30秒后变为2000-1-10:0:29

代码

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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
#include <iostream>
using namespace std;
bool isLeap(int x) //判断是否是闰年
{
if (x % 400 == 0)
return true;
if (x % 100 == 0)
return false;
if (x % 4 == 0)
return true;
return false;
}
long days(int y, int m, int d)
{
int num[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; //平年每月的天数 y--;
long ret = 365 * y + y / 4 - y / 100 + y / 400 + d;
for (int i = 1; i < m; i++)
{
ret += num[i];
if (i == 2 && isLeap(y + 1))
ret++; //符合闰年且月份大于2月
}
return ret;
}
int Leap_Year(int year) {
if (year % 400 == 0 || (year % 100 != 0 && year % 4 == 0))
return 366;
else
return 365;
}
class DateType
{
private:
int y0;
int m0;
int d0;
public:
friend bool isLeap(int x);
friend long days(int y, int m, int d);
void Set_Day(int day) {
d0 += day;
}
int Get_Day() {
return d0;
}
void Set_Month(int month) {
m0 += month;
}
int Get_Month() {
return m0;
}
void Set_Year(int year) {
y0 += year;
}
int Get_Year() {
return y0;
}
DateType() {
y0 = 1;
m0 = 1;
d0 = 1;
}
DateType(int y = 1, int m = 1, int d = 1) {
y0 = y;
m0 = m;
d0 = d;
}
void PrintDate() {
cout << y0 << "-" << m0 << "-" << d0;
}
};
class TimeType
{
private:
int hr0;
int mi0;
int se0;
public:
friend bool isLeap(int x);
friend long days(int y, int m, int d);
void Set_Second(int second) {
se0 += second;
}
int Get_Second() {
return se0;
}
void Set_Minute(int minute) {
mi0 += minute;
}
int Get_Minute() {
return mi0;
}
void Set_Hour(int hour) {
hr0 += hour;
}
int Get_Hour() {
return hr0;
}
TimeType(int hr = 0, int mi = 0, int se = 0) {
hr0 = hr;
mi0 = mi;
se0 = se;
}
TimeType() {
hr0 = 0;
mi0 = 0;
se0 = 0;
}
void Get_Time() {
cout << hr0 << ":" << mi0 << ":" << se0;
}
};
class DateTimeType :public DateType, public TimeType
{
private:
TimeType time;
DateType date;
public:
friend bool isLeap(int x);
friend long days(int y, int m, int d);
DateTimeType(int y=1, int m=1, int d=1, int hr=0, int mi=0, int se=0) :DateType(y, m, d),TimeType(hr, mi, se), date(y, m, d), time(hr, mi, se)
{

}
void PrintDateTime() {
date.PrintDate();
cout << " ";
time.Get_Time();
cout << endl;
}
DateType& GetDate() {
return date;
}
TimeType& GetTime() {
return time;
}
void IncrementSecond(int s) {
int MONTH[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
time.Set_Second(s);
if (time.Get_Second() < 60)
;
else
{
for (; time.Get_Second() >= 60;)
{
time.Set_Second(-60);
time.Set_Minute(1);
}
for (; time.Get_Minute() >= 60;)
{
time.Set_Minute(-60);
time.Set_Hour(1);
}
for (; time.Get_Hour() >= 24;)
{
time.Set_Hour(-24);
date.Set_Day(1);
}
long Total_Day = days(date.Get_Year(), date.Get_Month(), date.Get_Day());
int temp, Cur_Year, Cur_Month, Cur_Day;
for (Cur_Year = 0; Total_Day >= Leap_Year(Cur_Year); Cur_Year++)
{
Total_Day-=Leap_Year(Cur_Year);
}
if (Leap_Year(Cur_Year) == 366)
MONTH[2] = 29;
for (temp = 1,Cur_Month=1; Total_Day >= MONTH[temp]; temp++)
{
Total_Day -= MONTH[temp];
Cur_Month++;
}
Cur_Day = Total_Day;
date.Set_Day(- date.Get_Day() + Cur_Day);
date.Set_Month(- date.Get_Month() + Cur_Month);
date.Set_Year(- date.Get_Year() + Cur_Year);
}
}
};

int main() {
DateTimeType dttm1(1999, 12, 31, 23, 59, 59), dttm2;
(dttm1.GetDate()).PrintDate(); //调用对象成员所属类的公有成员函数
cout << endl;
dttm1.PrintDateTime(); //调用本派生类的成员函数 PrintDateTime
dttm2.PrintDateTime();
dttm1.IncrementSecond(30); //调用本派生类成员函数
dttm1.PrintDateTime();
return 0;
}

时间点差

标准库函数#include < time.h>

基本介绍

1 结构

struct tm
{
int tm_sec; /秒,正常范围0-59, 但允许至61/
int tm_min; /分钟,0-59/
int tm_hour; /小时, 0-23/
int tm_mday; /日,即一个月中的第几天,1-31/
int tm_mon; /月, 从一月算起,0-11/ 1+p->tm_mon;
int tm_year; /年, 从1900至今已经多少年/ 1900+ p->tm_year;
int tm_wday; /星期,一周中的第几天, 从星期日算起,0-6/
int tm_yday; /从今年1月1日到目前的天数,范围0-365/
int tm_isdst; /日光节约时间的旗标(也叫夏令时)/
};

2 时间概念

  • 本地时间(locale time)
  • 格林威治时间(Greenwich Mean Time GMT)比我国时间晚8个小时

基本输出

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
#include <iostream>
/*包含time头文件*/
#include <time.h>
using namespace std;
int main()
{
//time_t是long类型,精确到秒,是当前时间和1970年1月1日零点时间的差
const time_t now = time(NULL);

cout << "1970年到现在经过的秒数:" << now << endl;

/*本地时间:日期,时间 年月日,星期,时分秒*/
tm* current_time = localtime(&now);

cout << "年:" << 1900 + current_time -> tm_year << endl;
cout << "月:" << 1 + current_time -> tm_mon << endl; /*此month的范围为0-11*/
cout << "日:" << current_time -> tm_mday << endl;

cout << "现在是今年的第几天:" << current_time -> tm_yday << endl; /*当前日期是今年的第多少天[0,365] */
cout << "现在这周的第几天:" << current_time -> tm_wday << endl; /*days since Sunday - [0,6] */
cout << "现在是这个月的第几天:" << current_time -> tm_mday << endl;

cout << "现在的时间点:" << endl;
cout << "时:" << current_time -> tm_hour << endl;
cout << "分:" << current_time -> tm_min << endl; /*此month的范围为0-11*/
cout << "秒:" << current_time -> tm_sec << endl;

printf("本地时间:%d-%d-%d %d:%d:%d\r\n",
current_time -> tm_year + 1900,
current_time -> tm_mon + 1,
current_time -> tm_mday,
current_time -> tm_hour,
current_time -> tm_min,
current_time -> tm_sec);

/*格林威治时间*/
tm* current_gmtime = gmtime(&now);

printf("格林威治时间:%d-%d-%d %d:%d:%d\r\n",
current_gmtime -> tm_year + 1900,
current_gmtime -> tm_mon + 1,
current_gmtime -> tm_mday,
current_gmtime -> tm_hour,
current_gmtime -> tm_min,
current_gmtime -> tm_sec);

system("pause");
return 0;
}

time.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
#include <iostream>
#include <time.h>
using namespace std;
int main()
{
tm t1 = { 0 };
tm t2 = { 0 };
double seconds;

//高考时间2017,6,7
t1.tm_year = 2017 - 1900;
t1.tm_mon = 5;
t1.tm_mday = 7;
t1.tm_hour = 8;
t1.tm_min = 0;
t1.tm_sec = 0;

//现在时间2019,10,22
t2.tm_year = 2019 - 1900;
t2.tm_mon = 9;
t2.tm_mday = 22;
t2.tm_hour = 1;
t2.tm_min = 26;
t2.tm_sec = 22;

//转换结构体为time_t,利用difftime,计算时间差
seconds = difftime(mktime(&t2), mktime(&t1));

//最后输出时间,因为一天有86400秒(60*60*24)
cout << "两个时间相差天数:";
cout << seconds / 86400 << endl;

//最后输出时间,因为一小时有3600秒(60*60)
cout << "两个时间相差小时数:";
cout << seconds / 3600 << endl;

//最后输出时间,因为一分钟有60秒(60)
cout << "两个时间相差分钟数:";
cout << seconds / 60 << endl;

//最后输出时间
cout << "两个时间相差秒数:";
cout << seconds << endl;

system("pause");
return 0;
}

求两个时间点之间的差值


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达,可以邮件至 xingshuaikun@163.com。

×

喜欢就点赞,疼爱就打赏