
7 changed files with 261 additions and 1 deletions
@ -0,0 +1,173 @@ |
|||
/*
|
|||
Daylight Saving Time for OpenChronos on the TI ez430 chronos watch. |
|||
Copyright 2011 Rick Miller <rdmiller3@gmail.com> |
|||
|
|||
This program is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
This program is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
|
|||
#include "project.h" |
|||
|
|||
#if (CONFIG_DST > 0) |
|||
|
|||
// driver
|
|||
#include "altitude.h" |
|||
#include "display.h" |
|||
#include "vti_ps.h" |
|||
#include "ports.h" |
|||
#include "timer.h" |
|||
|
|||
#include "stopwatch.h" |
|||
|
|||
// logic
|
|||
#include "user.h" |
|||
#include "clock.h" |
|||
#include "date.h" |
|||
#include "dst.h" |
|||
|
|||
#include "menu.h" |
|||
|
|||
struct dst_date_struct dst_dates[2]; |
|||
u8 dst_state; // 0=ST, 1=DST
|
|||
|
|||
u8 dst_day_of_week(u16 year, u8 month, u8 day); |
|||
|
|||
void dst_init(void) |
|||
{ |
|||
dst_calculate_dates(); |
|||
} |
|||
|
|||
#define N_SUN_OF_MON(n,mon) (((n)*7)-dst_day_of_week(sDate.year,(mon),((n)*7))) |
|||
#define LAST_SUN_OF_MON(mon,days) ((days)-dst_day_of_week(sDate.year,(mon),(days))) |
|||
|
|||
void dst_calculate_dates(void) |
|||
{ |
|||
// This should be run whenever sDate.year gets changed.
|
|||
|
|||
|
|||
#if (CONFIG_DST == 1) |
|||
// DST in US/Canada: 2nd Sun in Mar to 1st Sun in Nov.
|
|||
dst_dates[0].month = 3; |
|||
dst_dates[0].day = N_SUN_OF_MON(2, 3); |
|||
dst_dates[1].month = 11; |
|||
dst_dates[1].day = N_SUN_OF_MON(1, 11); |
|||
#endif |
|||
#if (CONFIG_DST == 2) |
|||
// DST in Mexico: first Sun in Apr to last Sun in Oct.
|
|||
dst_dates[0].month = 4; |
|||
dst_dates[0].day = N_SUN_OF_MON(1, 4); |
|||
dst_dates[1].month = 10; |
|||
dst_dates[1].day = LAST_SUN_OF_MON(10, 31); |
|||
#endif |
|||
#if (CONFIG_DST == 3) |
|||
// DST in Brazil: third Sun in Oct to third Sun in Feb.
|
|||
dst_dates[0].month = 10; |
|||
dst_dates[0].day = N_SUN_OF_MON(3, 10); |
|||
dst_dates[1].month = 2; |
|||
dst_dates[1].day = N_SUN_OF_MON(3, 2); |
|||
#endif |
|||
#if (CONFIG_DST == 4) |
|||
// DST in EU/UK: last Sun in Mar to last Sun in Oct.
|
|||
dst_dates[0].month = 3; |
|||
dst_dates[0].day = LAST_SUN_OF_MON(3, 31); |
|||
dst_dates[1].month = 10; |
|||
dst_dates[1].day = LAST_SUN_OF_MON(10, 31); |
|||
#endif |
|||
#if (CONFIG_DST == 5) |
|||
// DST in Australia: first Sun in Oct to first Sun in Apr.
|
|||
dst_dates[0].month = 10; |
|||
dst_dates[0].day = N_SUN_OF_MON(1, 10); |
|||
dst_dates[1].month = 4; |
|||
dst_dates[1].day = N_SUN_OF_MON(1, 4); |
|||
#endif |
|||
#if (CONFIG_DST == 6) |
|||
// DST in New Zealand: last Sun in Sep to first Sun in Apr.
|
|||
dst_dates[0].month = 9; |
|||
dst_dates[0].day = LAST_SUN_OF_MON(9, 30); |
|||
dst_dates[1].month = 4; |
|||
dst_dates[1].day = N_SUN_OF_MON(1, 4); |
|||
#endif |
|||
|
|||
// This test may be wrong if you set your watch
|
|||
// on the time-change day.
|
|||
dst_state = (dst_isDateInDST(sDate.month, sDate.day)) ? |
|||
1 : 0; |
|||
} |
|||
|
|||
#define DSTNUM(x,y) (((u16)(x)*100)+(u16)(y)) |
|||
|
|||
u8 dst_isDateInDST(u8 month, u8 day) |
|||
{ |
|||
if (dst_dates[0].month < dst_dates[1].month) |
|||
{ |
|||
// Northern hemisphere
|
|||
return |
|||
((DSTNUM(month,day)>=DSTNUM(dst_dates[0].month,dst_dates[0].day)) && |
|||
(DSTNUM(month,day)<DSTNUM(dst_dates[1].month,dst_dates[1].day))); |
|||
} |
|||
else |
|||
{ |
|||
// Southern hemisphere
|
|||
return (!( |
|||
((DSTNUM(month,day)>=DSTNUM(dst_dates[1].month,dst_dates[1].day)) && |
|||
(DSTNUM(month,day)<DSTNUM(dst_dates[0].month,dst_dates[0].day))))); |
|||
} |
|||
} |
|||
|
|||
u8 dst_day_of_week(u16 year, u8 month, u8 day) |
|||
{ |
|||
// Calculate days since 2000-01-01
|
|||
u32 tmp = ((u32)sDate.year % 200) * 365; |
|||
tmp += ((sDate.year % 200) / 4); // leap days
|
|||
switch (sDate.month) // using lots of drop-through!
|
|||
{ |
|||
case 12: |
|||
tmp += 30; // for nov
|
|||
case 11: |
|||
tmp += 31; // for oct
|
|||
case 10: |
|||
tmp += 30; // for sep
|
|||
case 9: |
|||
tmp += 31; // for aug
|
|||
case 8: |
|||
tmp += 31; // for jul
|
|||
case 7: |
|||
tmp += 30; // for jun
|
|||
case 6: |
|||
tmp += 31; // for may
|
|||
case 5: |
|||
tmp += 30; // for apr
|
|||
case 4: |
|||
tmp += 31; // for mar
|
|||
case 3: |
|||
tmp += 28; // for feb
|
|||
if ((sDate.year % 4) == 0) |
|||
{ |
|||
tmp++; |
|||
} |
|||
case 2: |
|||
tmp += 31; // for jan
|
|||
case 1: |
|||
default: |
|||
// do nothing
|
|||
break; |
|||
} |
|||
tmp += sDate.day; |
|||
tmp--; // because day-of-month is 1-based (2000-01-01 is the ZERO day).
|
|||
|
|||
// day zero (2000-01-01) was a Saturday.
|
|||
return (u8)((tmp + 6) % 7); |
|||
} |
|||
|
|||
#endif /* (CONFIG_DST > 0) */ |
|||
|
@ -0,0 +1,35 @@ |
|||
/*
|
|||
Daylight Saving Time for OpenChronos on the TI ez430 chronos watch. |
|||
Copyright 2011 Rick Miller <rdmiller3@gmail.com> |
|||
|
|||
This program is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
This program is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
|
|||
#ifndef DST_H_ |
|||
#define DST_H_ |
|||
|
|||
struct dst_date_struct |
|||
{ |
|||
u8 month; |
|||
u8 day; |
|||
}; |
|||
|
|||
extern struct dst_date_struct dst_dates[]; |
|||
extern u8 dst_state; // 0=ST, 1=DST
|
|||
|
|||
void dst_init(void); |
|||
void dst_calculate_dates(void); |
|||
u8 dst_isDateInDST(u8 month, u8 day); |
|||
|
|||
#endif |
Loading…
Reference in new issue