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.
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 } }
Yep, that will help them. Thanks Eduard.