我如何将一年中的某一天(1-365)转换为其等效日期(即2013年1月5日)C++
How can I convert the day of the year (1-365) to its equivalent date (ie. January 5th, 2013) C++
我尝试过搜索一种可以实现这一点的算法,但没有找到任何结果。
我有构造函数Date2013(int dd)。
在这个成员函数中,我创建了一个包含月份的数组(一月、二月等)
然后我创建了一个if语句,它接收dd,如果dd在第1-31天之间,那么输出January,如果它在32-59天之间,然后输出二月。
我遇到的问题是,然后取他们输入的数字dd,并将其转换为一个月中合适的日期。一年中的第三十四天是二月二日。
有人知道任何算法吗,或者知道我可以实现这一点的方法吗?
(我刚刚开始学习我的C++,所以在任何代码中进行解释或注释都会非常有帮助,这样我就可以理解你的思维过程和语法)
最便携的&可靠的方法是使用ANSI C mktime&localtime函数,它将与C或C++一起工作
更新:
要回答如何实现自己的算法而不是使用标准的C库mktime函数的问题,一个好的起点是查看已知的工作代码,如glibc mktime源代码。您需要的相关花絮包括:
来自glibc 2.17(HEAD)mktime.c第141行附近:
#define TM_YEAR_BASE 1900
/* Return 1 if YEAR + TM_YEAR_BASE is a leap year. */
static inline int
leapyear (int year)
{
/* Don't add YEAR to TM_YEAR_BASE, as that might overflow.
Also, work even if YEAR is negative. */
return
((year & 3) == 0
&& (year % 100 != 0
|| ((year / 100) & 3) == (- (TM_YEAR_BASE / 100) & 3)));
}
从glibc 2.17(HEAD)mktime.c第160行开始:
const unsigned short int __mon_yday[2][13] =
{
/* Normal years. */
{ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
/* Leap years. */
{ 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
};
一个示例C++类实现了一个构造函数,该构造函数将year&dayOfYear到相应月份&dayOfMonth可能看起来像:
#include <iostream>
using namespace std;
#define MONTHS_IN_YEAR 12
class MyDateClass {
public:
MyDateClass(int year, int dayOfYear) {
int yearOffset = dayOfYear - TM_YEAR_BASE;
int leapYearIndex = leapyear(year) ? 1 : 0;
int daysInYear = leapYearIndex ? 366 : 365;
this->year = year;
this->dayOfYear = dayOfYear;
if (dayOfYear >= 1 && dayOfYear <= daysInYear) {
for (int mon = 0; mon < MONTHS_IN_YEAR; mon++) {
if (dayOfYear <= __mon_yday[leapYearIndex][mon+1]) {
month = mon + 1;
dayOfMonth = dayOfYear - __mon_yday[leapYearIndex][mon];
break;
}
}
} else {
cerr << "day of year must be between 1 and " << daysInYear << endl;
month = 0;
dayOfMonth = 0;
}
}
// Get month 1=January, 12=December
inline int getMonth() { return month; }
// Get day of month
inline int getDayOfMonth() { return dayOfMonth; }
// Get year
inline int getYear() { return year; }
// Get day of yar
inline int getDayOfYear() { return dayOfYear; }
private:
int month;
int dayOfMonth;
int year;
int dayOfYear;
};
希望我不会因为展示可能完成任务的示例代码而被投票否决。当然,你可以随心所欲地实现它。这只是一个例子。
如果您更愿意使用现有的mktime功能(推荐),它很可能出现在您正在编程的任何平台上的标准C库中,我的原始回答内容如下
使用mktime时,您需要确保将tm_mon=0和tm_mday设置为一年中的某一天(有关更好的解释,请参阅mktime文档),但简而言之,mktime会忽略tm_wday和tm_yday,只翻译tm_mday,如果您也将tm_mon设置为0,则它本质上会将tm_mday解释为一年之日;
以下是一些说明这一点的工作示例代码,它们将在C或C++中工作:
#include <stdio.h> /* printf, scanf */
#include <time.h> /* time_t, struct tm, time, mktime */
#include <strings.h> /* bzero */
int main () {
time_t loctime;
struct tm timeinfo, *loctimeinfo;
int year, day;
/* prompt user for year and day-of-the-year */
printf ("Enter year: "); scanf ("%d",&year);
printf ("Enter day of the year: "); scanf ("%d",&day);
/* initialize timeinfo and modify it to the user's choice */
bzero(&timeinfo, sizeof(struct tm));
timeinfo.tm_isdst = -1; /* Allow mktime to determine DST setting. */
timeinfo.tm_mon = 0;
timeinfo.tm_mday = day;
timeinfo.tm_year = year - 1900;
loctime = mktime (&timeinfo);
loctimeinfo = localtime(&loctime);
printf ("The date for that day of the year is %s.n", asctime(loctimeinfo));
return 0;
}
编译&示例运行:
$ g++ -o t2 t2.c
$ ./t2
Enter year: 2013
Enter day of the year: 1
The date for that day of the year is Tue Jan 1 00:00:00 2013
$ ./t2
Enter year: 2013
Enter day of the year: 365
The date for that day of the year is Tue Dec 31 00:00:00 2013
甚至适用于2012年这样的闰年:
$ ./t2
Enter year: 2012
Enter day of the year: 366
The date for that day of the year is Mon Dec 31 00:00:00 2012
因此,计算这一点的基本原则是有一个"每月天数"的列表。
int days_in_month[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
如果我们有一个名为days
的变量,它是一年中的天数,month
表示我们在哪个月结束:
从"month=1;"开始,只需检查days
是否小于days_in_month[month]
,如果不是从天数中减去days_in_month[month]
,并继续进行,直到你达到月=12,仍然有更多的天数,天数超过了days_in_month[month]
[这意味着这是明年,从month=1
开始,然后转到下一个year
-但我认为你的任务限制在1-365天,所以现在只需报告错误就可以了]。
当天数不超过days_in_month[month]
时,即为当月的天数。
请注意,我有意而不是编写了如何做到这一点的代码,而是描述了如何做到。因为我是至少写过几次这种代码的人,而你是试图学习的人。你不能通过复制和粘贴SO学习。
编辑:是的,我完全忽略了闰年。对于2013年来说,这不是闰年,所以我们不在乎…;)
- 查询SQLite数据库中的日期
- 获取日期异步信号安全吗?如果在信号处理程序中使用,它会导致死锁吗
- Log4cpp:以UTC/GMT时区打印日期
- 使用C++的日期库读取时间
- 日期格式为C++
- 如何在 C++20 计时中为日期添加天数?
- 如何在QTableView中排序和更改日期格式
- 如何在cpp中使用地图显示给定日期范围内(在下面的问题中)的费率?
- Gtkmm 会不断检查 Gtk::日历上的所选日期是否发生变化
- fmt 与 Howard Hinnant 的日期:为什么从 fmt::to_string "{}"?FMT 和日期的最佳实践?
- 使程序检查当前日期是否=预期日期
- 如何找到两个日期之间的时间差异(以秒和纳秒为单位)?
- JNI 日期值转换问题,在C++中获取不同的长整型值
- 确定夏令时是否适用于特定日期
- C++日期库因时区而失败
- 向日期运算符添加天数+
- 为什么在C++中获取日期和/或时间如此复杂?
- 如何验证用户输入月份的日期?
- 从编译时已知的日历日期创建"std::chrono::time_point"
- 在 MacOS 上C++:显示日期和时间问题