go to post Keshav Iyer · Sep 1, 2020 @Julius Kavay Thanks for catching that! I had only tested with UTC time when I posted that. Have updated the code in the previous comment to account for roll over of hours/days. Regarding your second point, I agree that validation should be done before processing the data. I have moved validation to the beginning of the method. Currently I don't have a use case for having validation be in its own method but if I do later, it would be easy to refactor it out from this method.
go to post Keshav Iyer · Sep 1, 2020 @Vic Sun @Julius Kavay Thanks! I wanted to stay away from using Ens classes because by namespace may not map from ENSLIB. I did the following for conversion and used DATEDIFF for comparison: ClassMethod ConvertW3CToTimestampUTC(pDateTime As %String) As %TimeStamp { Set date = $Piece(pDateTime, "T", 1) Set time = $Piece(pDateTime, "T", 2) // Validation Set containsPlus = ($Find(time, "+") > 0) Set containsMinus = ($Find(time, "-") > 0) Set containsZ = ($Find(time, "Z") > 0) If ((containsPlus + containsZ + containsMinus) > 1) { $$$ThrowStatus($$$ERROR($$$GeneralError, "Invalid time format. Cannot contain multiple timezone offset formats")) } If ((containsPlus + containsZ + containsMinus) = 0) { $$$ThrowStatus($$$ERROR($$$GeneralError, "Invalid time format. Missing timezone offset")) } Set parsedTime = "" Set dateAdd = "" // Obtain UTC time If containsZ { Set parsedTime = $Extract(time, 1, *-1) } Else { Set operator = $Case(containsPlus, 1: "+", : "-") Set absTime = $Piece(time, operator, 1) Set offset = $Piece(time, operator, 2) Set $ListBuild(offsetHours, offsetMinutes) = $ListFromString(offset, ":") Set offsetHours = "-"_operator_offsetHours Set offsetMinutes = "-"_operator_offsetMinutes Set $ListBuild(hours, minutes, seconds) = $ListFromString(absTime, ":") Set computedMinutes = minutes + offsetMinutes Set netMinutes = computedMinutes#60 Set hoursAdd = $Case((computedMinutes < 0), 1: -1, : $Case((computedMinutes >= 60), 1: 1, : 0)) Set computedHours = (hours + offsetHours + hoursAdd) Set netHours = computedHours#24 Set dateAdd = $Case((computedHours < 0), 1: -1, : $Case((computedHours >= 24), 1: 1, : 0)) // Add padding of 0's if needed If ($Length(netHours) = 1) { Set netHours = "0"_netHours } If ($Length(netMinutes) = 1) { Set netMinutes = "0"_netMinutes } Set parsedTime = netHours_":"_netMinutes_":"_seconds } Set dateTime = date_" "_parsedTime If (dateAdd '= "") { // Adjust date Set dateTime = $System.SQL.DATEADD("day", dateAdd, dateTime) } Return dateTime }