5

我想将像 01/31/2013 这样的日期转换为一年中的某一天(在这种情况下为 31)。这个日期来自用户输入,所以我还需要检查它是否是一个有效的日期。我知道我可以自己计算一年中的哪一天,如下所示:

int get_yday(int mon, int day, int year)
{
    int yday=0;
    mon--;

    switch (mon){
    case 12:
        yday+=31;
    case 11:
        yday+=30;
    ....
    case 2:
        if (is_leap_year(year)) yday+=29;
        else yday+=28;
    .....

但是,这意味着我需要自己检查用户输入,例如

switch(month){
case 1:
    if (day > 31 || day < 0) {...}
case 2:
    if (...check leap year and day ...) {...}

C 中是否有内置 API 可以轻松获取一年中的某一天?

我在下面有一个解决方案,但我想知道是否有更好的解决方案:

1. creating a tm struct of 01/31/2013 00:00:00
2. get timestamp by mktime()
3. convert timestamp to struct tm by localtime()
4. get tm_yday from tm struct
4

5 回答 5

11

使用偏移很容易:

#include <stdio.h>

int yisleap(int year)
{
    return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
}

int get_yday(int mon, int day, int year)
{
    static const int days[2][13] = {
        {0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334},
        {0, 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335}
    };
    int leap = yisleap(year);

    return days[leap][mon] + day;
}

int main(void)
{
    int day = get_yday(1, 31, 2013);

    printf("%d\n", day);
    return 0;
}
于 2013-10-15T09:22:39.550 回答
2

我提出以下算法:

#include <stdio.h>

int leap(int y)
{
    return (y % 4 == 0 && y % 100 != 0) || (y % 400 == 0);
}

int main() {

int year=1992;
int month=12;
int day=1;

int mo[12] = {31,28+leap(year),31,30,31,30,31,31,30,31,30,31};

int i;
int dofy=0;   // EDIT

for (i=0; i<(month-1); i++) {
    dofy += mo[i];
}

dofy += day;

printf("%d\n", dofy);

return 0;
}
于 2013-10-15T09:34:03.433 回答
1

您提出的解决方案很好,除了您可以省略第 3 步,因为mktime()会为您修改结构,没有理由使用时间戳,除非检查来自mktime(). 请记住在调用之前正确设置 的tm_isdst成员struct tm(通常为 -1,除非您确定)mktime()

于 2013-10-15T10:35:24.597 回答
0
int adate[3]    
int main(int argc, char *argv[])
{   
        adate[0]=04;
        adate[1]=26;
        adate[2]=2011;
     int nod=dayofyear(adate);
     printf("%d",nod);
     return 0;  
}

int dayofyear( int *date)
{
int index;
int leap;
int day;


leap = ( date[YEAR]%4 == 0 && date[YEAR]%100 != 0 || date[YEAR]%400 == 0 );
#ifdef DEBUG
fprintf( stderr, "dayofyear: year = %d,  leap = %d\n", date[YEAR], leap );
#endif

day = date[DATE];
for( index = 1; index < date[MONTH]; index++ )
    day += mon[leap][index];
return( day );
} 
于 2015-07-09T12:03:25.263 回答
0

在 EpochConverter.com 上有一个很好的例子来说明如何做到这一点

从纪元转换为人类可读的日期

#include <stdio.h>
#include <time.h>

int main(void)
{
    time_t rawtime = 1262304000;
    struct tm  ts;
    char       buf[80];

    // Format time, "ddd yyyy-mm-dd hh:mm:ss zzz"
    ts = *localtime(&rawtime);
    strftime(buf, sizeof(buf), "%a %Y-%m-%d %H:%M:%S %Z", &ts);
    printf("%s\n", buf);
    return 0;
}

从人类可读的日期转换为纪元

#include <stdio.h>
#include <time.h>

int main(void) {
    struct tm t;
    time_t t_of_day;

    t.tm_year = 2019-1900;  // Year - 1900
    t.tm_mon = 7;           // Month, where 0 = jan
    t.tm_mday = 8;          // Day of the month (zero-based)
    t.tm_hour = 16;
    t.tm_min = 11;
    t.tm_sec = 42;
    t.tm_isdst = -1;        // Is DST on? 1 = yes, 0 = no, -1 = unknown
    t_of_day = mktime(&t);

    printf("seconds since the Epoch: %ld\n", (long) t_of_day);
}
于 2021-05-21T19:37:33.897 回答