我需要计算给定日期的日期编号。这一年有366天。然而,每个月都有不同的值,我必须分配值。是否有更快的方法来实现它而不是我的方式呢?
#include<iostream>
using namespace std;
int main()
{
int day, month, year, dayNumber;
cout<< "Please enter the month, by numerical value:";
cin>> month;
cout<<"Please enter the day, by numerical value:";
cin>> day;
cout<<"Please enter the year, by numerical value:";
cin>> year;
if (month == 1)
{
dayNumber= day;
cout<< "Month;" << '\t'<< month << '\n'
<< "Day:"<<'\t'<< day<< '\n'
<< "Year:"<<'\t'<< year<<'\n'
<< "Day Number:"<< '\t'<< dayNumber<< endl;
}
else if(month==2)
{
dayNumber= day+31;
}
}
答案 0 :(得分:4)
只需使用mktime
:
tm date = {};
date.tm_year = year - 1900;
date.tm_mon = month - 1;
date.tm_mday = day;
mktime( &date );
dayNumber = date.tm_yday;
否则,你需要一个二维表:
int daysToMonth[2][12] =
{
{ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 },
{ 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 },
};
和一个功能:
bool isLeapYear( int year )
{
return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
}
那一年是:
daysToMonth[isLeapYear( year ) ? 1 : 0][month] + day;
答案 1 :(得分:3)
首先,您需要知道年份是否为闰年:
bool isLeap(year) {
return (((year % 4) == 0) && (((year % 100) != 0) || ((year % 400) == 0))
}
然后你可以创建给定年份和数组或每月每月的数字:
unsigned int daysPerMonth[] = {31, (isLeap(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
我只给你一大堆代码,但他们可以帮助你。
循环遍历此数组以获取实际日期编号。以1989年4月4日为例,不是闰年。它的天数为31 + 28 + 31(1月至3月),然后是+4。
答案 2 :(得分:1)
您可以创建一个包含每月天数的向量:
std::vector<int> days_in_month;
days_in_month.push_back(31); //Jan
days_in_month.push_back(29); //Feb
... // so on for each month
然后,要计算,你可以这样做:
int day = <day_entered_by_user>;
int month = <month_entered_by_user>;
int num_of_days = 0;
// Sum the number of days for all months preceding the current month
for(int i = 0; i < (month - 1); ++i)
num_of_days += days_in_month[i];
// Finally just add the day entered for the current month
num_of_days += day;
答案 3 :(得分:1)
您可以将每月的天数存储在数组中:
int days_per_month[] = {31, 29, 31, ...};
或
std::array<int, 12> days_per_month{{31, 29, 31,...}};
然后你需要遍历那个数组来计算已经过去的天数之和:
int sum = 0;
for ( int i = 1; i < month; ++i )
{
sum += days_per_month[i - 1]; // note the index shift!
}
dayNumber += sum;
另一种方法是直接将总和存储在数组中:
std::array<int, 12> passed_days{{0, 31, 60,...}};
然后你摆脱了循环:
dayNumber += passed_days[month - 1];
对于闰年,只需检查年份以及月份是否至少为3年。
答案 4 :(得分:1)
在许多方面,最好避免手动滚动。
使用提升:
#include <boost/date_time/gregorian/gregorian.hpp>
//...
try {
boost::gregorian::date d(year, month, day);
dayNumber = d.day_of_year();
}
catch (std::out_of_range& e) {
// Alternatively catch bad_year etc exceptions.
std::cout << "Bad date: " << e.what() << std::endl;
}
正如James Kanze建议您也可以使用mktime来避免依赖boost(未经测试):
tm timeinfo = {};
timeinfo.tm_year = year - 1900;
timeinfo.tm_mon = month - 1;
timeinfo.tm_mday = day;
mktime(&timeinfo);
dayNumber = timeinfo.tm_yday;
答案 5 :(得分:0)
真正的短代码看起来像下面一样:
{
int nonleap[12]={0,31, 31+28, 31+28+31, 31+28+31+30 .....};
int leap[12]={0,31, 31+29, 31+29+31, 31+29+31+30 .....};
if(yearIsLeap(year))
return leap[month]+day;
else
return nonleap[month]+day;
}
答案 6 :(得分:0)
你们真的很难做到,为什么不汇总前两个答案
int year = 2020, month = 12, day = 10;
tm timeinfo = {};
int dayNumber = 0;
bool isLeap = (((year % 4) == 0) && (((year % 100) != 0) || ((year % 400) == 0));
timeinfo.tm_year = year - 1900;
timeinfo.tm_mon = month - 1;
timeinfo.tm_mday = day;
mktime(&timeinfo);
dayNumber = timeinfo.tm_yday;
if (isLeap && month > 2) dayNumber++;