Reputation: 731
The problem of how to handle dates in JSON is one of the more troublesome issues that may arise when directly calling ASP.NET AJAX web services and page methods. Unlike every other data type in the language, JavaScript offers no declarative method for expressing a Date. Consequently, embedding them within JSON requires a bit of fancy footwork.
I will attempt to explain what exactly the problem is with dates in JSON.
What’s the problem?
The fundamental problem is that JavaScript does not provide a way to declaratively express Date objects. You may previously have seen this described as (the lack of) a Date literal. What are literals? To illustrate, these are literals for several other data types:
// String
'foo';
// Number
3.14;
// Boolean
true;
// Array
[1, 2, 3, 5, 7];
// Object
{ pi: 3.14, phi: 1.62 };
Unfortunately, when it comes to dates, the lack of a literal means that the only way to create one is by explicitly initializing a Date object:
// Correct.
new Date('4/26/09');
// Correct (the month is 0 indexed, hence the 3).
new Date(2009, 3, 26);
// Incorrect. This is a string, not a Date.
'4/26/09';
While this limitation is fine when writing client-side JavaScript code, it leaves us without a good way to transmit dates within JSON objects. lack of a date literal is a problem, Can Somebody Suggest a Solution.
Upvotes: 3
Views: 950
Reputation: 3594
I recently wrote a blog post about this sort of thing here... it's a minefield! At work, we've decided to transmit DateTimes and DateTimeOffsets from our MVC3 service as strings, using variations on a W3C format found here. For DateTime, we use YYYY-MM-DDThh:mm:ss, for DateTimeOffsets, YYYY-MM-DDThh:mm:ss+TZD (these format specifiers are W3C, not .NET).
But the answer to this question really does depend on what you want to do with the dates. As another reply suggests, you might be able to get away with simply sending a human readable string across the wire if all you want to do is display it to an end user.
Upvotes: 1
Reputation: 66641
I use two ways, one is to make it Date.UTC() and the other to make it as Ticks. Both they work.
The function that convert it to Json Ticks
private static readonly long UnixEpochTicks = (new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).Ticks;
public static long cOnlyDate(long Ticks)
{
return (864000000000 * (Ticks / 864000000000));
}
public static long ToJsonTicks(DateTime value)
{
return (cOnlyDate(value.ToUniversalTime().Ticks) - UnixEpochTicks) / 10000;
}
The results will be like {dt : 28839281}
and how I convert it to Date
public static string ToJsonDate(DateTime value)
{
return string.Format("Date.UTC({0}, {1}, {2})", value.Year, value.Month-1, value.Day);
}
The results will be like {d : Date.UTC(2012, 2, 11)}
ps, I just test now the solution of the "Unknow" and not work on my code.
Upvotes: 0
Reputation: 269
Consider why you want to send a DateTime to the client-side to begin with. Most often, you’re displaying a string representation of it and have no need for the proper JavaScript Date object. What’s more, if you end up with a JavaScript Date object, you’ll probably use additional code or a JavaScript library to display it in a user-friendly format. As much as I appreciate a clever workaround, I’d much rather avoid the problem completely. Rather than jump through all of these hoops to instantiate a JavaScript Date object on the client-side and then format it, I suggest simply returning a formatted string. For example,
[System.Web.Script.Services.ScriptService]
public class DateService : System.Web.Services.WebService
{
[WebMethod]
public string GetDate()
{
return new DateTime(2009, 4, 26).ToLongDateString();
}
}
Now, calling the service will return this JSON:
{"d":"Sunday, April 26, 2009"}
No more regular expressions. No more JavaScript Date objects. No more worrying about formatting the data on the client-side. Even better, no functionality is lost. If we need to instantiate Dates, we still can.
Upvotes: 1