244

Possible Duplicate:
How to format a JSON date?

My webs service is returning a DateTime to a jQuery call. The service returns the data in this format:

/Date(1245398693390)/

How can I convert this into a JavaScript-friendly date?

Community
  • 1
  • 1

10 Answers10

247

What is returned is milliseconds since epoch. You could do:

var d = new Date();
d.setTime(1245398693390);
document.write(d);

On how to format the date exactly as you want, see full Date reference at http://www.w3schools.com/jsref/jsref_obj_date.asp

You could strip the non-digits by either parsing the integer (as suggested here):

var date = new Date(parseInt(jsonDate.substr(6)));

Or applying the following regular expression (from Tominator in the comments):

var jsonDate = jqueryCall();  // returns "/Date(1245398693390)/"; 
var re = /-?\d+/; 
var m = re.exec(jsonDate); 
var d = new Date(parseInt(m[0]));
Community
  • 1
  • 1
vahidg
  • 3,953
  • 2
  • 22
  • 30
  • 38
    Or just var d = new Date(1245398693390); – Josh Stodola Jun 19 '09 at 14:42
  • 23
    This will come in handy too: var re = /-?\d+/; var m = re.exec(json_date_string); var d = new Date(parseInt(m[0])); – Tominator Sep 15 '09 at 08:03
  • 6
    how are you parsing out the "/Date(" and just grabbing the number? – leora Aug 26 '10 at 16:46
  • Cheers for this, I had to do a substring on it though, not sure if there's a better way? `d.setTime(currentRow.YearMonth.substring(currentRow.YearMonth.indexOf('(') + 1, currentRow.YearMonth.indexOf(')')));` – Kieran Senior May 26 '11 at 08:40
  • @Tominator's regex is a much better way of parsing out the date than substrings – gregmac Feb 06 '12 at 16:23
  • function parseDate(str) { return new Date(parseInt(str.substr(6).split(')')[0])); } – King Friday Aug 07 '12 at 03:26
  • @gregmac why? Isn't `substring` much quicker than regexes and the length is consistent. – Keith Apr 02 '13 at 11:02
  • 1
    @Keith Substring does no validation, which is important because even though it will "always" be that date format, the reality is things change. (eg. Someone may accidentally or purposely change the service to return ISO8601 dates). Parsing with regex is a quick and easy (for the programmer) way to handle this. If you handle it later, that's fine too, but if that means you're doing substring + validation, now you're into multiple lines of code (hopefully in a separate function) which means more things that can go wrong and more programmer time spent (programmers being more expensive than CPUs). – gregmac Apr 02 '13 at 15:15
  • 1
    I'll also add, that arguing about CPU time on these types of operations in 98%+ of cases is irrelevant. If you're at such a large scale that you need to eek out all the performance you can, AND your code is at the point where you've identified parsing a date with regex is one of the slowest operations -- KUDOS, and micro-optimize away. Most people never get there. Generally speaking the things that slow down apps are the I/O operations (database calls, file ops, remote web calls, etc), and you'll get way more bang for the buck there than doing trivial and boring date substring parsing code. – gregmac Apr 02 '13 at 15:23
  • 1
    @gregmac actually I regularly find Regex to be problem when performance is concerned, particularly things like parse operations that can be repeated a lot. Cheers for the clarification. – Keith Apr 03 '13 at 07:47
79

I have been using this method for a while:

using System;

public static class ExtensionMethods {
  // returns the number of milliseconds since Jan 1, 1970 (useful for converting C# dates to JS dates)
  public static double UnixTicks(this DateTime dt)
  {
    DateTime d1 = new DateTime(1970, 1, 1);
    DateTime d2 = dt.ToUniversalTime();
    TimeSpan ts = new TimeSpan(d2.Ticks - d1.Ticks);
    return ts.TotalMilliseconds;
  }
}

Assuming you are developing against .NET 3.5, it's a straight copy/paste. You can otherwise port it.

You can encapsulate this in a JSON object, or simply write it to the response stream.

On the Javascript/JSON side, you convert this to a date by simply passing the ticks into a new Date object:

