I have a datetime in a sql database: 2020-07-21 13:55:22.990 This datetime is in UTC although(correct me if I'm wrong), there would be no way to know that within the confines of the database. For reference, I am in CST(UTC-6) and this question was written during daylight savings time (so I'm -5 from UTC at the moment).
I'm sending a query to that database and getting back json using the following method (I don't believe there are any issues with it, but I've included it just in case):
private static string GetJSONFromSQLQuery(string query, string connectionString)
{
var dataTable = new DataTable();
using (var sqlConnection = new SqlConnection(connectionString))
using (var sqlCommand = new SqlCommand(query, sqlConnection))
using (var sqlDataAdapter = new SqlDataAdapter(sqlCommand))
{
sqlConnection.Open();
sqlDataAdapter.Fill(dataTable);
}
var rowsAsDictionaries = new List<Dictionary<string, object>>();
foreach (DataRow row in dataTable.Rows)
{
var rowAsDictionary = new Dictionary<string, object>();
// ReSharper disable once LoopCanBeConvertedToQuery
foreach (DataColumn column in dataTable.Columns)
rowAsDictionary.Add(column.ColumnName, row[column]);
rowsAsDictionaries.Add(rowAsDictionary);
}
return new JavaScriptSerializer().Serialize(rowsAsDictionaries);
}
This is a snippet of the json I get back (in a real call, there would be more properties in the object and generally more objects):
[
{
"Timestamp":"\\/Date(1595357722990)\\/",
},
]
https://www.freeformatter.com/epoch-timestamp-to-date-converter.html says this is 7/21/2020, 1:55:22 PM under 'Convert epoch timestamp to date'
I then deserialize the json with newtonsoft:
var deserializedJson = JsonConvert.DeserializeObject<List<MyObjectType>>(json)
MyObjectType has a bunch of { get; set; } properties and one of them is:
public DateTime Timestamp { get; set; }
From the above json snippet and newtonsoft call, Timestamp would be set to 7/21, 6:55:22 and the Kind property would be set to Utc. This is incorrect not what I was expecting.
After some searching I learned about the DateTimeZoneHandling property in JsonSerializerSettings and made the following calls with each of the 4 enum options:
var local = JsonConvert.DeserializeObject<List<MyObjectType>>(json, new JsonSerializerSettings
{
DateTimeZoneHandling = DateTimeZoneHandling.Local,
});
var roundtrip = JsonConvert.DeserializeObject<List<MyObjectType>>(json, new JsonSerializerSettings
{
DateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind,
});
var unspecified = JsonConvert.DeserializeObject<List<MyObjectType>>(json, new JsonSerializerSettings
{
DateTimeZoneHandling = DateTimeZoneHandling.Unspecified,
});
var utc = JsonConvert.DeserializeObject<List<MyObjectType>>(json, new JsonSerializerSettings
{
DateTimeZoneHandling = DateTimeZoneHandling.Utc,
});
Which gives me the following DateTime objects in MyObjectType (note these are snippets from a DateTime object):
deserializedJson:
Time: 7/21 6:55:22,
Kind: Utc
local:
Time: 7/21 1:55:22,
Kind: Local
roundtripKind:
Time: 7/21 6:55:22,
Kind: Utc
unspecified:
Time: 7/21 6:55:22,
Kind: Unspecified
utc:
Time: 7/21 6:55:22,
Kind: Utc
The Kind property is particularly important because I will be calling
TimeZoneInfo.ConvertTimeFromUtc(theDeserializedTimeStamp, TimeZoneInfo.Local);
My desired output is:
Time: 7/21 1:55:22,
Kind: Utc
Since that would be reflective of what is in the database and I would be able to call TimeZoneInfo.ConvertTimeFromUtc to convert the UTC time to whatever the local timezone is.
How do I get that output?
EDIT:
I found a workaround solution. I changed the return statement in GetJSONFromSQLQuery to:
return JsonConvert.SerializeObject(rowsAsDictionaries);
and all the DateTimeZoneHandling options left the time as 1:55 PM and had varying (but expected) results for the Kind property. Not sure why json from JavaScriptSerializer wouldn't play nicely, but I'm unstuck now at least.
The json that JsonConvert.SerializeObject looks like this:
[
{
"Timestamp":"2020-07-21T13:55:22.99"
}
]