![]() |
Forum Index : Microcontroller and PC projects : Daylight Saving
![]() ![]() |
|||||
Author | Message | ||||
phil99![]() Guru ![]() Joined: 11/02/2018 Location: AustraliaPosts: 2457 |
Just to clutter things up a bit more here is another one. It doesn't use the Epoch() function but does use Day$() so no good for the MicroMite. Function ds4.10(dateNow$) Usage:-'Determine Daylight Saving start and stop dates. If dateNow$="" Then dateNow$=Date$ Local integer month=Val(Mid$(dateNow$,4,2)), days=Val(Left$(dateNow$,2)), n If (month > 4) And (month < 10) Then ds4.10 = 0 'never DST in these months If (month < 4) Or (month > 10) Then ds4.10 = 1 'always DST in these months 'Change all the 4s and 10s for DST stop/start months other than April and October 'Swap 0 and 1 in lines above for northern hemisphere n=0 'If DST changes in second week change n to 8. If last week use the last day -7 If month = 4 Then 'End DST 1st Sunday in April Do 'find the first Sunday Inc n 'n = date of first Sunday Loop Until Day$(Str$(n)+Right$(dateNow$,8)) = "Sunday" If days < n Then 'compare date of first Sunday with supplied date ds4.10 = 1 Else ds4.10 = 0 'Swap 0 and 1 for northern hemisphere EndIf EndIf n=0 'If DST changes in second week change n to 8. If last week use the last day -7 If month = 10 Then 'Start DST 1st Sunday in October Do 'find the first Sunday Inc n 'n = date of first Sunday Loop Until Day$(Str$(n)+Right$(dateNow$,8)) = "Sunday" If days < n Then 'compare date of first Sunday with supplied date ds4.10 = 0 Else ds4.10 = 1 'Swap 0 and 1 for northern hemisphere EndIf EndIf End Function > ? ds4.10() 'DST for current date 1 > ? ds4.10("07-04-2025") 'DST for any date 0 > Edited 2025-03-02 07:29 by phil99 Footnote added 2025-03-02 14:25 by phil99 As this thread is going out in public (on FoTS) I thought I should comb my versions hair an give it a squirt of deodorant. Still not a good as Jim's last one (a few posts below) but can be readily configured for most DST rules and both hemispheres. Function dst(dateNow$) Extended version of Jim's test program at the bottom.'Daylight Saving Time indicator 'output - dst() = 0 is standard time, dst = 1 is summer time 'change the values in the following four lines to suit local DST rules Local integer hemi = 0 'northern hemisphere = 1, southern = 0 Local integer ChngMnth1 = 4, ChngMnth2 = 10 'Months when DST changes Local integer ChngWeek1 = 5, ChngWeek2 = 5 'Week of the month for change, use 5 for the last week of the month Local ChngDay$ = "Sunday" 'day of week for DST change. First letter upper case, rest lower case If dateNow$="" Then dateNow$=Date$ 'if no date supplied use current date 'convert the 'change weeks' to start dates for finding the DST start/end days ChngWeek1 = ChngWeek1 * 7 - 6 ChngWeek2 = ChngWeek2 * 7 - 6 If ChngWeek1 = 29 Then ChngWeek1 = 30 - 7 '<-Use 31 for a 31 day month if last week is used If ChngWeek2 = 29 Then ChngWeek2 = 31 - 7 '<-Use 30 for a 30 day month if last week is used Local integer month=Val(Mid$(dateNow$,4,2)), days=Val(Left$(dateNow$,2)), n=0 If (month > ChngMnth1) And (month < ChngMnth2) Then dst = 0 'no change in these months If (month < ChngMnth1) Or (month > ChngMnth2) Then dst = 1 'no change in these months If month = ChngMnth1 Then 'First change month Do 'find the change day Inc ChngWeek1 'day number for change, compare with supplied date Loop Until Day$(Str$(ChngWeek1)+Right$(dateNow$,8))=ChngDay$ Or n>31 If days < ChngWeek1 Then 'set DST flag dst = 1 Else dst = 0 EndIf EndIf If month = ChngMnth2 Then 'Second change month Do 'find the change day Inc ChngWeek2 'day number for change4, compare with supplied date Loop Until Day$(Str$(ChngWeek2)+Right$(dateNow$,8)) = ChngDay$ Or n>31 If days < ChngWeek2 Then 'set DST flag dst = 0 Else dst = 1 EndIf EndIf If hemi Then DST = Not DST 'adjust for hemisphere End Function 'Test program to verify change dates. Dim startdate$= "01-01-2024" Dim startday, tdate$, m ,dstchange = 1 startday = Epoch(startdate$+" 00:00:00")/86400 For m = 0 To 3660*2 tdate$ = Left$(DateTime$((startday+m)*86400),10) If dst(tdate$) <> dstchange Then dstchange = dst(tdate$) Print tdate$, Left$(Day$(tdate$),3), dst(tdate$) EndIf Next Footnote added 2025-03-02 15:34 by phil99 Was testing DST change in the last week of the month when I posted the above so change:- Local integer ChngWeek1 = 5, ChngWeek2 = 5 'Week of the month for change, use 5 for the last week of the month to:- Local integer ChngWeek1 = 1, ChngWeek2 = 1 'Week of the month for change, use 5 for the last week of the month to return to the first week. Footnote added 2025-03-03 06:56 by phil99 Extended testing shows an error in some years. Here is the amended section of code. If dateNow$="" Then dateNow$=Date$ 'if no date supplied use current date 'convert the 'change weeks' to start dates for finding the DST start/end days ChngWeek1 = (ChngWeek1 - 1) * 7 ChngWeek2 = (ChngWeek2 - 1) * 7 |
||||
palcal![]() Guru ![]() Joined: 12/10/2011 Location: AustraliaPosts: 1970 |
Maybe someone could put these in FOTS. "It is better to be ignorant and ask a stupid question than to be plain Stupid and not ask at all" |
||||
disco4now![]() Guru ![]() Joined: 18/12/2014 Location: AustraliaPosts: 983 |
I have updated FotS and put a link to this discussion. Latest F4 Latest H7 FotS |
||||
palcal![]() Guru ![]() Joined: 12/10/2011 Location: AustraliaPosts: 1970 |
@ TassyJim, what is this bit above the Function for ' DIM startdate$= "01-01-2024" DIM startday, tdate$,n,dstchange = 1 startday = EPOCH(startdate$+" 00:00:00")/86400 FOR n = 0 TO 3660 tdate$ = LEFT$(DATETIME$((startday+n)*86400),10) IF dst(tdate$) <> dstchange THEN dstchange = dst(tdate$) PRINT tdate$ ENDIF NEXT n "It is better to be ignorant and ask a stupid question than to be plain Stupid and not ask at all" |
||||
TassyJim![]() Guru ![]() Joined: 07/08/2011 Location: AustraliaPosts: 6230 |
That was just there to test for the next ~10 years. Might come in handy if someone needs to edit the change dates to suit their country. If I had done that first up, I would have found my initial error. Jim Edited 2025-03-02 10:47 by TassyJim VK7JH MMedit |
||||
TassyJim![]() Guru ![]() Joined: 07/08/2011 Location: AustraliaPosts: 6230 |
Last version. Should be easy to adapt for all countries. Not sure if US has cancelled DST yet. ' DST TassyJim March 2025 ' test for 10 years DIM startdate$= "01-01-2024" DIM startday, tdate$,n,dstchange = 1 startday = EPOCH(startdate$+" 00:00:00")/86400 FOR n = 0 TO 3660 tdate$ = LEFT$(DATETIME$((startday+n)*86400),10) IF dst(tdate$) <> dstchange THEN dstchange = dst(tdate$) PRINT tdate$, IF dstchange THEN PRINT "Start" ELSE PRINT "Finish" ENDIF NEXT n ' end of test code ' DST starts month1 and week1, ends month2 and week2 ' week = -1 for last Sunday in month ' week = 1 for first Sunday in month ' week = 2 for second Sunday in month FUNCTION dst(testDate$) LOCAL mth1start, mth2start, dst1, dst2, dst0, daynumnow LOCAL month1 = 10, week1 = 1,month2 = 4, week2 = 1 ' australia ' local month1 = 9, week1 = -1,month2 = 4, week2 = 1 ' NZ ' local month1 = 3, week1 = -1,month2 = 10, week2 = -1 ' UK and EU ' local month1 = 3, week1 = 2, month2 = 11, week2 = 1 ' Canada, US? IF week1 = -1 THEN month1 = month1 + 1 : week1 = 0 IF week2 = -1 THEN month2 = month2 + 1 : week2 = 0 week1 = week1 - 1 week2 = week2 - 1 IF testDate$ = "" THEN testDate$ = DATE$ daynumnow = EPOCH(testDate$+" 00:00:00")/86400 mth1start = EPOCH("01-"+STR$(month1,2,0,"0")+MID$(testDate$,6,5)+" 00:00:00")/86400 dst1 = (10-(mth1start MOD 7))MOD 7 dst1 = mth1start+dst1 +week1*7 mth2start = EPOCH("01-"+STR$(month2,2,0,"0")+MID$(testDate$,6,5)+" 00:00:00")/86400 dst2 = (10-(mth2start MOD 7))MOD 7 dst2 = mth2start+ dst2 +week2*7 IF dst1 > dst2 THEN dst0 = dst1 : dst1 = dst2 : dst2 = dst0 IF daynumnow < dst1 OR daynumnow >= dst2 THEN dst = 1 ELSE dst = 0 ENDIF IF mth1start < mth2start THEN dst = 1 - dst END FUNCTION Jim VK7JH MMedit |
||||
palcal![]() Guru ![]() Joined: 12/10/2011 Location: AustraliaPosts: 1970 |
@ TassyJim.... Thanks for these it is working well. "It is better to be ignorant and ask a stupid question than to be plain Stupid and not ask at all" |
||||
TassyJim![]() Guru ![]() Joined: 07/08/2011 Location: AustraliaPosts: 6230 |
Simplified the conditional statements. ' DST TassyJim March 2025 ' test for 10 years DIM startdate$= "01-01-2024" DIM startday, tdate$,n,dstchange = 1 startday = EPOCH(startdate$+" 00:00:00")/86400 FOR n = 0 TO 3660 tdate$ = LEFT$(DATETIME$((startday+n)*86400),10) IF dst(tdate$) <> dstchange THEN dstchange = dst(tdate$) PRINT tdate$, IF dstchange THEN PRINT "Start" ELSE PRINT "Finish" ENDIF NEXT n ' end of test code ' DST starts month1 and week1, ends month2 and week2 ' week = -1 for last Sunday in month ' week = 1 for first Sunday in month ' week = 2 for second Sunday in month FUNCTION dst(testDate$) LOCAL mth1start, mth2start, dst1, dst2, daynumnow ' Local month1 = 10, week1 = 1,month2 = 4, week2 = 1 ' Australia ' local month1 = 9, week1 = -1,month2 = 4, week2 = 1 ' NZ ' local month1 = 3, week1 = -1,month2 = 10, week2 = -1 ' UK and EU LOCAL month1 = 3, week1 = 2, month2 = 11, week2 = 1 ' Canada, US? IF week1 = -1 THEN month1 = month1 + 1 : week1 = 0 ' adjust for last sunday IF week2 = -1 THEN month2 = month2 + 1 : week2 = 0 week1 = week1 - 1 week2 = week2 - 1 IF testDate$ = "" THEN testDate$ = DATE$ daynumnow = EPOCH(testDate$+" 00:00:00")/86400 mth1start = EPOCH("01-"+STR$(month1,2,0,"0")+MID$(testDate$,6,5)+" 00:00:00")/86400 dst1 = (10-(mth1start MOD 7))MOD 7 dst1 = mth1start+dst1 +week1*7 mth2start = EPOCH("01-"+STR$(month2,2,0,"0")+MID$(testDate$,6,5)+" 00:00:00")/86400 dst2 = (10-(mth2start MOD 7))MOD 7 dst2 = mth2start+ dst2 +week2*7 IF dst1 < dst2 AND daynumnow >= dst1 AND daynumnow < dst2 THEN dst = 1 ELSEIF dst1 > dst2 AND (daynumnow >= dst1 OR daynumnow < dst2) THEN dst = 1 ELSE dst = 0 ENDIF END FUNCTION Jim VK7JH MMedit |
||||
![]() ![]() |
![]() |
![]() |
The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2025 |