SDES2UTDT ;ALB/TAW -Scheduling Encapsulation Utilities ;OCT 14,2025
;;5.3;Scheduling;**922**;13 Aug 1993;Build 7
;;Per VHA Directive 6402, this routine should not be modified
;
FMTISO(SDGMT,SDFMDT,SDCLINIC) ;convert internal fileman format to extended GMT
;INPUT SDFMDT - Fileman date/time
; SDCLINIC - OPT IEN from file 44
;OUTPUT -1 error occurred in translation
; GMT date/time in ISO 8601 extended format (No Errors)
;
N SDDTM,SDTIME,SDOFFSET,OFFSET
I +$G(SDFMDT)=0 S SDGMT="" Q
D FILEMANTOHL7^SDES2UTIL(.SDFMDT,.SDDTM)
I SDDTM<0 S SDGMT=-1 Q
S SDCLINIC=$G(SDCLINIC)
;Extract out date and convert to ISO 8601 extended format
S SDGMT=$E(SDDTM,1,4)_"-"_$E(SDDTM,5,6)_"-"_$E(SDDTM,7,8)
;if time is included, extract and convert to ISO 8601 external format
I $L(SDDTM)>8 D
.S SDTIME=$E(+SDDTM,9,99)
.;S SDTIME=$$REMOVEOFFSET(SDTIME)
.S SDTIME=$P(SDTIME,"-")
.S SDTIME=$P(SDTIME,"+")
.S SDTIME=$P(SDTIME,"Z")
.;append hour and min
.S SDGMT=SDGMT_"T"_$E(SDTIME,1,2)_":"_$E(SDTIME,3,4)
.;include seconds
.I $L(SDTIME)>4 S SDGMT=SDGMT_":"_$E(SDTIME,5,6)
.;
.D GETTZOFFSET^SDES2UTIL(.OFFSET,SDFMDT,1,SDCLINIC)
.I OFFSET=-1 S OFFSET=-9999
.;
.S SDGMT=SDGMT_OFFSET
I SDGMT["-9999" S SDGMT=-1
Q
;
ISOTFM(SDFMDTM,SDGMTDT,SDCLINIC) ;convert ISO 8601 extended GMT date/time to fileman format
;INPUT SDGMTDT - ISO 8601 extended GMT date/time
; SDCLINIC - OPT IEN from file 44
;OUTPUT -1 error occurred in translation
; FM date/time (No Errors)
;
N SDFM,SDTIME,X,Y,%DT,POP,TMPFM,SDOFFSET,SDISOOFFSET,VALID,SDISOTIME,ISOOFFSET
S (POP,SDOFFSET,TMPFM)=""
I $G(SDGMTDT)="" S SDFMDTM="" Q
;pattern match date(/time) for correctness
D VALIDISO(.VALID,SDGMTDT)
I 'VALID S SDFMDTM=-1 Q
S SDCLINIC=$G(SDCLINIC)
;extract out date, removing punctuation
S SDFM=$TR($P(SDGMTDT,"T"),"-")
;set parameters to validate date/time
S %DT="TXS"
;extract out time if entered, removing all punctuation except for TZ offset
S (SDTIME,SDISOTIME)=$P(SDGMTDT,"T",2)
I SDTIME'="" D
.;Must have a time zone offset
.I SDTIME'["Z",SDTIME'["+",SDTIME'["-" S POP=1 Q
.;exclude time if 0's else FMTE returns previous date with .24
.;S SDTIME=$$REMOVEOFFSET(SDTIME)
.S SDTIME=$P(SDTIME,"-")
.S SDTIME=$P(SDTIME,"+")
.S SDTIME=$P(SDTIME,"Z")
.S SDTIME=$P(SDTIME,".") ;No ractional seconds
.S SDTIME=$TR(SDTIME,":")
.I +SDTIME=0 Q
.;Get the correct offset
.;S TMPFM=$$CVTTOFM(SDGMTDT) ;Need a FM format of the ISO date that is passed in
.N X,Y,%DT
.S %DT=""
.S X=SDFM
.D ^%DT
.S TMPFM=Y
.I Y=-1 Q ;vse-2645 date is invalid so leave do dot logic and quit below
.; IF ZULU reset SDGMTDT to match system time
.I SDGMTDT["Z"!(SDGMTDT["+0000") D
..;S SDOFFSET=$$GETOFFSET(TMPFM,SDCLINIC)
..D GETTZOFFSET^SDES2UTIL(.SDOFFSET,TMPFM,1,SDCLINIC)
..I SDOFFSET=-1 S SDOFFSET=-9999
.E D
..;S SDISOOFFSET=$$GETISOOFFSET(SDGMTDT)
..S ISOOFFSET=$P(SDGMTDT,"+",2),SDISOOFFSET=""
..I ISOOFFSET'="" S SDISOOFFSET="+"_ISOOFFSET
..I SDISOOFFSET="" S SDISOOFFSET="-"_$P(SDISOTIME,"-",2)
..S SDISOOFFSET=$TR(SDISOOFFSET,":")
..;
..D GETOFFSETDIFF(.SDOFFSET,TMPFM,SDCLINIC,SDISOOFFSET,1)
.;Build HLT formatted date with offset (Flip the sign on offset)
.D FLIPOFFSET(.SDOFFSET)
.S SDFM=SDFM_SDTIME_SDOFFSET
I TMPFM=-1 S SDFMDTM=-1 Q
I SDFM["-9999"!(POP) S SDFMDTM=-1 Q
;
;convert date(/time) from HL7 format back to Fileman
I +SDOFFSET S SDFMDTM=$$HL7TFM^XLFDT(SDFM,"U")
I '(+SDOFFSET) S SDFMDTM=$$HL7TFM^XLFDT(SDFM)
Q:SDFMDTM<0 ;error occurred in conversion
;check validity of date (including leap year check)
S X=$$FMTE^XLFDT(SDFMDTM)
D ^%DT
S:Y<0 SDFMDTM=-1 ;date(/time) not valid
Q
;
REMOVEOFFSET(TIME,RETURN) ;
S RETURN=$P(TIME,"-")
S RETURN=$P(RETURN,"+")
S RETURN=$P(RETURN,"Z")
Q
;
GETISOOFFSET(DATE,ISOFOOSET) ;
N OFFSET
S ISOOFFSET=""
S OFFSET=$P(DATE,"+",2)
I OFFSET'="" S ISOOFFSET="+"_OFFSET
I ISOOFFSET="" S ISOOFFSET="-"_$P($P(DATE,"T",2),"-",2)
S ISOOFFSET=$TR(ISOOFFSET,":")
Q
GETOFFSET(DATE,SDCLINIC) ;
N OFFSET
S OFFSET=""
;Clinc can be in a different time zone
I $G(SDCLINIC) S OFFSET=$$GETTZOFFSET^SDESUTIL(DATE,SDCLINIC)
;get offset for VistA Instance
I OFFSET="" S OFFSET=$$GETTZOFFSET^SDESUTIL(DATE)
I OFFSET=-1 S OFFSET="BAD OFFSET"
Q OFFSET
;
GETOFFSETDIFF(OFFSET,DATE,SDCLINIC,SDISOOFFSET,VALIDDATE) ;Compare offsets and return the difference
N SDCLNOFFSET,SDSYSOFFSET,TMPOFFSET
S (OFFSET,SDCLNOFFSET)=""
;S (TMPOFFSET,SDSYSOFFSET)=$$GETOFFSET(DATE)
D GETTZOFFSET^SDES2UTIL(.SDSYSOFFSET,DATE,$G(VALIDDATE))
S TMPOFFSET=SDSYSOFFSET
;I $G(SDCLINIC) S (TMPOFFSET,SDCLNOFFSET)=$$GETOFFSET(DATE,SDCLINIC)
I $G(SDCLINIC) D GETTZOFFSET^SDES2UTIL(.SDCLNOFFSET,DATE,1,SDCLINIC) S TMPOFFSET=SDCLNOFFSET
I TMPOFFSET=-1 Q "-9999"
I $E(SDISOOFFSET)?1N S SDISOOFFSET="+"_SDISOOFFSET
;If called from ISOTFM and ISO offset is different from the Clinic/System offset
I $G(SDISOOFFSET)'="",SDISOOFFSET'=TMPOFFSET D
.S OFFSET=TMPOFFSET-SDISOOFFSET
;
I $G(SDISOOFFSET)="",SDSYSOFFSET'=SDCLNOFFSET D
.S OFFSET=SDCLNOFFSET-SDSYSOFFSET
S:OFFSET=0 OFFSET=""
Q
;
FLIPOFFSET(OFFSET) ;Need to flip the sign because HL7TFM will flip it back.
Q:+OFFSET=0 ""
I $E(OFFSET)="-" D
.S OFFSET=OFFSET*-1
.S OFFSET="+"_$E(10000+OFFSET,2,5)
E D
.S OFFSET="-"_$E(10000+OFFSET,2,5)
Q
;
CVTTOFM(D) ;
N X,Y,%DT
S %DT=""
S X=$P(D,"T")
D ^%DT
Q Y
;
;
FMTGMT(SDFMDT) ;convert internal fileman format to extended GMT
;initialize variables
;*****************************************************************
;INPUT SDFMDT - Fileman date/time
;OUTPUT -1 error occurred in translation
; GMT date/time in ISO 8601 extended format (No Errors)
;*****************************************************************
N SDDTM,SDGMT,SDTIME,SDOFFSET
S SDDTM=$$FMTHL7^XLFDT(SDFMDT)
Q:SDDTM<0 -1
;extract out date and convert to ISO 8601 extended format
S SDGMT=$E(SDDTM,1,4)_"-"_$E(SDDTM,5,6)_"-"_$E(SDDTM,7,8)
;if time is included, extract and convert to ISO 8601 external format
I $L(SDDTM)>8 D
.S SDTIME=$E(+SDDTM,9,99),SDOFFSET=$$TZ^XLFDT()
.;determine if seconds are included in time
.I $L(SDTIME)<5 D
..;no seconds included in date/time
..S SDGMT=SDGMT_"T"_$E(SDDTM,9,10)_":"_$E(SDDTM,11,99)
.;seconds included in date/time
.E S SDGMT=SDGMT_"T"_$E(SDTIME,1,2)_":"_$E(SDTIME,3,4)_":"_$E(SDTIME,5,6)_SDOFFSET
Q SDGMT
;
GMTTFM(SDGMTDT) ;convert ISO 8601 extended GMT date/time to fileman format
;initialize variables
;*****************************************************************
;INPUT SDGMTDT - ISO 8601 extended GMT date/time
;OUTPUT -1 error occurred in translation
; FM date/time (No Errors)
;*****************************************************************
N SDFM,SDTIME,SDOFFSET,SDFMDTM,X,Y,%DT
;get offset for VistA Instance
S SDOFFSET=$$TZ^XLFDT()
;pattern match date(/time) for correctness
Q:((SDGMTDT["T")&'(SDGMTDT?4N1"-"2N1"-"2N1"T"2N1":"2N.E)) -1
Q:((SDGMTDT'["T")&'(SDGMTDT?4N1"-"2N1"-"2N)) -1
;extract out date, removing punctuation
S SDFM=$E(SDGMTDT,1,4)_$E(SDGMTDT,6,7)_$E(SDGMTDT,9,10)
;set parameters to validate date/time
S %DT="TXS"
;extract out time if entered, removing all punctuation except for TZ offset
I SDGMTDT>10 D
.S SDTIME=$P($E(SDGMTDT,12,99),$E(SDOFFSET,1,1))
.;exclude time if 0's else FMTE returns previous date with .24
.Q:((SDTIME["00:00")!(SDTIME["00:00:00"))
.;determine if seconds are included in time
.I $L(SDTIME)<6 D
..;no seconds include in date/time
..S SDFM=SDFM_$E(SDGMTDT,12,13)_$E(SDGMTDT,15,99)
.;seconds included in date/time
.E S SDFM=SDFM_$E(SDTIME,1,2)_$E(SDTIME,4,5)_$E(SDTIME,7,8)_"-"_SDOFFSET
;convert date(/time) from HL7 format back to Fileman
S SDFMDTM=$$HL7TFM^XLFDT(SDFM)
Q:SDFMDTM<0 SDFMDTM ;error occurred in conversion
;check validity of date (including leap year check)
S X=$$FMTE^XLFDT(SDFMDTM)
D ^%DT
Q:Y<0 -1 ;date(/time) not valid
Q SDFMDTM
;
VALIDFMFORMAT(VALID,DATE) ;Is DATE a valind FileMan format
;Return 1=Yes
; 0=No
N X,Y,%DT
S %DT="T",VALID=0
I $G(DATE)="" Q
I $$FR^XLFDT(DATE) Q
S X=DATE D ^%DT
I Y=-1 Q
S VALID=1
Q
;
VALIDISO(VALID,DATE) ;Is DATE a valid ISO8601 format (e.g., 2022-01-12T13:21)
; Return
; 0 = not ISO8601 format
; 1 = ISO8601 format
N SDDATE,SDTIME,SDOFFSET,KEEPSDTIME
S VALID=0
I $G(DATE)="" Q
S SDDATE=$P(DATE,"T")
I SDDATE D
.;Validate date
.; YYYYMMDD, YYYY-MM-DD or YYYY-MM
.I SDDATE?6N Q ;YYYY-MM is not allowed
.S SDDATE=$TR(SDDATE,"-")
.I SDDATE?8N!(SDDATE?6N) S VALID=1
;
S (SDTIME,KEEPSDTIME)=$P(DATE,"T",2)
I VALID,SDTIME'="" D
.;Validate time (ignore seconds)
.; THH
.; THHMM or THH:MM
.; THHMMSS or THH:MM:SS
.S SDTIME=$P(SDTIME,"-")
.S SDTIME=$P(SDTIME,"+")
.S SDTIME=$P(SDTIME,"Z")
.S SDTIME=$P(SDTIME,".") ;Ignore seconds
.S SDTIME=$TR(SDTIME,":")
.I SDTIME'?6N,SDTIME'?4N,SDTIME'?2N S VALID=0 Q
.;Validate offset
.; Z
.; + or - followed by HH
.; + or - followed by HHMM or HH:MM
.I $E(DATE,$L(DATE))="Z" S VALID=1 Q
.S SDTIME=$TR(KEEPSDTIME,":")
.S SDOFFSET=$P(SDTIME,"+",2)
.I SDOFFSET'="" D Q
..I SDOFFSET'?2N,SDOFFSET'?4N S VALID=0
.S SDOFFSET=$P(SDTIME,"-",2)
.I SDOFFSET'="" D Q
..I SDOFFSET'?2N,SDOFFSET'?4N S VALID=0
Q
--- Routine Detail --- with STRUCTURED ROUTINE LISTING ---[H[J[2J[HSDES2UTDT 9447 printed Jan 29, 2026@15:54:01 Page 2
SDES2UTDT ;ALB/TAW -Scheduling Encapsulation Utilities ;OCT 14,2025
+1 ;;5.3;Scheduling;**922**;13 Aug 1993;Build 7
+2 ;;Per VHA Directive 6402, this routine should not be modified
+3 ;
FMTISO(SDGMT,SDFMDT,SDCLINIC) ;convert internal fileman format to extended GMT
+1 ;INPUT SDFMDT - Fileman date/time
+2 ; SDCLINIC - OPT IEN from file 44
+3 ;OUTPUT -1 error occurred in translation
+4 ; GMT date/time in ISO 8601 extended format (No Errors)
+5 ;
+6 NEW SDDTM,SDTIME,SDOFFSET,OFFSET
+7 IF +$GET(SDFMDT)=0
SET SDGMT=""
QUIT
+8 DO FILEMANTOHL7^SDES2UTIL(.SDFMDT,.SDDTM)
+9 IF SDDTM<0
SET SDGMT=-1
QUIT
+10 SET SDCLINIC=$GET(SDCLINIC)
+11 ;Extract out date and convert to ISO 8601 extended format
+12 SET SDGMT=$EXTRACT(SDDTM,1,4)_"-"_$EXTRACT(SDDTM,5,6)_"-"_$EXTRACT(SDDTM,7,8)
+13 ;if time is included, extract and convert to ISO 8601 external format
+14 IF $LENGTH(SDDTM)>8
Begin DoDot:1
+15 SET SDTIME=$EXTRACT(+SDDTM,9,99)
+16 ;S SDTIME=$$REMOVEOFFSET(SDTIME)
+17 SET SDTIME=$PIECE(SDTIME,"-")
+18 SET SDTIME=$PIECE(SDTIME,"+")
+19 SET SDTIME=$PIECE(SDTIME,"Z")
+20 ;append hour and min
+21 SET SDGMT=SDGMT_"T"_$EXTRACT(SDTIME,1,2)_":"_$EXTRACT(SDTIME,3,4)
+22 ;include seconds
+23 IF $LENGTH(SDTIME)>4
SET SDGMT=SDGMT_":"_$EXTRACT(SDTIME,5,6)
+24 ;
+25 DO GETTZOFFSET^SDES2UTIL(.OFFSET,SDFMDT,1,SDCLINIC)
+26 IF OFFSET=-1
SET OFFSET=-9999
+27 ;
+28 SET SDGMT=SDGMT_OFFSET
End DoDot:1
+29 IF SDGMT["-9999"
SET SDGMT=-1
+30 QUIT
+31 ;
ISOTFM(SDFMDTM,SDGMTDT,SDCLINIC) ;convert ISO 8601 extended GMT date/time to fileman format
+1 ;INPUT SDGMTDT - ISO 8601 extended GMT date/time
+2 ; SDCLINIC - OPT IEN from file 44
+3 ;OUTPUT -1 error occurred in translation
+4 ; FM date/time (No Errors)
+5 ;
+6 NEW SDFM,SDTIME,X,Y,%DT,POP,TMPFM,SDOFFSET,SDISOOFFSET,VALID,SDISOTIME,ISOOFFSET
+7 SET (POP,SDOFFSET,TMPFM)=""
+8 IF $GET(SDGMTDT)=""
SET SDFMDTM=""
QUIT
+9 ;pattern match date(/time) for correctness
+10 DO VALIDISO(.VALID,SDGMTDT)
+11 IF 'VALID
SET SDFMDTM=-1
QUIT
+12 SET SDCLINIC=$GET(SDCLINIC)
+13 ;extract out date, removing punctuation
+14 SET SDFM=$TRANSLATE($PIECE(SDGMTDT,"T"),"-")
+15 ;set parameters to validate date/time
+16 SET %DT="TXS"
+17 ;extract out time if entered, removing all punctuation except for TZ offset
+18 SET (SDTIME,SDISOTIME)=$PIECE(SDGMTDT,"T",2)
+19 IF SDTIME'=""
Begin DoDot:1
+20 ;Must have a time zone offset
+21 IF SDTIME'["Z"
IF SDTIME'["+"
IF SDTIME'["-"
SET POP=1
QUIT
+22 ;exclude time if 0's else FMTE returns previous date with .24
+23 ;S SDTIME=$$REMOVEOFFSET(SDTIME)
+24 SET SDTIME=$PIECE(SDTIME,"-")
+25 SET SDTIME=$PIECE(SDTIME,"+")
+26 SET SDTIME=$PIECE(SDTIME,"Z")
+27 ;No ractional seconds
SET SDTIME=$PIECE(SDTIME,".")
+28 SET SDTIME=$TRANSLATE(SDTIME,":")
+29 IF +SDTIME=0
QUIT
+30 ;Get the correct offset
+31 ;S TMPFM=$$CVTTOFM(SDGMTDT) ;Need a FM format of the ISO date that is passed in
+32 NEW X,Y,%DT
+33 SET %DT=""
+34 SET X=SDFM
+35 DO ^%DT
+36 SET TMPFM=Y
+37 ;vse-2645 date is invalid so leave do dot logic and quit below
IF Y=-1
QUIT
+38 ; IF ZULU reset SDGMTDT to match system time
+39 IF SDGMTDT["Z"!(SDGMTDT["+0000")
Begin DoDot:2
+40 ;S SDOFFSET=$$GETOFFSET(TMPFM,SDCLINIC)
+41 DO GETTZOFFSET^SDES2UTIL(.SDOFFSET,TMPFM,1,SDCLINIC)
+42 IF SDOFFSET=-1
SET SDOFFSET=-9999
End DoDot:2
+43 IF '$TEST
Begin DoDot:2
+44 ;S SDISOOFFSET=$$GETISOOFFSET(SDGMTDT)
+45 SET ISOOFFSET=$PIECE(SDGMTDT,"+",2)
SET SDISOOFFSET=""
+46 IF ISOOFFSET'=""
SET SDISOOFFSET="+"_ISOOFFSET
+47 IF SDISOOFFSET=""
SET SDISOOFFSET="-"_$PIECE(SDISOTIME,"-",2)
+48 SET SDISOOFFSET=$TRANSLATE(SDISOOFFSET,":")
+49 ;
+50 DO GETOFFSETDIFF(.SDOFFSET,TMPFM,SDCLINIC,SDISOOFFSET,1)
End DoDot:2
+51 ;Build HLT formatted date with offset (Flip the sign on offset)
+52 DO FLIPOFFSET(.SDOFFSET)
+53 SET SDFM=SDFM_SDTIME_SDOFFSET
End DoDot:1
+54 IF TMPFM=-1
SET SDFMDTM=-1
QUIT
+55 IF SDFM["-9999"!(POP)
SET SDFMDTM=-1
QUIT
+56 ;
+57 ;convert date(/time) from HL7 format back to Fileman
+58 IF +SDOFFSET
SET SDFMDTM=$$HL7TFM^XLFDT(SDFM,"U")
+59 IF '(+SDOFFSET)
SET SDFMDTM=$$HL7TFM^XLFDT(SDFM)
+60 ;error occurred in conversion
if SDFMDTM<0
QUIT
+61 ;check validity of date (including leap year check)
+62 SET X=$$FMTE^XLFDT(SDFMDTM)
+63 DO ^%DT
+64 ;date(/time) not valid
if Y<0
SET SDFMDTM=-1
+65 QUIT
+66 ;
REMOVEOFFSET(TIME,RETURN) ;
+1 SET RETURN=$PIECE(TIME,"-")
+2 SET RETURN=$PIECE(RETURN,"+")
+3 SET RETURN=$PIECE(RETURN,"Z")
+4 QUIT
+5 ;
GETISOOFFSET(DATE,ISOFOOSET) ;
+1 NEW OFFSET
+2 SET ISOOFFSET=""
+3 SET OFFSET=$PIECE(DATE,"+",2)
+4 IF OFFSET'=""
SET ISOOFFSET="+"_OFFSET
+5 IF ISOOFFSET=""
SET ISOOFFSET="-"_$PIECE($PIECE(DATE,"T",2),"-",2)
+6 SET ISOOFFSET=$TRANSLATE(ISOOFFSET,":")
+7 QUIT
GETOFFSET(DATE,SDCLINIC) ;
+1 NEW OFFSET
+2 SET OFFSET=""
+3 ;Clinc can be in a different time zone
+4 IF $GET(SDCLINIC)
SET OFFSET=$$GETTZOFFSET^SDESUTIL(DATE,SDCLINIC)
+5 ;get offset for VistA Instance
+6 IF OFFSET=""
SET OFFSET=$$GETTZOFFSET^SDESUTIL(DATE)
+7 IF OFFSET=-1
SET OFFSET="BAD OFFSET"
+8 QUIT OFFSET
+9 ;
GETOFFSETDIFF(OFFSET,DATE,SDCLINIC,SDISOOFFSET,VALIDDATE) ;Compare offsets and return the difference
+1 NEW SDCLNOFFSET,SDSYSOFFSET,TMPOFFSET
+2 SET (OFFSET,SDCLNOFFSET)=""
+3 ;S (TMPOFFSET,SDSYSOFFSET)=$$GETOFFSET(DATE)
+4 DO GETTZOFFSET^SDES2UTIL(.SDSYSOFFSET,DATE,$GET(VALIDDATE))
+5 SET TMPOFFSET=SDSYSOFFSET
+6 ;I $G(SDCLINIC) S (TMPOFFSET,SDCLNOFFSET)=$$GETOFFSET(DATE,SDCLINIC)
+7 IF $GET(SDCLINIC)
DO GETTZOFFSET^SDES2UTIL(.SDCLNOFFSET,DATE,1,SDCLINIC)
SET TMPOFFSET=SDCLNOFFSET
+8 IF TMPOFFSET=-1
QUIT "-9999"
+9 IF $EXTRACT(SDISOOFFSET)?1N
SET SDISOOFFSET="+"_SDISOOFFSET
+10 ;If called from ISOTFM and ISO offset is different from the Clinic/System offset
+11 IF $GET(SDISOOFFSET)'=""
IF SDISOOFFSET'=TMPOFFSET
Begin DoDot:1
+12 SET OFFSET=TMPOFFSET-SDISOOFFSET
End DoDot:1
+13 ;
+14 IF $GET(SDISOOFFSET)=""
IF SDSYSOFFSET'=SDCLNOFFSET
Begin DoDot:1
+15 SET OFFSET=SDCLNOFFSET-SDSYSOFFSET
End DoDot:1
+16 if OFFSET=0
SET OFFSET=""
+17 QUIT
+18 ;
FLIPOFFSET(OFFSET) ;Need to flip the sign because HL7TFM will flip it back.
+1 if +OFFSET=0
QUIT ""
+2 IF $EXTRACT(OFFSET)="-"
Begin DoDot:1
+3 SET OFFSET=OFFSET*-1
+4 SET OFFSET="+"_$EXTRACT(10000+OFFSET,2,5)
End DoDot:1
+5 IF '$TEST
Begin DoDot:1
+6 SET OFFSET="-"_$EXTRACT(10000+OFFSET,2,5)
End DoDot:1
+7 QUIT
+8 ;
CVTTOFM(D) ;
+1 NEW X,Y,%DT
+2 SET %DT=""
+3 SET X=$PIECE(D,"T")
+4 DO ^%DT
+5 QUIT Y
+6 ;
+7 ;
FMTGMT(SDFMDT) ;convert internal fileman format to extended GMT
+1 ;initialize variables
+2 ;*****************************************************************
+3 ;INPUT SDFMDT - Fileman date/time
+4 ;OUTPUT -1 error occurred in translation
+5 ; GMT date/time in ISO 8601 extended format (No Errors)
+6 ;*****************************************************************
+7 NEW SDDTM,SDGMT,SDTIME,SDOFFSET
+8 SET SDDTM=$$FMTHL7^XLFDT(SDFMDT)
+9 if SDDTM<0
QUIT -1
+10 ;extract out date and convert to ISO 8601 extended format
+11 SET SDGMT=$EXTRACT(SDDTM,1,4)_"-"_$EXTRACT(SDDTM,5,6)_"-"_$EXTRACT(SDDTM,7,8)
+12 ;if time is included, extract and convert to ISO 8601 external format
+13 IF $LENGTH(SDDTM)>8
Begin DoDot:1
+14 SET SDTIME=$EXTRACT(+SDDTM,9,99)
SET SDOFFSET=$$TZ^XLFDT()
+15 ;determine if seconds are included in time
+16 IF $LENGTH(SDTIME)<5
Begin DoDot:2
+17 ;no seconds included in date/time
+18 SET SDGMT=SDGMT_"T"_$EXTRACT(SDDTM,9,10)_":"_$EXTRACT(SDDTM,11,99)
End DoDot:2
+19 ;seconds included in date/time
+20 IF '$TEST
SET SDGMT=SDGMT_"T"_$EXTRACT(SDTIME,1,2)_":"_$EXTRACT(SDTIME,3,4)_":"_$EXTRACT(SDTIME,5,6)_SDOFFSET
End DoDot:1
+21 QUIT SDGMT
+22 ;
GMTTFM(SDGMTDT) ;convert ISO 8601 extended GMT date/time to fileman format
+1 ;initialize variables
+2 ;*****************************************************************
+3 ;INPUT SDGMTDT - ISO 8601 extended GMT date/time
+4 ;OUTPUT -1 error occurred in translation
+5 ; FM date/time (No Errors)
+6 ;*****************************************************************
+7 NEW SDFM,SDTIME,SDOFFSET,SDFMDTM,X,Y,%DT
+8 ;get offset for VistA Instance
+9 SET SDOFFSET=$$TZ^XLFDT()
+10 ;pattern match date(/time) for correctness
+11 if ((SDGMTDT["T")&'(SDGMTDT?4N1"-"2N1"-"2N1"T"2N1"
QUIT -1
+12 if ((SDGMTDT'["T")&'(SDGMTDT?4N1"-"2N1"-"2N))
QUIT -1
+13 ;extract out date, removing punctuation
+14 SET SDFM=$EXTRACT(SDGMTDT,1,4)_$EXTRACT(SDGMTDT,6,7)_$EXTRACT(SDGMTDT,9,10)
+15 ;set parameters to validate date/time
+16 SET %DT="TXS"
+17 ;extract out time if entered, removing all punctuation except for TZ offset
+18 IF SDGMTDT>10
Begin DoDot:1
+19 SET SDTIME=$PIECE($EXTRACT(SDGMTDT,12,99),$EXTRACT(SDOFFSET,1,1))
+20 ;exclude time if 0's else FMTE returns previous date with .24
+21 if ((SDTIME["00
QUIT
+22 ;determine if seconds are included in time
+23 IF $LENGTH(SDTIME)<6
Begin DoDot:2
+24 ;no seconds include in date/time
+25 SET SDFM=SDFM_$EXTRACT(SDGMTDT,12,13)_$EXTRACT(SDGMTDT,15,99)
End DoDot:2
+26 ;seconds included in date/time
+27 IF '$TEST
SET SDFM=SDFM_$EXTRACT(SDTIME,1,2)_$EXTRACT(SDTIME,4,5)_$EXTRACT(SDTIME,7,8)_"-"_SDOFFSET
End DoDot:1
+28 ;convert date(/time) from HL7 format back to Fileman
+29 SET SDFMDTM=$$HL7TFM^XLFDT(SDFM)
+30 ;error occurred in conversion
if SDFMDTM<0
QUIT SDFMDTM
+31 ;check validity of date (including leap year check)
+32 SET X=$$FMTE^XLFDT(SDFMDTM)
+33 DO ^%DT
+34 ;date(/time) not valid
if Y<0
QUIT -1
+35 QUIT SDFMDTM
+36 ;
VALIDFMFORMAT(VALID,DATE) ;Is DATE a valind FileMan format
+1 ;Return 1=Yes
+2 ; 0=No
+3 NEW X,Y,%DT
+4 SET %DT="T"
SET VALID=0
+5 IF $GET(DATE)=""
QUIT
+6 IF $$FR^XLFDT(DATE)
QUIT
+7 SET X=DATE
DO ^%DT
+8 IF Y=-1
QUIT
+9 SET VALID=1
+10 QUIT
+11 ;
VALIDISO(VALID,DATE) ;Is DATE a valid ISO8601 format (e.g., 2022-01-12T13:21)
+1 ; Return
+2 ; 0 = not ISO8601 format
+3 ; 1 = ISO8601 format
+4 NEW SDDATE,SDTIME,SDOFFSET,KEEPSDTIME
+5 SET VALID=0
+6 IF $GET(DATE)=""
QUIT
+7 SET SDDATE=$PIECE(DATE,"T")
+8 IF SDDATE
Begin DoDot:1
+9 ;Validate date
+10 ; YYYYMMDD, YYYY-MM-DD or YYYY-MM
+11 ;YYYY-MM is not allowed
IF SDDATE?6N
QUIT
+12 SET SDDATE=$TRANSLATE(SDDATE,"-")
+13 IF SDDATE?8N!(SDDATE?6N)
SET VALID=1
End DoDot:1
+14 ;
+15 SET (SDTIME,KEEPSDTIME)=$PIECE(DATE,"T",2)
+16 IF VALID
IF SDTIME'=""
Begin DoDot:1
+17 ;Validate time (ignore seconds)
+18 ; THH
+19 ; THHMM or THH:MM
+20 ; THHMMSS or THH:MM:SS
+21 SET SDTIME=$PIECE(SDTIME,"-")
+22 SET SDTIME=$PIECE(SDTIME,"+")
+23 SET SDTIME=$PIECE(SDTIME,"Z")
+24 ;Ignore seconds
SET SDTIME=$PIECE(SDTIME,".")
+25 SET SDTIME=$TRANSLATE(SDTIME,":")
+26 IF SDTIME'?6N
IF SDTIME'?4N
IF SDTIME'?2N
SET VALID=0
QUIT
+27 ;Validate offset
+28 ; Z
+29 ; + or - followed by HH
+30 ; + or - followed by HHMM or HH:MM
+31 IF $EXTRACT(DATE,$LENGTH(DATE))="Z"
SET VALID=1
QUIT
+32 SET SDTIME=$TRANSLATE(KEEPSDTIME,":")
+33 SET SDOFFSET=$PIECE(SDTIME,"+",2)
+34 IF SDOFFSET'=""
Begin DoDot:2
+35 IF SDOFFSET'?2N
IF SDOFFSET'?4N
SET VALID=0
End DoDot:2
QUIT
+36 SET SDOFFSET=$PIECE(SDTIME,"-",2)
+37 IF SDOFFSET'=""
Begin DoDot:2
+38 IF SDOFFSET'?2N
IF SDOFFSET'?4N
SET VALID=0
End DoDot:2
QUIT
End DoDot:1
+39 QUIT