我有一个以长值存储的日期,即20130228,我需要对它进行操作,例如添加30天或50等等。有关如何将其转换为更合适的建议吗?
答案 0 :(得分:4)
如果像这样存储
unsigned long d = 20130228;
你必须首先用简单的算术将其拆分并放入struct tm
struct tm tm;
tm.tm_year = d / 10000 - 1900;
tm.tm_mon = (d % 10000) / 100 - 1;
tm.tm_mday = d % 100;
tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
tm.tm_isdst = -1;
然后您可以向30
添加一些值tm.tm_mday
。如果您使用mktime()
,则会收到time_t
seconds since the epoch,tm
中的字段将被归一化
time_t t = mktime(&tm);
答案 1 :(得分:1)
您可以提取年份,月份和日期,然后根据每个月的天数并考虑闰年来添加您的日期。
#include <stdio.h>
unsigned long AddDays(unsigned long StartDay, unsigned long Days)
{
unsigned long year = StartDay / 10000, month = StartDay / 100 % 100 - 1, day = StartDay % 100 - 1;
while (Days)
{
unsigned daysInMonth[2][12] =
{
{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, // 365 days, non-leap
{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } // 366 days, leap
};
int leap = !(year % 4) && (year % 100 || !(year % 400));
unsigned daysLeftInMonth = daysInMonth[leap][month] - day;
if (Days >= daysLeftInMonth)
{
day = 0;
Days -= daysLeftInMonth;
if (++month >= 12)
{
month = 0;
year++;
}
}
else
{
day += Days;
Days = 0;
}
}
return year * 10000 + (month + 1) * 100 + day + 1;
}
int main(void)
{
unsigned long testData[][2] =
{
{ 20130228, 0 },
{ 20130228, 1 },
{ 20130228, 30 },
{ 20130228, 31 },
{ 20130228, 32 },
{ 20130228, 365 },
{ 20130228, 366 },
{ 20130228, 367 },
{ 20130228, 365*3 },
{ 20130228, 365*3+1 },
{ 20130228, 365*3+2 },
};
unsigned i;
for (i = 0; i < sizeof(testData) / sizeof(testData[0]); i++)
printf("%lu + %lu = %lu\n", testData[i][0], testData[i][1], AddDays(testData[i][0], testData[i][1]));
return 0;
}
输出(ideone):
20130228 + 0 = 20130228
20130228 + 1 = 20130301
20130228 + 30 = 20130330
20130228 + 31 = 20130331
20130228 + 32 = 20130401
20130228 + 365 = 20140228
20130228 + 366 = 20140301
20130228 + 367 = 20140302
20130228 + 1095 = 20160228
20130228 + 1096 = 20160229
20130228 + 1097 = 20160301
另一种选择是提取年份,月份和日期并将其转换为自epoch
使用mktime()
或类似函数以来的秒数,将秒数加到表示的秒数从给定日期开始的那些天,然后使用gmtime()
或localtime()
或类似函数将结果秒转换回日期,然后构造长整数值。我选择不使用这些功能来避免时区和夏令时等问题。我想要一个简单且包含的解决方案。
答案 2 :(得分:0)
通过将日期转换为“从X开始的时间单位”,日期更容易做“数学” - 标准库中的time_t
是“从午夜开始的秒数” 1970年1月“。因此,使用mktime
中的struct tm
将是一种解决方案。
如果由于某种原因您不想这样做,那么将您的日期转换为“自(例如)2000年1月1日以来的天数”将起作用。在处理整年时,你必须考虑到成年人(year % 4 == 0 && (year % 100 != 0 || year %400 == 0)
应该涵盖那些),当然,你需要在一年内照顾每月的天数。到目前为止的转换是类似的,但相反。