![]() |
Forum Index : Microcontroller and PC projects : Daylight Saving
Page 1 of 2 ![]() ![]() |
|||||
Author | Message | ||||
palcal![]() Guru ![]() Joined: 12/10/2011 Location: AustraliaPosts: 1970 |
FOTS has a daylight saving function Here This is for the UK where DS starts and ends on the Last Sunday for different months to Australia. It's beyond me to change this for our region. Has anyone changed this for Australia or have another function for DS. "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 |
Adjusted for southern hemisphere in this thread Latest F4 Latest H7 FotS |
||||
palcal![]() Guru ![]() Joined: 12/10/2011 Location: AustraliaPosts: 1970 |
Thanks for that, will try. "It is better to be ignorant and ask a stupid question than to be plain Stupid and not ask at all" |
||||
phil99![]() Guru ![]() Joined: 11/02/2018 Location: AustraliaPosts: 2457 |
It would appear that program preceded the addition of the inbuilt DAY$() function. Finding the first Sunday may be easier with something like:- If Day$(Date$) = "Sunday" then ... |
||||
palcal![]() Guru ![]() Joined: 12/10/2011 Location: AustraliaPosts: 1970 |
I did have a SUB using that, but it didn't work too well so before I tried anything, I thought I would ask. I need something that if power is applied after DS has started it still recognised. Edited 2025-02-28 08:56 by palcal "It is better to be ignorant and ask a stupid question than to be plain Stupid and not ask at all" |
||||
GerryL Newbie ![]() Joined: 24/01/2019 Location: AustraliaPosts: 36 |
here is an alternative that I have extracted from my original weather station program, the sub test at the bottom was a check to see it worked on rollover in April and October. The only changes you would need is the CONSTANTS of cSTD_TIME_ZONE and CDTS_TIME_ZONE dim integer gn_UTCHour dim integer gn_UTCMin dim integer gn_UTCSec dim integer gn_UTCDate dim integer gn_UTCMonth dim integer gn_UTCYear dim integer gn_UTCDay dim integer gn_LocalHour dim integer gn_LocalDate dim integer gn_LocalMonth dim integer gn_LocalYear dim integer gn_LocalDay dim integer gn_LocalMins dim integer gn_LocalSecs ' time conversion CONST cSTD_TIME_ZONE = 9.5 ' Adelaide CONST CDTS_TIME_ZONE = 10.5 CONST cSTANDARD_TIME_ZONE = cSTD_TIME_ZONE * 3600 ' + seconds, (i.e South Australia Central Standard Time, +9.5 Hrs from Z time) Const cLOCAL_TIME = 1 Const cZULU_TIME = 2 ' GMT, time zone =0 FUNCTION GetDSTStart(ls_Year as String, ln_TimeType as Integer) as integer ' returns time in seconds since 1970 of the actual first second of DST ' DST start occurs at 0200 local on First Sunday in October or 1630Z on Saturday just prior to First Sunday in October ' ls_Year is the year for the calculation in format of "yyyy" ' ln_TimeType determines what the start time will be referenced to, i.e. Zulu (GMT) or local time. local as integer ln_Start ln_Start = EPOCH("01-10-" + ls_Year + " 02:00:00") + GetOffsetSeconds(ls_Year, "10") ' 2am first sunday of October if ln_TimeType = cZULU_TIME then ln_Start = ln_Start - cSTANDARD_TIME_ZONE '1630Z on Sat prior to first Sunday of Oct GetDSTStart = ln_Start end Function FUNCTION GetDSTEnd(ls_Year as String, ln_TimeType as Integer) as integer ' returns time in seconds since 1970 of the actual first second of Standard Time (non DST period) in UTC (Z or GMT Time) ' DST end occurs at 0300 local on First Sunday in April or 1630 UTC on Saturday just prior to First Sunday in April ' ls_Year is the year for the calculation in format of "yyyy" local as integer ln_End ln_End = EPOCH("01-04-" + ls_Year + " 03:00:00") + GetOffsetSeconds(ls_Year, "04") ' 3am fist sunday of April if ln_TimeType = cZULU_TIME then ln_End = ln_End - cSTANDARD_TIME_ZONE - 3600 '1630Z on Sat prior to first Sunday of month GetDSTEnd = ln_End end Function Function GetOffsetSeconds(ls_Year as String, ls_Month as String) as integer ' returns time in seconds since 1970 of the actual first second of Standard Time (non DST period) in UTC (Z or GMT Time) 'e.g if month starts on a Monday then returns 86400 *6, Tuesday is 86400 * 5, Sunday = 0 local as integer ln_Offset local as String ls_Day ls_Day = DAY$("01-" + ls_Month + "-" + ls_Year) SELECT CASE ls_Day CASE "Sunday" ln_Offset = 0 CASE "Monday" ln_Offset = 1 CASE "Tuesday" ln_Offset = 2 CASE "Wednesday" ln_Offset = 3 CASE "Thursday" ln_Offset = 4 CASE "Friday" ln_Offset = 5 CASE "Saturday" ln_Offset = 6 CASE ELSE ln_Offset = 0 ' error if here END SELECT if ln_Offset <> 0 then ln_Offset = 7 - ln_Offset ln_Offset = ln_Offset * 86400 ' now seconds endif GetOffsetSeconds = ln_Offset End Function SUB StringUTCtoLocal (sYear as string, sDateTime as string) ' sYear as 20xx, sDateTime = dd-mm-yyyy hh:mm:ss local as integer ln_UTCTime, ln_StartDST, ln_EndDST, ln_LocalTime ln_StartDST = GetDSTStart(sYear,cZULU_TIME) 'Oct ln_EndDST = GetDSTEnd(sYear, cZULU_TIME) 'April 'print "date time = ",sDateTime ln_UTCTime = EPOCH(sDateTime) 'print "UTC = ", ln_UTCTime, " Start = ",ln_StartDST, "End = ", ln_EndDST if ln_UTCTime < ln_StartDST AND ln_UTCTime > ln_EndDST then 'less than oct and more than april gf_LocalTimeZone =cSTD_TIME_ZONE else gf_LocalTimeZone = CDTS_TIME_ZONE end if ln_LocalTime = ln_UTCTime + gf_LocalTimeZone * 3600 sDateTime = DATETIME$(ln_LocalTime) ' dd-mm-yyyy hh:mm:ss ' print "date Time = ",ls_TempString1 gn_LocalDate = val(left$(sDateTime,2)) 'dd gn_LocalMonth = val(mid$(sDateTime,4,2)) 'month gn_LocalYear = val(mid$(sDateTime,7,4)) 'year, 4 digit gn_LocalHour = val(mid$(sDateTime,12,2)) 'hour gn_LocalMins = val(mid$(sDateTime,15,2)) 'min gn_LocalSecs = val(mid$(sDateTime,18,2)) END SUB SUB Test ' convert UTC to local StringUTCtoLocal ("2025", "05-04-2025 16:29:59") print "UTC Input = ","05-04-2025 16:29:59" print "LOCAL Out = ",gn_LocalDate, "-", gn_LocalMonth,"-",gn_LocalYear," ",gn_LocalHour,":",gn_LocalMins,":",gn_LocalSecs StringUTCtoLocal ("2025", "05-04-2025 16:30:01") print "UTC Input = ","05-04-2025 16:30:01" print "LOCAL Out = ",gn_LocalDate, "-", gn_LocalMonth,"-",gn_LocalYear," ",gn_LocalHour,":",gn_LocalMins,":",gn_LocalSecs StringUTCtoLocal ("2025", "04-10-2025 16:29:59") print "UTC Input = ","04-10-2025 16:29:59" print "LOCAL Out = ",gn_LocalDate, "-", gn_LocalMonth,"-",gn_LocalYear," ",gn_LocalHour,":",gn_LocalMins,":",gn_LocalSecs StringUTCtoLocal ("2025", "04-10-2025 16:30:01") print "UTC Input = ","04-10-2025 16:30:01" print "LOCAL Out = ",gn_LocalDate, "-", gn_LocalMonth,"-",gn_LocalYear," ",gn_LocalHour,":",gn_LocalMins,":",gn_LocalSecs End SUB Test |
||||
TassyJim![]() Guru ![]() Joined: 07/08/2011 Location: AustraliaPosts: 6230 |
' as shown, dst starts on the first sunday of April ' change the month in the mth1start line to suit and add 7 for second sunday etc. ' for last sunday, use the following month and subtract 7 from the dst1 ' ' do the same for mth2start and dst2 ' for the northern hemosphere. reverse the final IF statement FUNCTION dst() LOCAL mth1start, mth2start, dst1, dst2, dateNow$, daynumnow dateNow$ = DATE$ daynumnow = EPOCH(dateNow$+" 00:00:00")/86400 mth1start = EPOCH("01-04-"+MID$(dateNow$,7,4)+" 00:00:00")/86400 dst1 = 3-(mth1start MOD 7) dst1 = mth1start+dst1 ' first sunday in april in current year. add 7 for 2nd sunday mth2start = EPOCH("01-10-"+MID$(dateNow$,7,4)+" 00:00:00")/86400 dst2 = 3-(mth2start MOD 7) dst2 = mth2start+ dst2 ' first sunday in october in current year. add 7 for 2nd sunday IF daynumnow < dst1 OR daynumnow >= dst2 THEN ' swap for northern hemisphere dst = 1 ELSE dst = 0 ENDIF END FUNCTION Jim VK7JH MMedit |
||||
palcal![]() Guru ![]() Joined: 12/10/2011 Location: AustraliaPosts: 1970 |
Thanks all, I'll have a play around. "It is better to be ignorant and ask a stupid question than to be plain Stupid and not ask at all" |
||||
palcal![]() Guru ![]() Joined: 12/10/2011 Location: AustraliaPosts: 1970 |
@ TassyJim I tested your code by putting in a dummy date, it works OK BUT I had to change the last lines to IF daynumnow < dst1 OR daynumnow >= dst2 THEN ' swap for northern hemisphere dst = 0 ELSE dst = 1 ENDIF END FUNCTION I reversed dst = 0 and dst = 1 "It is better to be ignorant and ask a stupid question than to be plain Stupid and not ask at all" |
||||
phil99![]() Guru ![]() Joined: 11/02/2018 Location: AustraliaPosts: 2457 |
TassyJim's method is excellent, simpler than any other that I have seen. This version lets you put in any test date. If the brackets are empty it works as before. If you need to invert DST add DS = NOT DST() to your program. ' TassyJim's amended Daylight Saving function ' If a date (as a string) is specified such as "28/02/2025" it is used, else Date$ is uesd. ' as shown, dst starts on the first sunday of April ' change the month in the mth1start line to suit and add 7 for second sunday etc. ' for last sunday, use the following month and subtract 7 from the dst1 ' ' do the same for mth2start and dst2 ' for the northern hemosphere. reverse the final IF statement Function dst(TestDate$) Local mth1start, mth2start, dst1, dst2, dateNow$, daynumnow If TestDate$ = "" Then dateNow$ = Date$ Else dateNow$ = TestDate$ EndIf daynumnow = Epoch(dateNow$+" 00:00:00")/86400 mth1start = Epoch("01-04-"+Mid$(dateNow$,7,4)+" 00:00:00")/86400 dst1 = 3-(mth1start Mod 7) dst1 = mth1start+dst1 ' first sunday in april in current year. add 7 for 2nd sunday mth2start = Epoch("01-10-"+Mid$(dateNow$,7,4)+" 00:00:00")/86400 dst2 = 3-(mth2start Mod 7) dst2 = mth2start+ dst2 ' first sunday in october in current year. add 7 for 2nd sunday If daynumnow < dst1 Or daynumnow >= dst2 Then ' swap for northern hemisphere dst = 1 Else dst = 0 EndIf End Function > ? dst() 1 > ? dst("07-04-2025") 0 > > ? not dst() 0 > ? not dst("07-04-2025") 1 > Footnote added 2025-02-28 12:33 by phil99 Removed the extra variable, it is redundant. Function dst(dateNow$) Local mth1start, mth2start, dst1, dst2, daynumnow If dateNow$ = "" Then dateNow$ = Date$ Footnote added 2025-02-28 20:48 by phil99 > for n=22 to 31:d$=str$(n)+"-03-2025":? d$, dst(d$), day$(d$) :next 22-03-2025 1 Saturday 23-03-2025 1 Sunday 24-03-2025 1 Monday 25-03-2025 1 Tuesday 26-03-2025 1 Wednesday 27-03-2025 1 Thursday 28-03-2025 1 Friday 29-03-2025 1 Saturday 30-03-2025 0 Sunday 31-03-2025 0 Monday > |
||||
palcal![]() Guru ![]() Joined: 12/10/2011 Location: AustraliaPosts: 1970 |
My stupid mistake it starts in Oct so yes we are in DS now if you don't live in Qld. Edited 2025-02-28 11:53 by palcal "It is better to be ignorant and ask a stupid question than to be plain Stupid and not ask at all" |
||||
Turbo46![]() Guru ![]() Joined: 24/12/2017 Location: AustraliaPosts: 1636 |
You could see Geoff’s Super Clock for an example. Bill Keep safe. Live long and prosper. |
||||
palcal![]() Guru ![]() Joined: 12/10/2011 Location: AustraliaPosts: 1970 |
@ Turbo46....I looked at that but got lost in all the code. "It is better to be ignorant and ask a stupid question than to be plain Stupid and not ask at all" |
||||
CaptainBoing![]() Guru ![]() Joined: 07/09/2016 Location: United KingdomPosts: 2150 |
I have yet to see any garbage from him... the man's a machine! ![]() In my defence ![]() h Edited 2025-02-28 21:23 by CaptainBoing |
||||
phil99![]() Guru ![]() Joined: 11/02/2018 Location: AustraliaPosts: 2457 |
My last footnote shows DST ending on the last Sunday in March instead of the first in April. Something to look into. |
||||
TassyJim![]() Guru ![]() Joined: 07/08/2011 Location: AustraliaPosts: 6230 |
I will have to check the code. In Australia Daylight Saving Time (DST) is used in the Australian Capital Territory, New South Wales, South Australia, Tasmania, and Victoria. It starts the 1st Sunday of October and ends the 1st Sunday of April. This is a political decision so anything can happen to change those dates. I do have a pre epoch() version of the function somewhere... Jim Edited 2025-03-01 06:23 by TassyJim VK7JH MMedit |
||||
TassyJim![]() Guru ![]() Joined: 07/08/2011 Location: AustraliaPosts: 6230 |
I had over simplified the code. Should have left it alone... FUNCTION dst(TestDate$) LOCAL mth1start, mth2start, dst1, dst2, dateNow$, daynumnow IF TestDate$ = "" THEN dateNow$ = DATE$ ELSE dateNow$ = TestDate$ ENDIF daynumnow = EPOCH(dateNow$+" 00:00:00")/86400 mth1start = EPOCH("01-04-"+MID$(dateNow$,7,4)+" 00:00:00")/86400 dst1 = (10-(mth1start MOD 7)MOD 7) dst1 = mth1start+dst1 ' first sunday in april in current year. add 7 for 2nd sunday mth2start = EPOCH("01-10-"+MID$(dateNow$,7,4)+" 00:00:00")/86400 dst2 = (10-(mth2start MOD 7)MOD 7) dst2 = mth2start+ dst2 ' first sunday in october in current year. add 7 for 2nd sunday IF daynumnow < dst1 OR daynumnow >= dst2 THEN ' swap for northern hemisphere dst = 1 ELSE dst = 0 ENDIF END FUNCTION Jim VK7JH MMedit |
||||
phil99![]() Guru ![]() Joined: 11/02/2018 Location: AustraliaPosts: 2457 |
Perfect, tested April and October for next 4 years plus 2050. Streamlined my "If TestDate" add-on. Extra variable not needed Function dst(dateNow$) Local mth1start, mth2start, dst1, dst2, daynumnow If dateNow$ = "" Then dateNow$ = Date$ daynumnow = Epoch(dateNow$+" 00:00:00")/86400 mth1start = Epoch("01-04-"+Mid$(dateNow$,7,4)+" 00:00:00")/86400 dst1 = (10-(mth1start Mod 7)Mod 7) Inc dst1, mth1start ' first sunday in april in current year. add 7 for 2nd sunday mth2start = Epoch("01-10-"+Mid$(dateNow$,7,4)+" 00:00:00")/86400 dst2 = (10-(mth2start Mod 7)Mod 7) Inc dst2, mth2start ' first sunday in october in current year. add 7 for 2nd sunday If daynumnow < dst1 Or daynumnow >= dst2 Then ' swap for northern hemisphere dst = 1 Else dst = 0 EndIf End Function Edited 2025-03-01 07:23 by phil99 |
||||
TassyJim![]() Guru ![]() Joined: 07/08/2011 Location: AustraliaPosts: 6230 |
Sorry, still stuffed it. Bracket in wrong place. This is better: ' 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 FUNCTION dst(TestDate$) LOCAL mth1start, mth2start, dst1, dst2, dateNow$, daynumnow IF TestDate$ = "" THEN dateNow$ = DATE$ ELSE dateNow$ = TestDate$ ENDIF daynumnow = EPOCH(dateNow$+" 00:00:00")/86400 mth1start = EPOCH("01-04-"+MID$(dateNow$,7,4)+" 00:00:00")/86400 dst1 = (10-(mth1start MOD 7))MOD 7 dst1 = mth1start+dst1 ' first sunday in april in current year. add 7 for 2nd sunday mth2start = EPOCH("01-10-"+MID$(dateNow$,7,4)+" 00:00:00")/86400 dst2 = (10-(mth2start MOD 7))MOD 7 dst2 = mth2start+ dst2 ' first sunday in october in current year. add 7 for 2nd sunday IF daynumnow < dst1 OR daynumnow >= dst2 THEN ' swap for northern hemisphere dst = 1 ELSE dst = 0 ENDIF END FUNCTION VK7JH MMedit |
||||
TassyJim![]() Guru ![]() Joined: 07/08/2011 Location: AustraliaPosts: 6230 |
A version for the micromites without epoch() startdate$= "01-01-2024" dstchange = 1 startday = toJD(startdate$) FOR n = 0 TO 3660 tdate$ = datex$(startday+n) IF dstx(tdate$) <> dstchange THEN dstchange = dstx(tdate$) PRINT tdate$ ENDIF NEXT n FUNCTION dstx(dateNow$) AS INTEGER LOCAL INTEGER mth1start, mth2start, dst1, dst2, daynumnow IF dateNow$ = "" THEN dateNow$ = DATE$ ENDIF daynumnow = toJD(dateNow$) mth1start = toJD("01-04-"+MID$(dateNow$,7,4)) dst1 = (13-(mth1start MOD 7))MOD 7 dst1 = mth1start+dst1 ' first sunday in april in current year. add 7 for 2nd sunday mth2start = toJD("01-10-"+MID$(dateNow$,7,4)) dst2 = (13-(mth2start MOD 7))MOD 7 dst2 = mth2start+ dst2 ' first sunday in october in current year. add 7 for 2nd sunday IF daynumnow < dst1 OR daynumnow >= dst2 THEN ' swap for northern hemisphere dstx = 1 ELSE dstx = 0 ENDIF END FUNCTION FUNCTION toJD(myDate$)' valid for Gregorian dates after Oct 15, 1582 LOCAL d, m, y, ff d = VAL(LEFT$(myDate$,2)) m = VAL(MID$(myDate$,4,2)) y = VAL(RIGHT$(myDate$,4)) ff=FIX((m-14)/12) toJD = FIX((1461*(y+4800+ff))/4)+FIX((367*(m-2-12*ff))/12)-FIX((3*(FIX(y+4900+ff)/100))/4)+d-32075 END FUNCTION FUNCTION datex$(jd)' valid for Gregorian dates after Oct 15, 1582 LOCAL l,n,i,j,d,m,y l = jd+68569 n = FIX((4*l)/146097) l = l-FIX((146097*n+3)/4) i = FIX((4000*(l+1))/1461001) l = l-FIX((1461*i)/4)+31 j = FIX((80*l)/2447) d = l-FIX((2447*j)/80) l = FIX(j/11) m = j+2-(12*l) y = 100*(n-49)+i+l datex$ = STR$(d,2,0,"0")+"-"+STR$(m,2,0,"0")+"-"+STR$(y,2) END FUNCTION It should work with integers or floats. Jim VK7JH MMedit |
||||
Page 1 of 2 ![]() ![]() |
![]() |
![]() |
The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2025 |