From a65a038146db7161a195f404e6640c3a7e41a386 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Victor?= Date: Tue, 22 Jun 2021 13:34:53 +0200 Subject: [PATCH] Support for time zones and non-US DST Use bits in .RYEAR/.RLPDTM result to return a local time zone, TZONE (definable in SYSTEM;CONFIG). TZONE should be the integer timezone offset (hours West of UTC) Bit 4.4 => timezone known (otherwise, assume EST/EDT = 5) Bit 4.3 => sign bit of timezone offset Bits 3.5-3.1 => absolute value of timezone offset If DSTEU is defined and != 0, calculate daylight savings time according to European Union rules: - starts at 2:00 (standard time) on the last Sunday in March, - ends at 2:00 (standard time) on the last Sunday in October. --- src/klh/{out.251 => out.252} | 25 +++++++++-- src/syseng/{ctimsr.16 => ctimsr.17} | 13 +++++- src/syseng/{datime.74 => datime.75} | 70 ++++++++++++++++++++++++++--- src/syseng/timoon.25 | 42 ++++++++++++++--- src/system/{time.951 => time.952} | 35 ++++++++++++++- 5 files changed, 169 insertions(+), 16 deletions(-) rename src/klh/{out.251 => out.252} (99%) rename src/syseng/{ctimsr.16 => ctimsr.17} (91%) rename src/syseng/{datime.74 => datime.75} (96%) rename src/system/{time.951 => time.952} (91%) diff --git a/src/klh/out.251 b/src/klh/out.252 similarity index 99% rename from src/klh/out.251 rename to src/klh/out.252 index 0b476e74..c53294d6 100755 --- a/src/klh/out.251 +++ b/src/klh/out.252 @@ -2342,6 +2342,8 @@ IFN OS%TNX,[ MOVEM 2,TM.MIN(U2) MOVEM 3,TM.SEC(U2) LDB 1,[.BP ,4] ; Get timezone + trne 1,40 + orcmi 1,77 TLNE 4,(IC%ADS) ; If DST was applied TLO 1,-1 ; then put -1 in LH MOVEM 1,TM.ZON(U2) @@ -2608,13 +2610,28 @@ UTCBDA: IFN UTMAC-U2,PUSH P,U2 ? MOVE U2,UTMAC ; Ensure ptr in U2 UTZGET: PUSH P,U1 -IFN OS%ITS,MOVEI U1,5 ; All ITS systems are in EST +; No longer are all ITS systems in EST +IFN OS%ITS,[ +;; Support .RLPDTM/.RYEAR timezone hack + push p,2 + .ryear 2, + tlnn 2,10000 ;TZ known? + jrst utzgt5 ;No, assume 5 + ldb u1,[230400,,2] ;Yes, get it + tlne 2,4000 ;Negative offset? + movns u1 ;No, so negate it for bkwds compat + skipa +utzgt5: movei u1,5 + pop p,2 +] IFN OS%TNX,[ PUSHAE P,[2,3,4] SETO 2, SETZ 4, ODCNV LDB U1,[.BP IC%TMZ, 4] + trne u1,40 ;East of UTC? + orcmi u1,77 ;Extend POPAE P,[4,3,2] ] HRROM U1,UTZLV ; Store local time-zone value @@ -2627,8 +2644,10 @@ IFN OS%TNX,[ DEFINE TZONE STD,DST [ASCIZ /STD/],,[ASCIZ /DST/] TERMIN - -UTBZON: TZONE GMT,GMT ; 0 How to ask for British Summer Time?? + repeat 12.-2,TZONE ;Dunno -3..-12 + tzone EET,EEST ;-2 + tzone CET,CEST ;-1 +UTBZON: TZONE GMT,BST ; 0 How to ask for British Summer Time?? TZONE ; 1 TZONE ; 2 TZONE ; 3 (NST = Newfoundland is -0330) diff --git a/src/syseng/ctimsr.16 b/src/syseng/ctimsr.17 similarity index 91% rename from src/syseng/ctimsr.16 rename to src/syseng/ctimsr.17 index f7bf2223..479c64e0 100755 --- a/src/syseng/ctimsr.16 +++ b/src/syseng/ctimsr.17 @@ -99,6 +99,7 @@ GETTIM: .RLPDTM A, ; Get in A, # secs since beg of year. CAME A,[-1] CAMN B,[-1] JSR LOGOUT ; If either is -1, time not known. + push p,b ;[BV] save ryear result CAIGE B, ; If 4.9 on, SUBI A,24.*3600. ; subtract 1 day - .RLPDTM misfeature! TLNE B,100000 ; Bit 4.7 = Daylight Savings time? @@ -110,7 +111,17 @@ GETTIM: .RLPDTM A, ; Get in A, # secs since beg of year. ADDI B,(C) ; Plus # LY's, to get total days in years past. IMULI B,86400. ; Now get # seconds in all them days. ADD A,B ; and produce total seconds since 1/1/00 ! - ADD A,[GMTDIF*3600.] ; Adjust to GMT. + ;;[BV] TZ hack + pop p,c + tlnn c,10000 ; TZ known? + jrst getti0 ; no + ldb b,[230400,,c] ; Get absolute TZ + tlne c,4000 ; Negative? + movns b + skipa +getti0: movei b,GMTDIF ; Default TZ=5 + imuli b,3600. + add a,b POPJ P, TSINT: 0 ? 0 diff --git a/src/syseng/datime.74 b/src/syseng/datime.75 similarity index 96% rename from src/syseng/datime.74 rename to src/syseng/datime.75 index 91c6ed42..628b8ffc 100755 --- a/src/syseng/datime.74 +++ b/src/syseng/datime.75 @@ -179,9 +179,11 @@ TIMEXP: PUSH P,A PUSHJ P,IDAYL SETOM (P) TIMEX1: PUSHJ P,TIMENG - MOVE B,[440700,,[ASCIZ /-EST/]] + movei b,"- + idpb b,d + pushj p,timzst SKIPE (P) - MOVE B,[440700,,[ASCIZ /-EDT/]] ; Use EDT if DST in effect. + pushj p,timzds TIMEX2: ILDB A,B IDPB A,D CAIE A,"T @@ -335,9 +337,11 @@ LTME1: IDPB B,C IDPB B,C POP P,A ; Restore to test DST bit. - MOVE B,[440700,,[ASCIZ / EST/]] + movei b,40 + idpb b,c + pushj p,timzst TRNE A,TM%DST - MOVE B,[440700,,[ASCIZ / EDT/]] ; Use EDT if DST in effect. + pushj p,timzds ILDB A,B IDPB A,C ;note nice hack..makes asciz when done. JUMPN A,.-2 @@ -386,9 +390,11 @@ TIMRFC: PUSH P,A IDPB A,D MOVE A,-1(P) ;Recover time word. PUSHJ P,TIMASC ;Output "09:31:12". - MOVE B,[440700,,[ASCIZ / EST/]] + movei b,40 + idpb a,d + pushj p,timzst PUSHJ P,IDAYL - MOVE B,[440700,,[ASCIZ / EDT/]] + pushj p,timzds TIMRZN: ILDB A,B IDPB A,D ;Output " EST" CAIE A,"T @@ -399,6 +405,58 @@ TIMRZN: ILDB A,B ] ;end ifn $$rfc +;;; Routines for fetching time zone string +ifn $$OUTZ+$$DSTB+$$RFC,[ + +;; Get it for DST: return ASCBP to string in B +timzds: pushj p,timzon + hrrzs b + hrli b,440700 + popj p, + +;; Get it for standard time: return ASCBP to string in B +timzst: pushj p,timzon + hlrzs b + hrli b,440700 + popj p, + +timzon: push p,a + push p,c + .ryear c, + tlnn c,10000 ;TZ known? + jrst timz5 ;No, assume 5 = EST + ldb a,[230400,,c] ;Get absolute offset + tlne c,4000 ;Negate? + movns a ;Yes + skipa +timz5: movei a,5 + move b,tznam(a) + pop p,c + pop p,a + popj p, + +DEFINE TZONE STD,DST + [ASCIZ /STD/],,[ASCIZ /DST/] +TERMIN + repeat 12.-2,TZONE ;Dunno -3..-12 + tzone EET,EEST ;-2 + tzone CET,CEST ;-1 +tznam: TZONE GMT,BST ; 0 How to ask for British Summer Time?? + TZONE ; 1 + TZONE ; 2 + TZONE ; 3 (NST = Newfoundland is -0330) + TZONE AST,ADT ; 4 Atlantic + TZONE EST,EDT ; 5 Eastern + TZONE CST,CDT ; 6 Central + TZONE MST,MDT ; 7 Mountain + TZONE PST,PDT ; 8 Pacific + TZONE YST,YDT ; 9 Yukon + TZONE HST,HDT ; 10 Alaska-Hawaii + TZONE BST,BDT ; 11 Bering + REPEAT 24.-11.,TZONE ; 12-24 unspecified + +]; end ifn $$OUTZ+$$DSTB+$$RFC + ;;; Routines for fancy output of time. IFN $$OUTT,[ diff --git a/src/syseng/timoon.25 b/src/syseng/timoon.25 index eca93c33..b349949f 100755 --- a/src/syseng/timoon.25 +++ b/src/syseng/timoon.25 @@ -371,11 +371,23 @@ Merid: skiple verbose popj p, -; EST or EDT ? - MOVEI A,[ASCIZ / EDT/] - TLNN RYEAR,100000 - MOVEI A,[ASCIZ / EST/] - OASC (A) + ;; hack configured timezone + tlnn ryear,10000 ;TZ known? + jrst tz5 ;No, assume 5 = EST + ldb a,[230400,,ryear] ;Get absolute TZ + tlne ryear,4000 ;Negative? + movns a + skipa +tz5: movei a,5 + push p,b + hlrz b,tznam(a) ;Assume standard + tlne ryear,100000 ;DST? + hrrz b,tznam(a) ;Yes + skipe (b) + oasc [asciz / /] + oasc (b) + pop p,b +] popj p, @@ -531,6 +543,26 @@ MONTHR: [ASCIZ /uary/] MONLNG: 31. FEBRUA: 28. 31. ? 30. ? 31. ? 30. ? 31. ? 31. ? 30. ? 31. ? 30. ? 31. + +DEFINE TZONE STD,DST + [ASCIZ /STD/],,[ASCIZ /DST/] +TERMIN + repeat 12.-2,TZONE ;Dunno -3..-12 + tzone EET,EEST ;-2 + tzone CET,CEST ;-1 +tznam: TZONE GMT,BST ; 0 How to ask for British Summer Time?? + TZONE ; 1 + TZONE ; 2 + TZONE ; 3 (NST = Newfoundland is -0330) + TZONE AST,ADT ; 4 Atlantic + TZONE EST,EDT ; 5 Eastern + TZONE CST,CDT ; 6 Central + TZONE MST,MDT ; 7 Mountain + TZONE PST,PDT ; 8 Pacific + TZONE YST,YDT ; 9 Yukon + TZONE HST,HDT ; 10 Alaska-Hawaii + TZONE BST,BDT ; 11 Bering + REPEAT 24.-11.,TZONE ; 12-24 unspecified ; Type out the phase of the moon diff --git a/src/system/time.951 b/src/system/time.952 similarity index 91% rename from src/system/time.951 rename to src/system/time.952 index 4fbce58d..954e86b6 100644 --- a/src/system/time.951 +++ b/src/system/time.952 @@ -196,6 +196,19 @@ GLPDTM: CONO PI,CLKOFF ;AVOID DOUBLE YEAR INCREMENT PUSH P,A ;SAVE # SECONDS DURING NEXT CALL PUSHJ P,GDWOBY ;GET DAY OF WEEK OF BEGINNING OF YEAR (0 => SUNDAY) DPB B,[270300,,E] ;DEPOSIT IN RIGHT PLACE +IFDEF TZONE,[ + ;;[BV] timezone hack: + ;; 4.4 => Timezone known + ;; 4.3 => sign bit of timezone offset from UTC (hours West of UTC) + ;; 3.5-3.1 => absolute value of timezone offset from UTC (fixnum) + TLO E,10000 ;Set TZ known bit (4.4) +IFL TZONE,[ ;; negative offset + TLO E,4000 ;Set TZ sign bit (4.3) + MOVEI A,-TZONE +] +.ELSE MOVEI A,TZONE + DPB A,[230400,,E] ;3.5-3.1 is ABS(TZONE) +] POP P,A ;RESTORE A AOS (P) ;CAUSE RETURN TO SKIP @@ -204,12 +217,24 @@ GLPDTM: CONO PI,CLKOFF ;AVOID DOUBLE YEAR INCREMENT GLPDT2: JFCL ;POPJ FOR STD TIME ;JRST CRDDST FOR DAY LIGHT TIME ;JFCL "NORMAL" +IFDEF DSTEU,IFN DSTEU,[ + ;; [BV] hack DST for EU rules + CAML A,[>*SPD+7200.] ;If before 2am last Sunday in March, + CAML A,[*SPD+7200.] ;or after 2am Oct 31 (standard time!), + POPJ P, ;then obviously standard time + CAML A,[*SPD+7200.] ;If before 2am March 31, + CAML A,[>*SPD+7200.] ;or after 2am possbly last Sunday in October, + JRST GLPDT3 ;then we have to compute + ;; else it's obviously DST +] +.ELSE [ CAML A,[*SPD+7200.] ;IF BEFORE 2AM APR 1, CAML A,[*SPD+3600.] ;OR IF AFTER 1AM STANDARD TIME OCT 31, POPJ P, ;THEN OBVIOUSLY STANDARD TIME IS IN EFFECT CAML A,[*SPD+7200.] ;IF BEFORE 2AM APR 7 STANDARD TIME, CAML A,[*SPD+3600.] ;OR IF AFTER 1AM STANDARD TIME OCTOBER 25, JRST GLPDT3 ;THEN NOT OBVIOUS +] CRDDST: TLO E,100000 ;DAYLIGHT SAVINGS TIME, SET BIT IN E ADDI A,3600. ;CONTINUE TO LOCALIZE THE TIME THAT WILL BE RETURNED POPJ P, @@ -238,12 +263,20 @@ GLPDT3: PUSH P,A ;SAVE # SECS POP P,A ;DAYLIGHT SAVINGS TIME, RESTORE A JRST CRDDST ;MUNG A AND E AND RETURN +IFDEF DSTEU,IFN DSTEU,[ +CRDSB: 7200. ;In Mar changes at 2AM (standard time) + 7200. ;In October also changes at 2AM (standard time!) + +CRDTST: CAIGE A,> ;First possible last Sunday in March + CAIL A,> ;First possible last Sunday in October +] +.ELSE [ CRDSB: 7200. ;IN APR CHANGES AT 2AM EST 3600. ;IN OCTOBER CHANGES AT 1AM EST CRDTST: CAIGE A, CAIL A, - +] ;IF LEAP YEAR THEN SET BIT 4.8 OF E ;IF NOT LEAP YEAR THEN IF AFTER FEB 28 THEN SET BIT 4.9 OF E AND ADD SPD TO A