Replies

@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.

@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
}