闰年的判断方法
在我们目前使用的格里高利历(Gregorian Calendar)中,闰年的确定遵循着一套精确的规则,具体来说,这些规则如下:
1.任何能被4整除的年份通常被认为是闰年。这意味着每四年,我们会增加一天,即2月29日,使得该年有366天而非常规的365天。
2.第二个规则是:如果一个年份能被100整除,那么它通常不被认定为闰年,但是它既能被100整除,同时也能被400整除,那么它就是闰年。
以2000年和1900年为例,2000年是闰年,因为它能被400整除(2000 ÷ 400 = 5),而1900年虽然能被100整除(1900 ÷ 100 = 19),但不能被400整除(1900 ÷ 400 ≠ 整数),因此1900年不是闰年。
bool isLeapYear(int year) {
return (year % 400 == 0) || (year % 4 == 0 && year % 100 != 0);
}
判断给定的日期是给定年份的第几天
要计算给定的日期是给定年份的第几天,可以遍历从1月到给定月份之前的所有月份,累加每个月的天数到dayOfYear
,最后,将给定月份的天数加到dayOfYear
上即可。要特别注意2月,因为闰年和平年的天数不同,在累加月份天数时,如果年份是闰年且当前月份是2月,则2月有29天;否则,2月有28天。
int calculateDayOfYear(int year, int month, int day)
{
int dayOfYear = 0;
std::array<int, 12> daysPerMonth = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
if (isLeapYear(year))
daysPerMonth[1] = 29;
for (int i = 0; i < month - 1; i++)
dayOfYear += daysPerMonth[i];
dayOfYear += day;
return dayOfYear;
}
判断给定的日期是星期几
基姆拉尔森计算公式是一种用于计算给定日期是星期几的算法,特别适用于编程和日常生活中的日期计算。该公式基于公历日期系统,通过特定的数学运算来确定任何一天是星期几。以下是关于基姆拉尔森计算公式的详细解释和计算步骤:
公式概述
基姆拉尔森计算公式的基本形式如下:
W=(d+2m+3(m+1)/5+y+y/4−y/100+y/400+1)%7
其中:
- d 表示日期中的日数(1-31)。
- m 表示月份数(3-14,其中1月和2月被视为上一年的13月和14月)。
- y 表示年份。
- W 表示星期几,取值范围为0到6,其中0代表星期日,1代表星期一,依此类推。
int calculateWeekDay(int year, int month, int day) {
if (month == 1 || month == 2) {
month += 12;
year--;
}
int w = (day + 2 * month + 3 * (month + 1) / 5 + year + year / 4 - year / 100 + year / 400 + 1) % 7;
return w;
}
完整代码如下
#include <iostream>
#include <array>
#include <chrono>
#include <cmath>
/**
* 判断指定年份是否为闰年
*
* 闰年的判断条件如下:
* 1、年份可以被400整除;
* 2、年份能被4整除,但不能被100整除;
*
* @param year 要判断的年份
* @return 如果年份是闰年则返回true,否则返回false
*/
bool isLeapYear(int year) {
return (year % 400 == 0) || (year % 4 == 0 && year % 100 != 0);
}
/**
* 计算给定的日期是今年第几天
*
* @param year 要判断的年份
* @param year 要判断的月份
* @param year 要判断的日期
* @return 返回该日期是今年第几天
*/
int calculateDayOfYear(int year, int month, int day)
{
int dayOfYear = 0;
std::array<int, 12> daysPerMonth = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
if (isLeapYear(year))
daysPerMonth[1] = 29;
for (int i = 0; i < month - 1; i++)
dayOfYear += daysPerMonth[i];
dayOfYear += day;
return dayOfYear;
}
/**
* 基姆拉尔森公式根据日期判断星期几
*
* @param year 要判断的年份
* @param year 要判断的月份
* @param year 要判断的日期
* @return 返回该日期是周几,计算结果的取值范围是0-6,0代表星期日,1-6分别代表星期一到星期六
*/
int calculateWeekDay(int year, int month, int day) {
if (month == 1 || month == 2) {
month += 12;
year--;
}
int w = (day + 2 * month + 3 * (month + 1) / 5 + year + year / 4 - year / 100 + year / 400 + 1) % 7;
return w;
}
/**
* 计算当前日期为当前年份周数
*
* 在中国,周数的计算通常遵循以下规则:
* 1.每周从星期一开始,到星期日结束;
* 2.1月1日所在的周通常被认为是第1周;
* @param year 要判断的年份
* @param year 要判断的月份
* @param year 要判断的日期
* @return 返回该日期是第几周
*/
int calculateWeekNumber(int year, int month, int day) {
int daysOfRemain = CalculateDayOfYear(year, month, day) - (7 - calculateWeekDay(year, 1, 1));
if (daysOfRemain == 0)
{
return 1;
}
int weekNumber = std::ceil(static_cast<double>(daysOfRemain) / 7);
return weekNumber + 1;
}
int main() {
auto now = std::chrono::system_clock::now();
auto today = std::chrono::system_clock::to_time_t(now);
std::tm date;
#ifdef _WIN32
::localtime_s(&date, &today);
#else
::localtime_r(&date, &today);
#endif
int year = date.tm_year + 1900; // tm_year 是从1900年开始计数的
int month = date.tm_mon + 1; // tm_mon 是从0开始计数的
int day = date.tm_mday;
std::cout << "今天是 " << year << "年" << month << "月" << day << "日" << std::endl;
std::cout << "今天是今年的第 " << calculateWeekNumber(year, month, day) << " 周" << std::endl;
return 0;
}