DIUTC ;O-OIFO/ALA/LG - UTC Timezone API ;Dec 16, 2015 10:00 AM
;;22.2;VA FileMan;**2,21**;Jan 05, 2016;Build 4
;;Per VA Directive 6402, this routine should not be modified.
;
UTC(DTM,TMZ,INST,CNTRY,EXT) ;PEP - Return UTC value
;
; Input Parameters - DATE/TIME (DTM) is (*REQUIRED*) all other parameters are (Optional)
;
; DTM - Standard Date/Time; FileMan Internal and External; FileMan-specific e.g. NOW, T+1@12A
; TMZ - TimeZone ? Either Full Name (e.g., EASTERN; EASTERN EUPOREAN; ESTONIA; YUKON)
; or Pointer to the WORLD TIMEZONE (#1.71) file.
; Note: Time Zone Abbreviation (e.g. EST) can be ambiguous so is not used
; INST - Pointer to Institution (#4) file
; CNTRY - Country Name or Pointer to the COUNTRY CODE (#779.004) file.
; If Country Name is passed in, it must match the name in the HL7 COUNTRY file
; EXT - Extended return value
; Null=Default returns GMT with offset (internal FM format)
; 1 returns GMT with offset (internal FM format) with additional external values (multi-part)
;
; Output
; returns GMT with offset (internal FM format), if EXT=1 returns additional external values
;
;
N %DT,XX,H,M,X,Y
N CODE,DTME,GMT,GMTE,GMTO,INSTE,OFF,TMFRM,TMZE,CNTRYE,TMZEXC
;
; get values for all possible parameters
F XX="DTM","TMZ","INST","CNTRY","EXT" S @XX=$G(@XX)
;
I DTM="" Q -1_"^Date/Time parameter is missing."
I '$P(DTM,".",2) Q -1_"^Date/Time parameter missing time." ;p21
I INST]"",(TMZ]""!(CNTRY]"")) Q -1_"^Institution parameter cannot include Country or Timezone parameter."
I TMZ]"",CNTRY="" Q -1_"^Timezone parameter must include Country parameter."
I CNTRY]"",TMZ="" Q -1_"^Country parameter must include Timezone parameter."
I EXT'="",(EXT'=1) Q -1_"^Extended parameter must be NULL or a 1 for extended output."
;
S %DT="RSTX",X=DTM D ^%DT
I Y<0 Q Y_"^Invalid Date/Time"
S DTM=$E(Y_"00000",1,14)
S Y=DTM D DD^%DT S DTME=Y ; External Date/Time
;
; Find offset if timezone and country parameteres are passed
I TMZ]"" D ;
. I +TMZ'=TMZ S TMZ=$$FIND1^DIC(1.71,"","X",TMZ,"","","ERROR")
. S TMZE=$$GET1^DIQ(1.71,TMZ_",",.01,"E")
I CNTRY]"" D ;
. I +CNTRY'=CNTRY S CNTRY=$$FIND1^DIC(779.004,"","MX",CNTRY,"D","","ERROR")
;
; If no timezone param, no country param, look for institution param
; If the institution param exists get values:
; institution (external), timezone (internal/external), country (internal), timezone exception (internal)
; If no institution param, try to get data from default instituion stored in DUZ(2)
I TMZ="",CNTRY="" N MSG D I $D(MSG) Q -1_MSG
. I INST D Q ; if Institution is passed get data from Institution file #4
. . S INSTE=$$GET1^DIQ(4,INST_",",.01,"E")
. . S TMZ=$$GET1^DIQ(4,INST_",",800,"I")
. . S TMZE=$$GET1^DIQ(4,INST_",",800,"E")
. . S CNTRY=$$GET1^DIQ(4,INST_",",801,"I")
. . S TMZEXC=$$GET1^DIQ(4,INST_",",802,"I")
. . I 'TMZ!'CNTRY S MSG="^Cannot determine Country and Timezone from the Institution."
. ; if Institution not passed try default Institution in DUZ(2)
. I +$G(DUZ(2))=0 S MSG="^Cannot determine User location." Q ; quit if DUZ(2) not defined with message
. S INSTE=$$GET1^DIQ(4,+DUZ(2)_",",.01,"E")
. S TMZ=$$GET1^DIQ(4,+DUZ(2)_",",800,"I")
. S TMZE=$$GET1^DIQ(4,+DUZ(2)_",",800,"E")
. S CNTRY=$$GET1^DIQ(4,+DUZ(2)_",",801,"I")
. S TMZEXC=$$GET1^DIQ(4,+DUZ(2)_",",802,"I")
. I 'TMZ!'CNTRY S MSG="^Cannot determine Country and Timezone from User location."
;
; uppercase the external value for Country from Description field (#2) in file (#779.004)
I CNTRY S CNTRYE=$$UP^XLFSTR($$GET1^DIQ(779.004,CNTRY_",",2,"E"))
;
I 'TMZ Q -1_"^Invalid Timezone."
I 'CNTRY Q -1_"^Invalid Country."
I '$D(^DIT(1.71,"AB",CNTRY,TMZ)) Q -1_"^Mismatch of Country and Timezone."
;
D CHECKDST ; check for daylight savings, standard, or summer timeframe
D GMT ; convert input time to Greenwich Mean Time based on Offset
;
; Quit with GMT+Offset only (internal value)
I 'EXT Q GMT_GMTO
;
; Quit with "Extended" output
Q GMT_GMTO_U_GMTE_" (UTC"_OFF_")"_U_OFF_U_$G(TMZE)_U_$G(CNTRYE)_U_$G(CODE)_U_$G(TMFRM)_U_$G(INSTE)
;
;GMT+OFFSET ^ GMT+OFFSET EXT ^ OFFSET ^ TIMEZONE EXT ^ COUTRY EXT ^ TIMEZONE ABBREV ^ TIMEFRAME EXT (DAYLIGHT,STANDARD,SUMMER) ^ INSTITUTION EXT
;
GMT ; calculate GMT time
;
I '$D(OFF) Q ; quit if we don't have the Offset
;
S H=$E(OFF,2,3),M=$E(OFF,4,5) ; get hour and minutes from GMT offset
S H=$TR($E(OFF),"-+","+-")_H
S M=$TR($E(OFF),"-+","+-")_M
S GMT=$$FMADD^XLFDT(DTM,,H,M,) ; GMT internal Date/Time value
S GMT=$E(GMT_"00000",1,14)
S Y=GMT D DD^%DT S GMTE=Y ; GMT External Date/Time value
S GMTO=OFF,M=$E(GMTO,4,5)
S GMTO=$E(GMTO,1,3)*60+M/5+500
;(+/-hours x 60 + minutes) / 5 = value then 500 +/- value = offset
;
; massage offset for output
S OFF=$E(OFF,1,3)_":"_$E(OFF,4,5)
Q
;
CHECKDST ;
; Check if this timezone changes to daylight (or summer) time or not
; (TDST=1, DOES NOT CHANGE, TDST=0, does change)
;
N TDST,SIEN,DIEN,CIEN,DSIEN,YEAR,YIEN,STAN,SDTM,EDTM,DST,DSAV,SAME
;
S TDST=1
S SIEN=$O(^DIT(1.71,TMZ,1,"B","SST",""))
S DIEN=$O(^DIT(1.71,TMZ,1,"B","DST",""))
I 'DIEN S DIEN=$O(^DIT(1.71,TMZ,1,"B","SUM",""))
I DIEN S CIEN=$O(^DIT(1.71,TMZ,1,DIEN,1,"B",CNTRY,""))
I $G(CIEN) S TDST=0,DST=1
I '$G(CIEN) S TDST=1
; If the timezone does not change, then DST would be zero for standard time (SST)
I $G(TDST) S DST=0
; retrieve the offset for daylight savings (DST=1) OR standard (DST=0)
S STAN=^DIT(1.71,TMZ,1,SIEN,0) I DIEN'="" S DSAV=^DIT(1.71,TMZ,1,DIEN,0)
I 'TDST D
. S DSIEN=$O(^DIT(1.72,"B",CNTRY,""))
. I 'DSIEN Q ; quit if country timeframes not found in world daylight savings file #1.72
. S SAME=$P(^DIT(1.72,DSIEN,0),"^",3)
. I SAME'="" S DSIEN=$O(^DIT(1.72,"B",SAME,""))
;
; using the year from the date, determine the start and end date/time of world daylight savings from file #1.72
I $G(DSIEN) D
. S YEAR=$P($$FMTE^XLFDT(DTM\1,5),"/",3)
. S YIEN=$O(^DIT(1.72,DSIEN,1,"B",YEAR,""))
. I YIEN'="" S SDTM=$P(^DIT(1.72,DSIEN,1,YIEN,0),"^",2),EDTM=$P(^(0),"^",3)
. I YIEN="" Q ; quit if year data not found
. ; if DST=1, daylight savings in affect, DST=0, standard time in affect
. I DTM<SDTM!(DTM'<EDTM) S DST=0
. I DTM'<SDTM,DTM<EDTM S DST=1
;
I $G(TMZEXC)=0 S DST=0 ; Timezone Exception from Institution file #4
;
I 'DST S OFF=$P(STAN,"^",2),CODE=$P(STAN,"^",3),TMFRM=$P(STAN,U)
I DST S OFF=$P(DSAV,"^",2),CODE=$P(DSAV,"^",3),TMFRM=$P(DSAV,U)
S TMFRM=$S(TMFRM="SST":"STANDARD",TMFRM="DST":"DAYLIGHT SAVINGS",TMFRM="SUM":"SUMMER",1:"") ; set Timeframe
Q
--- Routine Detail --- with STRUCTURED ROUTINE LISTING ---[H[J[2J[HDIUTC 6730 printed Oct 16, 2024@18:55:14 Page 2
DIUTC ;O-OIFO/ALA/LG - UTC Timezone API ;Dec 16, 2015 10:00 AM
+1 ;;22.2;VA FileMan;**2,21**;Jan 05, 2016;Build 4
+2 ;;Per VA Directive 6402, this routine should not be modified.
+3 ;
UTC(DTM,TMZ,INST,CNTRY,EXT) ;PEP - Return UTC value
+1 ;
+2 ; Input Parameters - DATE/TIME (DTM) is (*REQUIRED*) all other parameters are (Optional)
+3 ;
+4 ; DTM - Standard Date/Time; FileMan Internal and External; FileMan-specific e.g. NOW, T+1@12A
+5 ; TMZ - TimeZone ? Either Full Name (e.g., EASTERN; EASTERN EUPOREAN; ESTONIA; YUKON)
+6 ; or Pointer to the WORLD TIMEZONE (#1.71) file.
+7 ; Note: Time Zone Abbreviation (e.g. EST) can be ambiguous so is not used
+8 ; INST - Pointer to Institution (#4) file
+9 ; CNTRY - Country Name or Pointer to the COUNTRY CODE (#779.004) file.
+10 ; If Country Name is passed in, it must match the name in the HL7 COUNTRY file
+11 ; EXT - Extended return value
+12 ; Null=Default returns GMT with offset (internal FM format)
+13 ; 1 returns GMT with offset (internal FM format) with additional external values (multi-part)
+14 ;
+15 ; Output
+16 ; returns GMT with offset (internal FM format), if EXT=1 returns additional external values
+17 ;
+18 ;
+19 NEW %DT,XX,H,M,X,Y
+20 NEW CODE,DTME,GMT,GMTE,GMTO,INSTE,OFF,TMFRM,TMZE,CNTRYE,TMZEXC
+21 ;
+22 ; get values for all possible parameters
+23 FOR XX="DTM","TMZ","INST","CNTRY","EXT"
SET @XX=$GET(@XX)
+24 ;
+25 IF DTM=""
QUIT -1_"^Date/Time parameter is missing."
+26 ;p21
IF '$PIECE(DTM,".",2)
QUIT -1_"^Date/Time parameter missing time."
+27 IF INST]""
IF (TMZ]""!(CNTRY]""))
QUIT -1_"^Institution parameter cannot include Country or Timezone parameter."
+28 IF TMZ]""
IF CNTRY=""
QUIT -1_"^Timezone parameter must include Country parameter."
+29 IF CNTRY]""
IF TMZ=""
QUIT -1_"^Country parameter must include Timezone parameter."
+30 IF EXT'=""
IF (EXT'=1)
QUIT -1_"^Extended parameter must be NULL or a 1 for extended output."
+31 ;
+32 SET %DT="RSTX"
SET X=DTM
DO ^%DT
+33 IF Y<0
QUIT Y_"^Invalid Date/Time"
+34 SET DTM=$EXTRACT(Y_"00000",1,14)
+35 ; External Date/Time
SET Y=DTM
DO DD^%DT
SET DTME=Y
+36 ;
+37 ; Find offset if timezone and country parameteres are passed
+38 ;
IF TMZ]""
Begin DoDot:1
+39 IF +TMZ'=TMZ
SET TMZ=$$FIND1^DIC(1.71,"","X",TMZ,"","","ERROR")
+40 SET TMZE=$$GET1^DIQ(1.71,TMZ_",",.01,"E")
End DoDot:1
+41 ;
IF CNTRY]""
Begin DoDot:1
+42 IF +CNTRY'=CNTRY
SET CNTRY=$$FIND1^DIC(779.004,"","MX",CNTRY,"D","","ERROR")
End DoDot:1
+43 ;
+44 ; If no timezone param, no country param, look for institution param
+45 ; If the institution param exists get values:
+46 ; institution (external), timezone (internal/external), country (internal), timezone exception (internal)
+47 ; If no institution param, try to get data from default instituion stored in DUZ(2)
+48 IF TMZ=""
IF CNTRY=""
NEW MSG
Begin DoDot:1
+49 ; if Institution is passed get data from Institution file #4
IF INST
Begin DoDot:2
+50 SET INSTE=$$GET1^DIQ(4,INST_",",.01,"E")
+51 SET TMZ=$$GET1^DIQ(4,INST_",",800,"I")
+52 SET TMZE=$$GET1^DIQ(4,INST_",",800,"E")
+53 SET CNTRY=$$GET1^DIQ(4,INST_",",801,"I")
+54 SET TMZEXC=$$GET1^DIQ(4,INST_",",802,"I")
+55 IF 'TMZ!'CNTRY
SET MSG="^Cannot determine Country and Timezone from the Institution."
End DoDot:2
QUIT
+56 ; if Institution not passed try default Institution in DUZ(2)
+57 ; quit if DUZ(2) not defined with message
IF +$GET(DUZ(2))=0
SET MSG="^Cannot determine User location."
QUIT
+58 SET INSTE=$$GET1^DIQ(4,+DUZ(2)_",",.01,"E")
+59 SET TMZ=$$GET1^DIQ(4,+DUZ(2)_",",800,"I")
+60 SET TMZE=$$GET1^DIQ(4,+DUZ(2)_",",800,"E")
+61 SET CNTRY=$$GET1^DIQ(4,+DUZ(2)_",",801,"I")
+62 SET TMZEXC=$$GET1^DIQ(4,+DUZ(2)_",",802,"I")
+63 IF 'TMZ!'CNTRY
SET MSG="^Cannot determine Country and Timezone from User location."
End DoDot:1
IF $DATA(MSG)
QUIT -1_MSG
+64 ;
+65 ; uppercase the external value for Country from Description field (#2) in file (#779.004)
+66 IF CNTRY
SET CNTRYE=$$UP^XLFSTR($$GET1^DIQ(779.004,CNTRY_",",2,"E"))
+67 ;
+68 IF 'TMZ
QUIT -1_"^Invalid Timezone."
+69 IF 'CNTRY
QUIT -1_"^Invalid Country."
+70 IF '$DATA(^DIT(1.71,"AB",CNTRY,TMZ))
QUIT -1_"^Mismatch of Country and Timezone."
+71 ;
+72 ; check for daylight savings, standard, or summer timeframe
DO CHECKDST
+73 ; convert input time to Greenwich Mean Time based on Offset
DO GMT
+74 ;
+75 ; Quit with GMT+Offset only (internal value)
+76 IF 'EXT
QUIT GMT_GMTO
+77 ;
+78 ; Quit with "Extended" output
+79 QUIT GMT_GMTO_U_GMTE_" (UTC"_OFF_")"_U_OFF_U_$GET(TMZE)_U_$GET(CNTRYE)_U_$GET(CODE)_U_$GET(TMFRM)_U_$GET(INSTE)
+80 ;
+81 ;GMT+OFFSET ^ GMT+OFFSET EXT ^ OFFSET ^ TIMEZONE EXT ^ COUTRY EXT ^ TIMEZONE ABBREV ^ TIMEFRAME EXT (DAYLIGHT,STANDARD,SUMMER) ^ INSTITUTION EXT
+82 ;
GMT ; calculate GMT time
+1 ;
+2 ; quit if we don't have the Offset
IF '$DATA(OFF)
QUIT
+3 ;
+4 ; get hour and minutes from GMT offset
SET H=$EXTRACT(OFF,2,3)
SET M=$EXTRACT(OFF,4,5)
+5 SET H=$TRANSLATE($EXTRACT(OFF),"-+","+-")_H
+6 SET M=$TRANSLATE($EXTRACT(OFF),"-+","+-")_M
+7 ; GMT internal Date/Time value
SET GMT=$$FMADD^XLFDT(DTM,,H,M,)
+8 SET GMT=$EXTRACT(GMT_"00000",1,14)
+9 ; GMT External Date/Time value
SET Y=GMT
DO DD^%DT
SET GMTE=Y
+10 SET GMTO=OFF
SET M=$EXTRACT(GMTO,4,5)
+11 SET GMTO=$EXTRACT(GMTO,1,3)*60+M/5+500
+12 ;(+/-hours x 60 + minutes) / 5 = value then 500 +/- value = offset
+13 ;
+14 ; massage offset for output
+15 SET OFF=$EXTRACT(OFF,1,3)_":"_$EXTRACT(OFF,4,5)
+16 QUIT
+17 ;
CHECKDST ;
+1 ; Check if this timezone changes to daylight (or summer) time or not
+2 ; (TDST=1, DOES NOT CHANGE, TDST=0, does change)
+3 ;
+4 NEW TDST,SIEN,DIEN,CIEN,DSIEN,YEAR,YIEN,STAN,SDTM,EDTM,DST,DSAV,SAME
+5 ;
+6 SET TDST=1
+7 SET SIEN=$ORDER(^DIT(1.71,TMZ,1,"B","SST",""))
+8 SET DIEN=$ORDER(^DIT(1.71,TMZ,1,"B","DST",""))
+9 IF 'DIEN
SET DIEN=$ORDER(^DIT(1.71,TMZ,1,"B","SUM",""))
+10 IF DIEN
SET CIEN=$ORDER(^DIT(1.71,TMZ,1,DIEN,1,"B",CNTRY,""))
+11 IF $GET(CIEN)
SET TDST=0
SET DST=1
+12 IF '$GET(CIEN)
SET TDST=1
+13 ; If the timezone does not change, then DST would be zero for standard time (SST)
+14 IF $GET(TDST)
SET DST=0
+15 ; retrieve the offset for daylight savings (DST=1) OR standard (DST=0)
+16 SET STAN=^DIT(1.71,TMZ,1,SIEN,0)
IF DIEN'=""
SET DSAV=^DIT(1.71,TMZ,1,DIEN,0)
+17 IF 'TDST
Begin DoDot:1
+18 SET DSIEN=$ORDER(^DIT(1.72,"B",CNTRY,""))
+19 ; quit if country timeframes not found in world daylight savings file #1.72
IF 'DSIEN
QUIT
+20 SET SAME=$PIECE(^DIT(1.72,DSIEN,0),"^",3)
+21 IF SAME'=""
SET DSIEN=$ORDER(^DIT(1.72,"B",SAME,""))
End DoDot:1
+22 ;
+23 ; using the year from the date, determine the start and end date/time of world daylight savings from file #1.72
+24 IF $GET(DSIEN)
Begin DoDot:1
+25 SET YEAR=$PIECE($$FMTE^XLFDT(DTM\1,5),"/",3)
+26 SET YIEN=$ORDER(^DIT(1.72,DSIEN,1,"B",YEAR,""))
+27 IF YIEN'=""
SET SDTM=$PIECE(^DIT(1.72,DSIEN,1,YIEN,0),"^",2)
SET EDTM=$PIECE(^(0),"^",3)
+28 ; quit if year data not found
IF YIEN=""
QUIT
+29 ; if DST=1, daylight savings in affect, DST=0, standard time in affect
+30 IF DTM<SDTM!(DTM'<EDTM)
SET DST=0
+31 IF DTM'<SDTM
IF DTM<EDTM
SET DST=1
End DoDot:1
+32 ;
+33 ; Timezone Exception from Institution file #4
IF $GET(TMZEXC)=0
SET DST=0
+34 ;
+35 IF 'DST
SET OFF=$PIECE(STAN,"^",2)
SET CODE=$PIECE(STAN,"^",3)
SET TMFRM=$PIECE(STAN,U)
+36 IF DST
SET OFF=$PIECE(DSAV,"^",2)
SET CODE=$PIECE(DSAV,"^",3)
SET TMFRM=$PIECE(DSAV,U)
+37 ; set Timeframe
SET TMFRM=$SELECT(TMFRM="SST":"STANDARD",TMFRM="DST":"DAYLIGHT SAVINGS",TMFRM="SUM":"SUMMER",1:"")
+38 QUIT