jQuery.ajax({
  ...
  success: function(msg) {
    var d = new Date(msg);
  }
}
Adam Wise
  • 2,043
  • 20
  • 17
Jeff Meatball Yang
  • 37,839
  • 27
  • 91
  • 125
  • I use your code in C#.Net4.0 to convert c# dates in JSON (REST), but it doesn't give me the right conversion for JS dates. Here is an example of correct conversion return by Json-Rest: c#date: 2009-09-12 00:00:00, equals JSdate: Date(1252684800000+0800). Your code gives me a value of: DATE(-28800000) which is not acceptable by json. What is your solution to this?.. thanks – fiberOptics Feb 23 '12 at 09:54
  • 1
    Change double to string with format ToString("#"). Double can returns decimals and introduce a bug in some cases – Sith2021 Dec 10 '13 at 20:09
  • new Date(msg) does not accept a string. So don't forget parseInt (as in the other answers on this page). – Tillito Jan 27 '14 at 09:57
34

To parse the date string using String.replace with backreference:

var milli = "/Date(1245398693390)/".replace(/\/Date\((-?\d+)\)\//, '$1');
var d = new Date(parseInt(milli));
William Niu
  • 15,798
  • 7
  • 53
  • 93
  • 4
    Using a regex is overkill for this example. Just use `new Date(parseInt(milli.substr(6)));` to begin parse at numeric part of string. – David Clarke Oct 26 '15 at 21:31
19

If you pass a DateTime from a .Net code to a javascript code, C#:

DateTime net_datetime = DateTime.Now;

javascript treats it as a string, like "/Date(1245398693390)/":

You can convert it as fllowing:

// convert the string to date correctly
var d = eval(net_datetime.slice(1, -1))

or:

// convert the string to date correctly
var d = eval("/Date(1245398693390)/".slice(1, -1))
Robert Koritnik
  • 103,639
  • 52
  • 277
  • 404
ytl
  • 231
  • 2
  • 2
17

If you're having trouble getting to the time information, you can try something like this:

    d.date = d.date.replace('/Date(', '');
    d.date = d.date.replace(')/', '');  
    var expDate = new Date(parseInt(d.date));
davidmdem
  • 3,763
  • 2
  • 30
  • 33
  • 1
    you can skip the second replace statement since `parseInt('1234abcd') returns 1234` in js – amd Feb 11 '13 at 13:03
12

the conversion from 1970,1,1 needs the double rounded to zero decimal places i thinks

DateTime d1 = new DateTime(1970, 1, 1);
DateTime d2 = dt.ToUniversalTime();
TimeSpan ts = new TimeSpan(d2.Ticks - d1.Ticks);
return Math.Round( ts.TotalMilliseconds,0);

on the client side i use

new Date(+data.replace(/\D/g, ''));
Flash
  • 121
  • 1
  • 2
8

http://stevenlevithan.com/assets/misc/date.format.js

var date = eval(data.Data.Entity.Slrq.replace(/\/Date\((\d )\)\//gi, "new Date($1)"));  
alert(date.format("yyyy-MM-dd HH:mm:ss"));  
alert(dateFormat(date, "yyyy-MM-dd HH:mm:ss"));  
Jérôme Verstrynge
  • 57,710
  • 92
  • 283
  • 453
harry
  • 81
  • 1
  • 1
7

You can try a 3rd party library like json.net There's documention on the project site. It does say it requires .net 3.5.

Otherwise there's another one called Nii.json which i believe is a port from java. I found a link to it on this blog

Dave Archer
  • 3,022
  • 20
  • 23
5

The previous answers all state that you can do the following:

var d = eval(net_datetime.slice(1, -1));

However, this doesn't work in either Chrome or FF because what's getting evaluated literally is:

// returns the current timestamp instead of the specified epoch timestamp
var d = Date([epoch timestamp]);

The correct way to do this is:

var d = eval("new " + net_datetime.slice(1, -1)); // which parses to

var d = new Date([epoch timestamp]); 
cowmoo
  • 136
  • 3
  • 3
  • I noticed this version provided the Time zone offset: UTC.....Example: Tue Sep 20 09:44:41 EDT 2011. Other versions did not have the "EDT". Thanks cowmoo. – granadaCoder Sep 20 '11 at 13:45
4

Thought i'd add my solution that i've been using.

If you're using the System.Web.Script.Serialization.JavaScriptSerializer() then the time returned isn't going to be specific to your timezone. To fix this you'll also want to use dte.getTimezoneOffset() to get it back to your correct time.

String.prototype.toDateFromAspNet = function() {
    var dte = eval("new " + this.replace(/\//g, '') + ";");
    dte.setMinutes(dte.getMinutes() - dte.getTimezoneOffset());
    return dte;
}

now you'll just call

"/Date(1245398693390)/".toDateFromAspNet();

Fri Jun 19 2009 00:04:53 GMT-0400 (Eastern Daylight Time) {}

Brian
  • 4,974
  • 2
  • 28
  • 30
  • 1
    It has it's places. I think this is the only instance that i've used it. As for the security concerns i'd say it's okay within this context because we're not pulling from anything that is publicly changeable such as a querystring or form field. Obviously anyone with intent can do as they please whether eval is used or not being that it's client script. – Brian Jun 13 '11 at 20:17
  • Besides the security concerns, `eval` is inefficient, and it prevents many JavaScript optimizers and minifiers from working. If you're using `eval` for anything other than JSON parsing, there's probably a better way to do it. – Evan Kroske Jun 13 '11 at 22:25