This format is commonly referred to as an "ASP.NET JSON Date" - because it first emerged from the JavaScriptSerializer
and DataContractJsonSerializer
classes used in ASP.NET and other parts of .NET. However, it was heavily criticized, and ultimately deprecated in favor of the standard ISO 8601 format, which is the default in the Json.Net library used in most modern .NET code. You'll still see it in WCF, and in older versions of ASP.NET MVC.
This format has two main variations:
/Date(1401993000000)/
- A timestamp alone
/Date(1401993000000+0530)/
- A timestamp with an offset
You will occasionally see the forward slashes escaped with backslashes, as in \/Date(1401993000000)\/
, depending on how it was generated. This should be tolerated by parsers, but should not be depended upon.
In both formats shown, the timestamp portion is intended to represent the number of milliseconds since the Unix Epoch, which is 1970-01-01 00:00:00.000 UTC.
I say "intended", because it is possible in .NET to have a DateTime
with DateTimeKind.Unspecified
, which can't possibly be mapped back to UTC. In this case, the serializer will act as if it had DateTimeKind.Local
. The output will then reflect the value adjusted to UTC in the computer's local time zone, along with the computer's UTC offset for that point in time. Ideally, you should not rely on this behavior, as you will get different results from computers in different time zones.
When an offset is present in the output string, it is in +HHmm
/-HHmm
format, with positive values falling East of GMT - the same direction as the ISO 8601 standard. However, unlike ISO 8601, the value portion is not adjusted for that offset. It remains UTC-based.
In other words:
/Date(1401993000000)/
= 2014-06-05T18:30:00Z
/Date(1401993000000+0530)/
= 2014-06-05T18:30:00Z
+ +0530
= 2014-06-06T00:00:00+05:30
Because of this, the offset portion is extraneous when using this value to create a JavaScript Date
object - since a Date
object wraps a timestamp in UTC, and has no provision for retaining a provided offset.
You can certainly break out the string into its parts and use them yourself,
but instead consider using Moment.js for parsing this string. It understands the format natively, and can give you back an object that retains knowledge of the offset.
var m = moment.parseZone("/Date(1401993000000+0530)/");
m.format() // "2014-06-06T00:00:00+05:30"
If you were looking for a Date
object, you can certainly call m.toDate()
. The resulting Date
object will have the same UTC timestamp, but due to how the Date
object works, any local-time functions will only use the offset of the host environment.
In other words, with output of a Date
object, the +0530
part of your input becomes useless. You might have well have parsed /Date(1401993000000)/
.