[3.14] jsonDecode fails for time datatype

Discussions about product bugs & problems!
Note: This is no replacement for the Official ETM Support!
5 posts • Page 1 of 1
moto3101
Posts:37
Joined: Tue Aug 22, 2017 2:04 pm

[3.14] jsonDecode fails for time datatype

Post by moto3101 »

Hello all,

we are dealing with a serious problem with the jsonEncode(...) and jsonDecode(...) function. I have prepared a small example:

Code: Select all

public void testTimeJson() {
  
  time t; 
  t = makeTime(2020,01,10,15,38,12);

  DebugTN("saved Time:", t);
  string tJson = jsonEncode(t);
  
  DebugTN("json String:" ,tJson);

  //First test using dyn_anytype first and then cast to time
  dyn_anytype decoded1 = jsonDecode(tJson);
  DebugTN("decoded1:",decoded1);
  time decodedTime1 = (time)decoded1[1]; 
  DebugTN("decodedTime1:",decodedTime1);
 
 //Second test, direct cast to time 
  time decodedTime2 = jsonDecode(tJson);
  DebugTN("decodedTime2:",decodedTime2);
}
The output in the log viewer is as follows:

Code: Select all

WCCOAui      (2), 2020.01.10 14:55:03.882, CTRL, WARNING,     5/ctrl, Ort der folgenden Meldung: 
    Module: _QuickTest_
    Panel: ..testJson.xml []
    Script: Initialize
    In panel scope library: testJson.xml []
    Line: 19
WCCOAui      (2), 2020.01.10 14:55:03.882, IMPL, WARNING,    50, Default branch called, TimeVar, operator=, cannot assign variable of type DYNANYTYPE_VAR
WCCOAui2:2020.01.10 14:55:03.882["saved Time:"][2020.01.10 15:38:12.000000000]
WCCOAui2:2020.01.10 14:55:03.882["json String:"]["[\"2020-01-10T14:38:12.000Z\"]"]
WCCOAui2:2020.01.10 14:55:03.882["decoded1:"][dyn_anytype 1 items
WCCOAui2:     1: "2020-01-10T14:38:12.000Z"
WCCOAui2:]
WCCOAui2:2020.01.10 14:55:03.882["decodedTime1:"][2020.01.10 23:38:12.000000000]
WCCOAui2:2020.01.10 14:55:03.902["decodedTime2:"][1970.01.01 01:00:00.000000000]
So, somehow WinCC fails to correctly decode the time, which prevents us from using this function for all data which contain timestamps.

Is this an error or are we using the wrong way to decode the time?

Thanks and with best regards,
moTo
Last edited by moto3101 on Mon Jan 13, 2020 10:36 am, edited 1 time in total.

leoknipp
Posts:2928
Joined: Tue Aug 24, 2010 7:28 pm

Re: [3.14] jsonDecode fails for time datatype

Post by leoknipp »

The return value of the function jsonDecode is of type anytype and not dyn_anytype.
Please use the correct variable types.

Best Regards
Leopold Knipp
Senior Support Specialist

moto3101
Posts:37
Joined: Tue Aug 22, 2017 2:04 pm

Re: [3.14] jsonDecode fails for time datatype

Post by moto3101 »

Dear Leo,
thanks for your reply.
I tried it with both anytype and dyn_anytype. Both datatypes do not work. If you debug the returned object of jsonDecode, the log viewer indicates that it returns a dyn_anytype (thats why I tried it with dyn_anytype).

Code: Select all

 time t; 
  t = makeTime(2020,01,10,15,38,12);

  DebugTN("Time t:", t);
  string tJson = jsonEncode(t);
  
  DebugTN("json String:" ,tJson);

  anytype decoded1 = jsonDecode(tJson);
  DebugTN("decodedJsonObject:",jsonDecode(tJson));
  time decodedTime1 = (time)decoded1; 
  DebugTN("decodedTime1:",decodedTime1);
  
You even get a warning due to an assignment error when using anytype:

Code: Select all

Output:
WCCOAui      (3), 2020.01.13 10:33:45.385, CTRL, WARNING,     5/ctrl, Ort der folgenden Meldung: 
    Module: _QuickTest_
    Panel: ...testJson.xml []
    Script: Initialize
    In panel scope library: testJson.xml []
    Line: 68
WCCOAui      (3), 2020.01.13 10:33:45.385, IMPL, WARNING,    50, Default branch called, TimeVar, operator=, cannot assign variable of type DYNANYTYPE_VAR

WCCOAui3:2020.01.13 10:33:45.385["Time t:"][2020.01.10 15:38:12.000000000]
WCCOAui3:2020.01.13 10:33:45.385["json String:"]["[\"2020-01-10T14:38:12.000Z\"]"]
WCCOAui3:2020.01.13 10:33:45.385["decodedJsonObject:"][dyn_anytype 1 items
WCCOAui3:     1: "2020-01-10T14:38:12.000Z"
WCCOAui3:]
WCCOAui3:2020.01.13 10:33:45.393["decodedTime1:"][1970.01.01 01:00:00.000000000]


However, independent of the datatype being used, the time is never parsed back correctly.

leoknipp
Posts:2928
Joined: Tue Aug 24, 2010 7:28 pm

Re: [3.14] jsonDecode fails for time datatype

Post by leoknipp »

I have tested it with the following script and it worked without any problems:

main()
{
time t;
t = makeTime(2020,01,10,15,38,12);

DebugTN("saved Time:", t);
string tJson = jsonEncode(t);

DebugTN("json String:" ,tJson);

//First test using dyn_anytype first and then cast to time
anytype decoded1 = jsonDecode(tJson);
DebugTN("decoded1:",decoded1);
}

When reading the times in the debug messages you have to take into account that a variable of type "time" is automatically converted to a string variable when using the Debug* functions.
A time converted to a string is then shown in local time format. Therefore you will get a deviation (if your time zone is not UTC) between the time shown at the debug message and the time stored in the JSON string.

Best Regards
Leopold Knipp
Senior Support Specialist

dbindernagel
Posts:161
Joined: Mon Feb 23, 2015 1:34 pm

Re: [3.14] jsonDecode fails for time datatype

Post by dbindernagel »

The problem is how the jsonEncode function handles "single values".
From the help file:
The function jsonEncode() encodes a variable (of any type) as a string (a dyn_ datatype as JSON array or a mapping as JSON object).
Thus, you can pass either a dyn_data type, a mapping, a simple value, an enum or a class/struct. A mapping is only allowed with string keys.
Other data types are handled as a 1 element dyn_ array of its type. Passing the int value 1, for example, is the same as if you would pass makeDynInt(1).
Since JSON only understands numeric and string data types, most of the WinCC OA data types are converted to strings.


So if you pass a variable of type time the function converts the time variable to a string and puts it in a dyn.
If you want to get the correct time value back you have to do the following (at least I don't see another way).

Code: Select all

time t1;
t1 = makeTime(2020,01,10,15,38,12);
  
string encoded = jsonEncode(t1);
anytype decoded = jsonDecode(encoded);

// Use scanTimeUTC to convert the string to a time variable.
time t2 = scanTimeUTC(decoded[1]);

// Converted to int just to easier show the time values are the same.  
DebugN("Time 1", (int)t1);
DebugN("Time 2", (int)t2);

5 posts • Page 1 of 1