【问题标题】:Does struct tm->tm_yday give correct value for leap year?struct tm->tm_yday 是否为闰年提供正确的值?
【发布时间】:2017-02-14 23:13:49
【问题描述】:

假设我想获取自 1 月 1 日以来经过的天数,这会返回闰年的正确值吗?

struct tm *now_tm;
struct timeval tv;
time_t currtime;

gettimeofday(&tv, NULL);
currtime=tv.tv_sec;
now_tm = localtime(&currtime);
int day = now_tm->tm_yday;

tm 参考 http://www.cplusplus.com/reference/ctime/tm/

【问题讨论】:

    标签: c time


    【解决方案1】:

    是的,如果您将 currtime 初始化为当前时间而不是让它未初始化:

    time_t currtime = time(0);
    

    将(可能)在您的计算机上以man localtime 找到更好的参考。或者你可以阅读它here

    请注意,该字段记录为具有 0-365(含)的值,而不是 0-364,因此它有 366 个可能的值。

    【讨论】:

    • @schwern:如果您有正确的 time 函数声明(这也是获得正确返回值类型所必需的顺序),则保证工作。
    • 我的错误,常量 0 是空指针。我把它和像calloc这样的归零内存混在一起了。
    【解决方案2】:

    是的,您可以对其进行测试。你最好用gmtime 来做这件事,因为localtime 涉及时区,而时区可以一天一天地过去,我们不需要那么复杂。

    2000 年是闰年,也是一个棘手的年份,所以它是一个很好的测试。 UTC 2000 年 1 月 1 日午夜的 Unix 纪元是 946684800(30 年 + 从 1970 年 1 月 1 日开始的 7 个闰日)。所以我们提前 31 + 28 天到 2 月 29 日。我们可以使用gmtime 来获取一年中的哪一天,并使用asctime 来验证我们的日期是否正确。

    #include <stdio.h>
    #include <time.h>
    
    int main() {
        struct tm *date;
        const int secs_per_day = 24 * 60 * 60;
    
        /* Jan 1st, 2000 midnight UTC in Unix epoch.
           30 years since Jan 1st, 1970.
           Plus 7 leap days between Jan 1, 1970 and Jan 1, 2000.
           Feb 29th 1972, 76, 82, 86, 92, and 96
        */
        int days = (30 * 365) + 7;
        time_t time = days * secs_per_day;
    
        date = gmtime(&time);
        printf("%d == %s", date->tm_yday, asctime(date));
    
        /* Jump ahead to Feb 29th */
        time += (31 + 28) * secs_per_day;
    
        date = gmtime(&time);
        printf("%d == %s", date->tm_yday, asctime(date));
    }
    

    我们可以看到它有效,2000 年 2 月 29 日是一年中的第 59 天(从 0 开始计数)。

    0 == Sat Jan  1 00:00:00 2000
    59 == Tue Feb 29 00:00:00 2000
    

    【讨论】:

      【解决方案3】:

      是的 - 它将返回 365。1 月 1 日将返回 0,12 月 31 日将返回非闰年的 364 和闰年的 365

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-11-14
        • 2022-10-02
        • 1970-01-01
        • 2018-02-25
        相关资源
        最近更新 更多