【问题标题】:C get day of year from dateC 从日期获取一年中的某一天
【发布时间】:2021-05-22 03:37:33
【问题描述】:

我想将 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

【问题讨论】:

  • “下面的解决方案”正是我会做的,我认为没有更好的标准C api。

标签: c date


【解决方案1】:

使用偏移很容易:

#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;
}

【讨论】:

    【解决方案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;
    }
    

    【讨论】:

    • 记得用0初始化dofy
    【解决方案3】:

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

    【讨论】:

      【解决方案4】:
      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 );
      } 
      

      【讨论】:

        【解决方案5】:

        有一个pretty good example of how to do this on 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);
        }
        

        【讨论】:

          猜你喜欢
          • 2016-01-22
          • 2023-04-02
          • 2013-09-12
          • 1970-01-01
          • 2023-04-11
          • 2019-04-10
          • 2012-12-06
          • 1970-01-01
          • 2014-08-03
          相关资源
          最近更新 更多