Calculating daylight saving time from only date

后端 未结 9 1592
春和景丽
春和景丽 2021-01-31 10:53

I am working with an Arduino and a real time clock chip. The chip compensates for leap years and such, so it will always have the correct date, but it does not handle daylight s

9条回答
  •  执笔经年
    2021-01-31 11:15

    this code uses mktime to get a day of the week. It used a day of the week to compute daylight savings time. If you don't want to use mktime, you can use program second_sunday. Start with 3/14/2007, which is Wednesday. The day of the week will advance 1 day for every year and 2 days for every leap after 2004.

    #include 
    #include 
    #include 
    #include 
    
    
    int isDst(int month, int dayOfMonth, int hour, int dayOfWeek);
    
    int main(int argc, char *argv[])
    {
       int isdst, dayOfWeek;
       char buf[80];
       struct tm tmData;
    
       if( argc == 1 )
       {
          printf("\nsyntax: %s mm/dd/yyyy_hh:mm:00", argv[0]);
          return -1;
       }
    
       // 0123456789A12
       // 03/12/2018_12
       strcpy(buf, argv[1]);
       tmData.tm_mon   = atoi(&buf[0]) - 1;  //month -1
       tmData.tm_mday  = atoi(&buf[3]); //day of month
       tmData.tm_year  = atoi(&buf[6]) - 1900; // year - 1900
       tmData.tm_hour  = atoi(&buf[11]); // hour
       tmData.tm_min   = 0; //minutes (not used)
       tmData.tm_sec   = 0; //seconds (not used)
       //tmData.tm_min   = atoi(&buf[14]);
       //tmData.tm_sec   = atoi(&buf[27]);
    
       //day light saving time variable.
       //NOT used in this calculation.
       //Tells mktime the input date is in day light saving time
       tmData.tm_isdst = 0; //
    
       mktime(&tmData);
       dayOfWeek = tmData.tm_wday;
    
       printf("%02d/%02d/%2d_%02d dayWk=%d ",
          tmData.tm_mon+1, tmData.tm_mday, tmData.tm_year, tmData.tm_hour, dayOfWeek);
       isdst = isDst(tmData.tm_mon+1, tmData.tm_mday, tmData.tm_hour, dayOfWeek);
       printf("isdst=%d\n", isdst);
    
       return 0;
    }
    
    
    int isDst(int month, int dayOfMonth, int hour, int dayOfWeek)
    {
       int second_sunday, first_sunday;
    
       if( month  > 3 && month < 11  ) return 1; //4,5,6,7,8,9,10
       if( month  < 3 || month == 12 ) return 0; //1, 2 or 12
       if( month == 3 )
       {
          //The 2nd Sunday in March is 8,9,10,11,12,13,14
          if( dayOfMonth < 8  ) return 0;
          if( dayOfMonth > 14 ) return 1;
    
          //To get here dayOfMonth >= 8 && dayOfMonth <= 14
          second_sunday = dayOfMonth - dayOfWeek;
          if( second_sunday < 8 ) second_sunday += 7;
    printf("2nd_Sunday=%2d ", second_sunday);
          if( dayOfMonth > second_sunday ) return 1;
          if( dayOfMonth < second_sunday ) return 0;
    
          //To get here dayOfMonth = second_sunday
          if( hour >= 2 ) return 1;
          else return 0;
       }
    
       if( month == 11 )
       {
          //The 1st Sunday in Nov is 1,2,3,4,5,6,7
          if( dayOfMonth > 7 ) return 0;
    
          //To get here dayOfMonth >= 1 && dayOfMonth <= 7
          first_sunday = dayOfMonth - dayOfWeek;
          if( first_sunday < 1 ) first_sunday += 7;
    printf("1st_Sunday=%2d ", first_sunday);
          if( dayOfMonth > first_sunday ) return 0;
          if( dayOfMonth < first_sunday ) return 1;
    
          //To get here dayOfMonth = first_sunday
          if( hour >= 2 ) return 0;
          else return 1;
       }
       return -1;
    }
    /**************
       Compile via   cl.exe  isDst.c
    
       Begin and End dates for day light saving time
       03/11/2007_01:00:00    11/04/2007_01:00:00
       03/09/2008_01:00:00    11/02/2008_01:00:00
       03/08/2009_01:00:00    11/01/2009_01:00:00
       03/14/2010_01:00:00    11/07/2010_01:00:00
       03/13/2011_01:00:00    11/06/2011_01:00:00
       03/11/2012_01:00:00    11/04/2012_01:00:00
       03/10/2013_01:00:00    11/03/2013_01:00:00
       03/09/2014_01:00:00    11/02/2014_01:00:00
       03/08/2015_01:00:00    11/01/2015_01:00:00
       03/13/2016_01:00:00    11/06/2016_01:00:00
       03/12/2017_01:00:00    11/05/2017_01:00:00
       03/11/2018_01:00:00    11/04/2018_01:00:00
       03/10/2019_01:00:00    11/03/2019_01:00:00
       03/08/2020_01:00:00    11/01/2020_01:00:00
       03/14/2021_01:00:00    11/07/2021_01:00:00
       03/13/2022_01:00:00    11/06/2022_01:00:00
       03/12/2023_01:00:00    11/05/2023_01:00:00
       03/10/2024_01:00:00    11/03/2024_01:00:00
       03/09/2025_01:00:00    11/02/2025_01:00:00
       03/08/2026_01:00:00    11/01/2026_01:00:00
       03/14/2027_01:00:00    11/07/2027_01:00:00
       03/12/2028_01:00:00    11/05/2028_01:00:00
       03/11/2029_01:00:00    11/04/2029_01:00:00
       03/10/2030_01:00:00    11/03/2030_01:00:00
       03/09/2031_01:00:00    11/02/2031_01:00:00
       03/14/2032_01:00:00    11/07/2032_01:00:00
    
       isDst.exe 03/11/2007_02:00:00  >> dst.txt
       isDst.exe 03/09/2008_02:00:00  >> dst.txt
       isDst.exe 03/08/2009_02:00:00  >> dst.txt
       isDst.exe 03/14/2010_02:00:00  >> dst.txt
       isDst.exe 03/13/2011_02:00:00  >> dst.txt
       isDst.exe 03/11/2012_02:00:00  >> dst.txt
       isDst.exe 03/10/2013_02:00:00  >> dst.txt
       isDst.exe 03/09/2014_02:00:00  >> dst.txt
       isDst.exe 03/08/2015_02:00:00  >> dst.txt
       isDst.exe 03/13/2016_02:00:00  >> dst.txt
       isDst.exe 03/12/2017_02:00:00  >> dst.txt
       isDst.exe 03/11/2018_02:00:00  >> dst.txt
       isDst.exe 03/10/2019_02:00:00  >> dst.txt
       isDst.exe 03/08/2020_02:00:00  >> dst.txt
       isDst.exe 03/14/2021_02:00:00  >> dst.txt
       isDst.exe 03/13/2022_02:00:00  >> dst.txt
       isDst.exe 03/12/2023_02:00:00  >> dst.txt
       isDst.exe 03/10/2024_02:00:00  >> dst.txt
       isDst.exe 03/09/2025_02:00:00  >> dst.txt
       isDst.exe 03/08/2026_02:00:00  >> dst.txt
       isDst.exe 03/14/2027_02:00:00  >> dst.txt
       isDst.exe 03/12/2028_02:00:00  >> dst.txt
       isDst.exe 03/11/2029_02:00:00  >> dst.txt
       isDst.exe 03/10/2030_02:00:00  >> dst.txt
       isDst.exe 03/09/2031_02:00:00  >> dst.txt
       isDst.exe 03/14/2032_02:00:00  >> dst.txt
       isDst.exe 11/04/2007_02:00:00  >> dst.txt
       isDst.exe 11/02/2008_02:00:00  >> dst.txt
       isDst.exe 11/01/2009_02:00:00  >> dst.txt
       isDst.exe 11/07/2010_02:00:00  >> dst.txt
       isDst.exe 11/06/2011_02:00:00  >> dst.txt
       isDst.exe 11/04/2012_02:00:00  >> dst.txt
       isDst.exe 11/03/2013_02:00:00  >> dst.txt
       isDst.exe 11/02/2014_02:00:00  >> dst.txt
       isDst.exe 11/01/2015_02:00:00  >> dst.txt
       isDst.exe 11/06/2016_02:00:00  >> dst.txt
       isDst.exe 11/05/2017_02:00:00  >> dst.txt
       isDst.exe 11/04/2018_02:00:00  >> dst.txt
       isDst.exe 11/03/2019_02:00:00  >> dst.txt
       isDst.exe 11/01/2020_02:00:00  >> dst.txt
       isDst.exe 11/07/2021_02:00:00  >> dst.txt
       isDst.exe 11/06/2022_02:00:00  >> dst.txt
       isDst.exe 11/05/2023_02:00:00  >> dst.txt
       isDst.exe 11/03/2024_02:00:00  >> dst.txt
       isDst.exe 11/02/2025_02:00:00  >> dst.txt
       isDst.exe 11/01/2026_02:00:00  >> dst.txt
       isDst.exe 11/07/2027_02:00:00  >> dst.txt
       isDst.exe 11/05/2028_02:00:00  >> dst.txt
       isDst.exe 11/04/2029_02:00:00  >> dst.txt
       isDst.exe 11/03/2030_02:00:00  >> dst.txt
       isDst.exe 11/02/2031_02:00:00  >> dst.txt
       isDst.exe 11/07/2032_02:00:00  >> dst.txt
       https://stackoverflow.com/questions/5590429/calculating-daylight-saving-time-from-only-date
    ***************/
    
    
    
    /*****
    The previous programs used mktime to compute day_of_week.
    It used day_of_week to compute 2nd_sunday in march and
    1st_sunday in Nov.
    If you don't want to use mktime, you can use this program to
    compute 2nd_sunday.  The same technique will compute 1st_sunday.
    
    On 03/14/2007, the day of the week is Wed, or 3.
    Every year after 2007, the day of the week advances 1 day.
    on leap years, the day of the week advances 2 days.
    Must include the no. of leap years sinc 2004.
    ******/
    
    #include 
    #include 
    #include 
    
    int secondSunday(year);
    
    int main(int argc, char *argv[])
    {
       int year, second_sunday;
    
       if( argc == 1 )
       {
          printf("\nsyntax: %s year, with year >= 2007.\n", argv[0]);
          return -1;
       }
    
       year = atoi(argv[1]);
       if( year < 2007 )
       {
          printf("\nsyntax: %s year, with year >= 2007.\n", argv[0]);
          return -1;
       }
    
       second_sunday = secondSunday(year);
       printf("second_sunday=%d\n", second_sunday);
    
       return 0;
    }
    
    
    int secondSunday(year)
    {
       //On 03/14/2007, the day of the week is Wed, or 3.
       int no_years, no_leaps, day_of_week, second_sunday;
    
       no_years = year - 2007;
       no_leaps = (year - 2004)/4;
       day_of_week = 3 + (no_years + no_leaps) % 7;
       second_sunday = 14 - day_of_week;
       if( second_sunday < 8 ) second_sunday += 7;
    
       //printf("no_years=%d,no_leaps=%d,day_of_week=%d, second_sunday=%d\n",
       //no_years, no_leaps, day_of_week, second_sunday);
    
       return second_sunday;
    }
    /**************
       Compile via   cl.exe  second_sunday.c
    
       second_sunday.exe 2007
       second_sunday.exe 2008
       second_sunday.exe 2009
       second_sunday.exe 2010
       second_sunday.exe 2011
       second_sunday.exe 2012
       second_sunday.exe 2013
       second_sunday.exe 2014
       second_sunday.exe 2015
       second_sunday.exe 2016
       second_sunday.exe 2017
       second_sunday.exe 2018
       second_sunday.exe 2019
       second_sunday.exe 2020
       second_sunday.exe 2021
       second_sunday.exe 2022
       second_sunday.exe 2023
       second_sunday.exe 2024
       second_sunday.exe 2025
       second_sunday.exe 2026
       second_sunday.exe 2027
       second_sunday.exe 2028
       second_sunday.exe 2029
       second_sunday.exe 2030
       second_sunday.exe 2031
       second_sunday.exe 2032
    ***************/
    

提交回复
热议问题