CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Daylight Savings...

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Guest








Daylight Savings...
PostPosted: Thu Nov 05, 2009 10:49 am     Reply with quote

Hi All,

Does anyone have a handy routine that will take the year and determine the days that Daylight Savings Time will begin and end?

Thanks!

Joe
Douglas Kennedy



Joined: 07 Sep 2003
Posts: 755
Location: Florida

View user's profile Send private message AIM Address

PostPosted: Thu Nov 05, 2009 1:57 pm     Reply with quote

This was my code but you may find a better way to do it.

Code:

////////////////////////////////////////////////////////////////////
///////        special look up tables
//////////////////////////////////////////////////////////////////////
const int8 table[12]= {6,2,2,5,0,3,5,1,4,6,2,4}; /// for day of week
const int8 months[12]={30,28,30,30,31,30,31,30,30,31,30,31}; // days in month

//////////         globals//////////////////////////////////////
//// day mth template
 struct d_m{
       int8 day;
       int8 mth;
       };
/// declare storage for daylight start
union {
       int8 reg[2];
       struct d_m date;
      } dls_start;
/// declare storage for daylight end
union {
       int8 reg[2];
       struct d_m date;
      }   dls_end;


//////////////////////////////// functions ///////////////////////////////////////////
int8 day_of_week(int8 day,int8 mth,int8 yr)
{int8 val,tmp;

//// yr is last two digits Ex 2007 is 07
///  mth is month Jan=1.....Dec=12
/// explanation
/// 365 days is 1 mod 7 so a non leap year begins on the next day of the week
// to the prior year and another day added if a leap year
// the calc is ahead of itself during an actual leap year hence the
// adjusting down for jan and feb in a leap year
// the table is derived as follows 1/1/01 is a monday so yr=1 day=1 +x mod 7
// has to yield 1 (Monday) so table[0] must be 6 ( 6+1+1=8 and 8 mod 7 is 1)
val=yr+yr/4; /// leap year adj good 2007 to 2099
val=val+table[mth-1]; /// table contains modulo 7  adjustments for mths
val=val+day; /// actual day 1..31
tmp=yr%4;
if(tmp==0) { //leap year
            if(mth<3) val=val-1; /// adjust jan and feb down one for leap year
           }
val=val%7;  /// modulo 7
if(val==0)val=7;

/// val is now the day of week 1=Mon .......7=Sun
return(val);

/// ex dls_start.date.mth=11 dls_start.date.day=1 Nov 1st Sunday
////// ex dls_end.date.mth=03 dls_end.date.day=2 March 2nd Sunday
///// code assumes switch always occurs on a Sunday

int8 dls_adj(int8 hr,int8 day,int8 mth,int8 yr) /// requires day_of_week
{
int8 adj,dow,start_day,start_mth,end_day,end_mth,sun;

//// local clock springs forward in march falls back in Nov
/// for Florida Nov thru March local time is GMT -5  otherwiseo GMT-4
/// adj to local time is 0 for March thru Nov  and 1 Nov thru March
/// dls_start.date.mth is 11=Nov dls_start.date.day is 1 =1st sun
/// dls_end.date.mth is 03=Mar dls_end.date.day is 2 =2nd sun
/// start and end are relative to GMT-4 ( the day the -1 adj starts)
/// the day the (-1 adjustment ends) this is opposite to DLS
/// starting in Mar and ending in Nov
/// If Daylight saving law changes then dls_start.date.mth and dls_start.day are adjusted
/// For 2008 it is the 1st Sun in Nov and 2nd Sun in Mar

/// get dow for Nov 1 in current year
start_mth=dls_start.date.mth;


sun=dls_start.date.day;
dow=day_of_week(1,start_mth,yr); // d/m/y Sun is 7

start_day=sun*7-dow+1;
/// 1st Sun in Nov dls_start.date.day=1 dls_start.date.mth=11
/// ex if Nov 1 is a Sun then dow is 7 so 1st Sun is Nov 1
///                a Wed then dow is 3 so 1st Sun is Nov 5
///

/// get dow for Mar 1 in current year
end_mth=dls_end.date.mth;
sun=dls_end.date.day;
dow=day_of_week(1,end_mth,yr); // d/m/y Sun is 7

dow=day_of_week(1,end_mth,yr); // d/m/y Sun is 7

end_day=sun*7-dow+1;
/// 2nd Sun in Mar dls_start.date.day=2 dls_start.date.mth=3
/// ex if Mar 1 is a Sun then dow is 7 so 2nd Sun is Mar 8
///                a Wed then dow is 3 so 2nd Sun is Mar 12
///
//// now if the DS1307 date is less than end_mth/end_day Mar 2nd Sun
///  the dsl adj is 1
///  also if the Ds307 date is greater than start_mth/end_mth Now 1st Sun
///  the dsl adj is 1
adj=0;
if(mth<end_mth) adj=1;
if( (mth==end_mth) && (day<end_day))adj=1;
if((mth==end_mth) && (day==end_day) && (hr<2)) adj=1;
if(mth>start_mth) adj=1;
if( (mth==start_mth) && (day>start_day)) adj=1;
if( (mth==start_mth) && (day==start_day) && (hr>2)) adj=1;

dls_start.date.day=start_day;
dls_start.date.mth=start_mth;
dls_end.date.day=end_day;
dls_end.date.mth=end_mth;
return(adj);

ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Thu Nov 05, 2009 4:56 pm     Reply with quote

Beware that the date for Daylight Savings Time is not the same in all countries. For Europe the given example program would calculate the wrong date and has to be modified for this.

What we did in our data logging application was to ignore DST and only log in UTC-time. The PC processing the data can then decide on how to handle DST. This made things a lot easier and more user friendly. For example, what to do when the clock is set back one hour? Throw away the already recorded data? Or create a double as high number of counted items? Implementing this on the PC allowed for the user to choose as he wishes.
Douglas Kennedy



Joined: 07 Sep 2003
Posts: 755
Location: Florida

View user's profile Send private message AIM Address

PostPosted: Thu Nov 05, 2009 9:21 pm     Reply with quote

Code:

/// ex dls_start.date.mth=11 dls_start.date.day=1 Nov 1st Sunday
////// ex dls_end.date.mth=03 dls_end.date.day=2 March 2nd Sunday
///// code assumes switch always occurs on a Sunday

I don't know the specifics of European DST but if it starts on any sunday in any month then the variables dls_start.date.day and dls_start_.date.mth would work. dls_start.date.day is 1 if its the first Sunday 2 if the second and 3 if its the third similarly for end dates. Now if European DST starts after the first full moon in November it wont work.
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Fri Nov 06, 2009 6:36 am     Reply with quote

European DST start last sunday in march and ends last sunday in october, fortunately you don't need a moon calendar, but possbly the gregorian formula to calculate the day of week, if not provided by your system clock/RTC.
John Morley



Joined: 09 Aug 2004
Posts: 97

View user's profile Send private message

PostPosted: Fri Nov 13, 2009 10:56 am     Reply with quote

Hi All,

Here is some code I use for calculating the start and end days of daylight savings here in the US:

Code:


        int8 iBeginDay;
        int8 iEndDay;
        int16 iYear;

       iBeginDay = (14 - ((iYear * 5) / 4 + 1) % 7);
       iEndDay = iBeginDay - 7;



In the US, daylight savings always begins on the 2nd Sunday in March, and ends on the 1st Sunday in November. The code above will determine the day in March, and the day in November when this will occur.

BTW, I've tested it until 2099, so if the definition of daylight savings does not change, this code is good for a long while.....

John
_________________
John Morley
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group