Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 21:09 23 May 2025 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : Daylight Saving

     Page 2 of 2    
Author Message
phil99

Guru

Joined: 11/02/2018
Location: Australia
Posts: 2457
Posted: 11:45am 01 Mar 2025
Copy link to clipboard 
Print this post

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$)
 '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
Usage:-
> ? 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$)
 '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
Extended version of Jim's test program at the bottom.

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: Australia
Posts: 1970
Posted: 09:25pm 01 Mar 2025
Copy link to clipboard 
Print this post

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: Australia
Posts: 983
Posted: 09:40pm 01 Mar 2025
Copy link to clipboard 
Print this post

I have updated FotS and put a link to this discussion.
Latest F4 Latest H7 FotS
 
palcal

Guru

Joined: 12/10/2011
Location: Australia
Posts: 1970
Posted: 11:09pm 01 Mar 2025
Copy link to clipboard 
Print this post

@ 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: Australia
Posts: 6230
Posted: 12:46am 02 Mar 2025
Copy link to clipboard 
Print this post

  palcal said  @ TassyJim,  what is this bit above the Function for


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: Australia
Posts: 6230
Posted: 02:34am 02 Mar 2025
Copy link to clipboard 
Print this post

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: Australia
Posts: 1970
Posted: 03:25am 02 Mar 2025
Copy link to clipboard 
Print this post

@ 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: Australia
Posts: 6230
Posted: 04:19am 02 Mar 2025
Copy link to clipboard 
Print this post

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
 
     Page 2 of 2    
Print this page


To reply to this topic, you need to log in.

The Back Shed's forum code is written, and hosted, in Australia.
© JAQ Software 2025