Overview
Examples
Screenshots
Comparisons
Applications
Download
Documentation
Tutorials
Bazaar
Status & Roadmap
FAQ
Authors & License
Forums
Funding Ultimate++
Search on this site
Search in forums












SourceForge.net Logo
Home » U++ Library support » U++ Core » Jsonize() Date and Time serialization [patch]
Jsonize() Date and Time serialization [patch] [message #57209] Fri, 11 June 2021 19:41 Go to next message
zsolt is currently offline  zsolt
Messages: 696
Registered: December 2005
Location: Budapest, Hungary
Contributor
I'm working on a web service and my problem was, that JavaScript handles date and time in ISO format, but U++ Jsonize() in special ways.
I attached a minimal HTML file to demonstrate, how JavaScript serializes Date and DateTime and U++ should do the same if we want to be compatible.

My HTML file shows a JSON output like this:
{
    "my_date": "2021-06-08",
    "my_datetime": "2021-06-15T19:25"
}

Jsonize() outputs dates like this:
{
    "my_date": "20210608",
    "my_datetime": "20210615T19:25"
}

Is it possible to fix Jsonize()?

I propose something like this:
@@ -328,7 +328,7 @@ template<> void Jsonize(JsonIO& io, Date& var)
 			return;
 		}
 		if(IsString(v)) {
-			String text = v;
+			String text = Filter(v.ToString(), CharFilterDigit);
 			if(text.GetCount() > 6) {
 				Date d;
 				d.year = ScanInt(text.Left(4));
@@ -346,7 +346,7 @@ template<> void Jsonize(JsonIO& io, Date& var)
 		if(IsNull(var))
 			io.Set(Null);
 		else
-			io.Set(Format("%04d%02d%02d", var.year, var.month, var.day));
+			io.Set(Format("%04d-%02d-%02d", var.year, var.month, var.day));
 }
 
 template<> void Jsonize(JsonIO& io, Time& var)
@@ -358,15 +358,15 @@ template<> void Jsonize(JsonIO& io, Time& var)
 			return;
 		}
 		if(IsString(v)) {
-			String text = v;
-			if(text.GetCount() > 15) {
+			String text = Filter(v.ToString(), CharFilterDigit);
+			if(text.GetCount() > 10) {//seconds may be missing
 				Time tm;
 				tm.year = ScanInt(text.Left(4));
 				tm.month = ScanInt(text.Mid(4, 2));
 				tm.day = ScanInt(text.Mid(6, 2));
-				tm.hour = ScanInt(text.Mid(9, 2));
-				tm.minute = ScanInt(text.Mid(12, 2));
-				tm.second = ScanInt(text.Mid(15));
+				tm.hour = ScanInt(text.Mid(8, 2));
+				tm.minute = ScanInt(text.Mid(10, 2));
+				tm.second = ScanInt(text.Mid(12, 2));
 				if(tm.IsValid()) {
 					var = tm;
 					return;
@@ -379,7 +379,7 @@ template<> void Jsonize(JsonIO& io, Time& var)
 		if(IsNull(var))
 			io.Set(Null);
 		else
-			io.Set(Format("%04d%02d%02d`T%02d:%02d:%02d",
+			io.Set(Format("%04d-%02d-%02d`T%02d:%02d:%02d",
 				          var.year, var.month, var.day, var.hour, var.minute, var.second));
 }
Re: Jsonize() Date and Time serialization [patch] [message #57210 is a reply to message #57209] Fri, 11 June 2021 19:51 Go to previous messageGo to next message
zsolt is currently offline  zsolt
Messages: 696
Registered: December 2005
Location: Budapest, Hungary
Contributor
Quick correction:
This one would be safer for dates:
@ -328,12 +328,12 @@ template<> void Jsonize(JsonIO& io, Date& var)
 			return;
 		}
 		if(IsString(v)) {
-			String text = v;
+			String text = Filter(v.ToString(), CharFilterDigit);
 			if(text.GetCount() > 6) {
 				Date d;
 				d.year = ScanInt(text.Left(4));
 				d.month = ScanInt(text.Mid(4, 2));
-				d.day = ScanInt(text.Mid(6));
+				d.day = ScanInt(text.Mid(6,2));
 				if(d.IsValid()) {
 					var = d;
 					return;
@@ -346,7 +346,7 @@ template<> void Jsonize(JsonIO& io, Date& var)
 		if(IsNull(var))
 			io.Set(Null);
 		else
-			io.Set(Format("%04d%02d%02d", var.year, var.month, var.day));
+			io.Set(Format("%04d-%02d-%02d", var.year, var.month, var.day));
 }
 
 template<> void Jsonize(JsonIO& io, Time& var)
@@ -358,15 +358,15 @@ template<> void Jsonize(JsonIO& io, Time& var)
 			return;
 		}
 		if(IsString(v)) {
-			String text = v;
-			if(text.GetCount() > 15) {
+			String text = Filter(v.ToString(), CharFilterDigit);
+			if(text.GetCount() > 10) {//seconds may be missing
 				Time tm;
 				tm.year = ScanInt(text.Left(4));
 				tm.month = ScanInt(text.Mid(4, 2));
 				tm.day = ScanInt(text.Mid(6, 2));
-				tm.hour = ScanInt(text.Mid(9, 2));
-				tm.minute = ScanInt(text.Mid(12, 2));
-				tm.second = ScanInt(text.Mid(15));
+				tm.hour = ScanInt(text.Mid(8, 2));
+				tm.minute = ScanInt(text.Mid(10, 2));
+				tm.second = ScanInt(text.Mid(12, 2));
 				if(tm.IsValid()) {
 					var = tm;
 					return;
@@ -379,7 +379,7 @@ template<> void Jsonize(JsonIO& io, Time& var)
 		if(IsNull(var))
 			io.Set(Null);
 		else
-			io.Set(Format("%04d%02d%02d`T%02d:%02d:%02d",
+			io.Set(Format("%04d-%02d-%02d`T%02d:%02d:%02d",
 				          var.year, var.month, var.day, var.hour, var.minute, var.second));
 }
 
Re: Jsonize() Date and Time serialization [patch] [message #57211 is a reply to message #57210] Sat, 12 June 2021 08:47 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
zsolt wrote on Fri, 11 June 2021 19:51
Quick correction:
This one would be safer for dates:
@ -328,12 +328,12 @@ template<> void Jsonize(JsonIO& io, Date& var)
 			return;
 		}
 		if(IsString(v)) {
-			String text = v;
+			String text = Filter(v.ToString(), CharFilterDigit);
 			if(text.GetCount() > 6) {
 				Date d;
 				d.year = ScanInt(text.Left(4));
 				d.month = ScanInt(text.Mid(4, 2));
-				d.day = ScanInt(text.Mid(6));
+				d.day = ScanInt(text.Mid(6,2));
 				if(d.IsValid()) {
 					var = d;
 					return;
@@ -346,7 +346,7 @@ template<> void Jsonize(JsonIO& io, Date& var)
 		if(IsNull(var))
 			io.Set(Null);
 		else
-			io.Set(Format("%04d%02d%02d", var.year, var.month, var.day));
+			io.Set(Format("%04d-%02d-%02d", var.year, var.month, var.day));
 }
 
 template<> void Jsonize(JsonIO& io, Time& var)
@@ -358,15 +358,15 @@ template<> void Jsonize(JsonIO& io, Time& var)
 			return;
 		}
 		if(IsString(v)) {
-			String text = v;
-			if(text.GetCount() > 15) {
+			String text = Filter(v.ToString(), CharFilterDigit);
+			if(text.GetCount() > 10) {//seconds may be missing
 				Time tm;
 				tm.year = ScanInt(text.Left(4));
 				tm.month = ScanInt(text.Mid(4, 2));
 				tm.day = ScanInt(text.Mid(6, 2));
-				tm.hour = ScanInt(text.Mid(9, 2));
-				tm.minute = ScanInt(text.Mid(12, 2));
-				tm.second = ScanInt(text.Mid(15));
+				tm.hour = ScanInt(text.Mid(8, 2));
+				tm.minute = ScanInt(text.Mid(10, 2));
+				tm.second = ScanInt(text.Mid(12, 2));
 				if(tm.IsValid()) {
 					var = tm;
 					return;
@@ -379,7 +379,7 @@ template<> void Jsonize(JsonIO& io, Time& var)
 		if(IsNull(var))
 			io.Set(Null);
 		else
-			io.Set(Format("%04d%02d%02d`T%02d:%02d:%02d",
+			io.Set(Format("%04d-%02d-%02d`T%02d:%02d:%02d",
 				          var.year, var.month, var.day, var.hour, var.minute, var.second));
 }
 


This is tough decision - backward incompatible change. At minimum we should make Jsonize recognize old format as well as new...

In any case, so far the Jsonize format was considered like "U++ private", it was not meant for "external" communication.

That said, I am OK with the change, as long as it able to read previous format...

Mirek
Re: Jsonize() Date and Time serialization [patch] [message #57212 is a reply to message #57211] Sat, 12 June 2021 09:41 Go to previous messageGo to next message
zsolt is currently offline  zsolt
Messages: 696
Registered: December 2005
Location: Budapest, Hungary
Contributor
mirek wrote on Sat, 12 June 2021 08:47


That said, I am OK with the change, as long as it able to read previous format...

Mirek


Thanks. This is why I put those filters there. This way it can read the old format.

BTW, I think U++ is extremely useful and efficient in web service development.
With some helper classes and macros I was able to create a type-safe web service framework.
My endpoints are normal C++ functions now, thanks to the Jsonize() infrastructure.
Re: Jsonize() Date and Time serialization [patch] [message #57226 is a reply to message #57212] Sun, 13 June 2021 10:00 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
OK, applied, please check.

That said, the code could use a bit of optimization... (those Mids and Format are probably not the most optimal solution). Maybe in the future...
Re: Jsonize() Date and Time serialization [patch] [message #57227 is a reply to message #57226] Sun, 13 June 2021 13:47 Go to previous messageGo to next message
zsolt is currently offline  zsolt
Messages: 696
Registered: December 2005
Location: Budapest, Hungary
Contributor
Thank you!
I tested. It works perfectly.

Yes, I tried replacing those formats with a simple code, dumping to a string with IntStr() and was much faster, but ugly.
Do you have an idea about it?

And yes, the parsing is not very optimal this way. And doesn't solve the problem of dates after year 9999.
Re: Jsonize() Date and Time serialization [patch] [message #57262 is a reply to message #57227] Mon, 21 June 2021 14:05 Go to previous message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
After revisiting the code, I am afraid it is not really correct: Mid is UB if there are not enough characters in the String...

Working on further checks&fixing...

Mirek

[Updated on: Mon, 21 June 2021 14:08]

Report message to a moderator

Previous Topic: MSVS15x64: Compile Error C3256 C3259 C3250 in Fn.h findarg
Next Topic: How do I implement mouse hover in Ctrl based class
Goto Forum:
  


Current Time: Fri Apr 19 00:38:26 CEST 2024

Total time taken to generate the page: 0.01676 seconds