Reputation: 175
i have an API that get information from targetProcess and put that information in sql tables.
the issue comes when a targetProcess field is date because i recieved it as json date "/Date(1409202000000-0500 )/"
.
How can i convert this json date to Datetime in c#?
i have been trying add extra quotes like the asnwer in this StackOverflow Post but it doesnt work.
i tried replace the the word Date for only use 1409202000000-0500
in
DateTime dotNetDate = new DateTime(1970, 1, 1);
dotNetDate = dotNetDate.AddMilliseconds(Convert.ToInt64(1409202000000-0500)
i use too JSON.NET as bellow
string sa = "/Date(1409202000000-0500 )/"
DateTime dt = new DateTime();
dt = JsonConvert.DeserializeObject<DateTime>(sa);
but it doesnt work too,
so the question is....How can i convert this json date to Datetime in c#?
Upvotes: 12
Views: 43805
Reputation: 3055
The solution, using System.Text.Json and converter. source: microsoft
sealed class UnixEpochDateTimeOffsetConverter : JsonConverter<DateTimeOffset>
{
static readonly DateTimeOffset s_epoch = new(1970, 1, 1, 0, 0, 0, TimeSpan.Zero);
static readonly Regex s_regex = new("^/Date\\(([+-]*\\d+)([+-])(\\d{2})(\\d{2})\\)/$", RegexOptions.CultureInvariant);
public override DateTimeOffset Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
string formatted = reader.GetString()!;
Match match = s_regex.Match(formatted);
if (
!match.Success
|| !long.TryParse(match.Groups[1].Value, System.Globalization.NumberStyles.Integer, CultureInfo.InvariantCulture, out long unixTime)
|| !int.TryParse(match.Groups[3].Value, System.Globalization.NumberStyles.Integer, CultureInfo.InvariantCulture, out int hours)
|| !int.TryParse(match.Groups[4].Value, System.Globalization.NumberStyles.Integer, CultureInfo.InvariantCulture, out int minutes))
{
throw new JsonException();
}
int sign = match.Groups[2].Value[0] == '+' ? 1 : -1;
TimeSpan utcOffset = new(hours * sign, minutes * sign, 0);
return s_epoch.AddMilliseconds(unixTime).ToOffset(utcOffset);
}
public override void Write(Utf8JsonWriter writer, DateTimeOffset value, JsonSerializerOptions options)
{
long unixTime = Convert.ToInt64((value - s_epoch).TotalMilliseconds);
TimeSpan utcOffset = value.Offset;
string formatted = string.Create(CultureInfo.InvariantCulture, $"/Date({unixTime}{(utcOffset >= TimeSpan.Zero ? "+" : "-")}{utcOffset:hhmm})/");
writer.WriteStringValue(formatted);
}
}
Upvotes: 0
Reputation: 1
You can use my function it does not need any third party reference.
private DateTime JSONdateTime2dateTime(long JSONdatetimelong)
{
long DT_Tic = (JSONdatetimelong + 62135607600000) * 10000;
return new DateTime(DT_Tic);
}
Upvotes: 0
Reputation: 1839
Here you have my function. There is even a possibility that you can get a shorter number for the Json date like in OpenweatherAPI for sunrise and sunset, then in this case you need to multiplicate with 1000. My function handle both scenarios.
public static DateTime GetDateTimeFromJSON(long jsonDateTime, bool shorter = false)
{
return JsonConvert.DeserializeObject<DateTime>($"\"\\/Date({ (shorter ? jsonDateTime * 1000 : jsonDateTime) })\\/\"", new JsonSerializerSettings
{
DateFormatHandling = DateFormatHandling.MicrosoftDateFormat
}).ToLocalTime();
}
Upvotes: 0
Reputation: 729
The issue is with your date string. instead of
string sa = "/Date(1409202000000-0500 )/"
try
string sa = @"""/Date(1409202000000-0500)/""";
Change your code :
string sa = @"""/Date(1409202000000-0500)/""";
DateTime dt = new DateTime();
dt = JsonConvert.DeserializeObject<DateTime>(sa);
// dt = "2014-08-28 3.00.00 PM"
Upvotes: 5
Reputation: 33873
You need to manually wrap your string "programatically" in quotes to ensure that it properly formatted correctly:
string sa = @"""" + "/Date(1409202000000-0500 )/" + @"""";
DateTime dt = JsonConvert.DeserializeObject<DateTime>(sa);
If you need to call it multiple times (which it seems like you do), just move the wrapping responsibility to a method:
public string WrapStringInQuotes(string input)
{
return @"""" + input + @"""";
}
Upvotes: 20