Question
· Jan 10, 2023

How to use Regular expression to replace all ODBC datetime occurences in a String to UTC datetime format?

Hi guys,

 

Suppose I have a JSON string as below:

{"MessageID":"11111","save_date1":"2022-02-02 01:01:34","Sender_ID1":"esb","sent_date2":"1985-12-11 11:42:00"}

The two date variables are all formatted as ODBC date time, when I tried to import it to a %JSON.Adapter object, the date format was rejected as below

Error #9406:Unexpected format for value of field, save_date1, using class base mapping

 

Thus I'm trying to format all possible ODBC date time in the incoming JSON with Regular expression:

ClassMethod DateTimeFormatter(input As %String) As %String
{
    Set strTgt = input
    set r = "(([0-9]{4}-[0-9]{2}-[0-9]{2}) ([0-9]{2}:[0-9]{2}:[0-9]{2}))"
    set m=##class(%Regex.Matcher).%New(r, strTgt)
    while m.Locate(){
        set strTgt = m.ReplaceFirst("$2T$3Z")
        set m=##class(%Regex.Matcher).%New(r, strTgt)
    }
    Quit strTgt
}

As can be seen, so far I initialized %Regex.Matcher many times to format each of the occurences of  the ODBC dates. I wonder how may I write the regular expression or alter the loop thus I can initiate %Regex.Matcher once and format all the occurences?

 

Thanks.

Product version: IRIS 2022.1
Discussion (2)1
Log in or sign up to continue

I would not recommend regexp for that. If you have one place with such a date, you can use transient/calculated property pair:

Class User.JSON Extends (%RegisteredObject, %JSON.Adaptor)
{

Property tsjson As %String(%JSONFIELDNAME = "ts") [ Transient ];

Property ts As %TimeStamp(%JSONINCLUDE = "none") [ SqlComputeCode = {set {*}=$replace({tsjson}," ", "T")_"Z"}, SqlComputed ];

/// d ##class(User.JSON).Test()
ClassMethod Test()
{
	set json = {"ts":"2022-02-02 01:01:34"}
	set obj = ..%New()
	zw obj.%JSONImport(json)
	w "ts:" _ obj.ts
}

}

If you have a lot of json properties,  use a custom datatype to do automatic conversion:

Class User.JSONTS Extends %Library.TimeStamp
{

ClassMethod IsValidDT(%val As %RawString) As %Status
{
    /// replace it with a real check
    q $$$OK
}

/// Converts the Objectscript value to the JSON number value.
ClassMethod JSONToLogical(%val As %Decimal) As %String [ CodeMode = generator, ServerOnly = 1 ]
{
    /// $replace({tsjson}," ", "T")_"Z"
    If 1,($$$getClassType(%class)=$$$cCLASSCLASSTYPEDATATYPE) || $$$comMemberKeyGet(%class,$$$cCLASSparameter,"%JSONENABLED",$$$cPARAMdefault) {
        Set %codemode=$$$cMETHCODEMODEEXPRESSION
        Set %code="$replace(%val,"" "", ""T"")_""Z"""
    } Else {
        Set %code=0 
    }
    Quit $$$OK
}

}

And use it instead of the standard timestamp:

Class User.JSON Extends (%RegisteredObject, %JSON.Adaptor)
{

Property ts As User.JSONTS;

/// d ##class(User.JSON).Test()
ClassMethod Test()
{
	set json = {"ts":"2022-02-02 01:01:34"}
	set obj = ..%New()
	zw obj.%JSONImport(json)
	w "ts:" _ obj.ts
}

}