0

getTime() gives you milliseconds since January 1, 1970.

How can I get the milliseconds since January 1, 2012?

This is what I currently have:

var n = new Date()
var a = n.getTime()

console.log (a)
jQuerybeast
  • 14,130
  • 38
  • 118
  • 196
  • You would need to be more specific, since 1/1/2012 00:00:00 GMT? – TJR Jan 08 '12 at 19:01
  • Just build an object which is the date since Jan 1st, 2012 at 00:00 and .getTime() on it, it is then just a matter of making a difference – fge Jan 08 '12 at 19:01

4 Answers4

4

How about:

var diff = new Date() - new Date(2012, 0, 1); // diff is in milliseconds

for calculating differences including local time zone deviations, or

var diff = new Date() - Date.UTC(2012, 0, 1); // diff in ms

for more scientific solutions.

Note that months in Javascript are zero based.

matsev
  • 32,104
  • 16
  • 121
  • 156
3
var ms = +new Date() - new Date( '2012/01/01' )

or make that 2nd date object new Date( '2012/01/01 GMT' ) if desired

  • ? That's your ms since 1/1/2012. Do whatever you want with it –  Jan 08 '12 at 19:04
  • Thank you. Exactly what I wanted – jQuerybeast Jan 08 '12 at 19:06
  • 1
    That date format is *not* the format that must be recognized by conforming implementations of ECMAScript Edition 5.1. The format that must be recognized is the extended format specified in ISO 8601 (see section 15.9.1.15). Also, as a feature of ECMAScript, the `-` operator converts all its operands to `Number` (section 11.6.2), so the explicit conversion with unary `+` is unnecessary: `var ms = new Date() - new Date("2012-01-01T00:00:00.000Z");`. – PointedEars Jan 08 '12 at 19:20
  • 1
    You must use UTC else the duration is timezone specific. – TJR Jan 08 '12 at 20:52
  • @PointedEars -- Every implementation of ECMAScript recognizes `YYYY/MM/DD`, there's no point in writing out the full format. I'd sooner write ( YYYY, MM, DD ) as in matsev's answer. @TJR -- hence the 2nd line –  Jan 09 '12 at 01:05
  • @cwolves Sufficient proof for your statement is lacking and cannot be provided, because you can only ever prove it for a *subset* of ECMAScript implementations. – PointedEars Jan 09 '12 at 02:02
  • @PointedEars -- And I care why? ___Every___ version of IE, Safari, Chrome, FF, Opera, Mobile Safari, etc recognize `YYYY/MM/DD`. As does node.js, rhino, asp (js), ... –  Jan 09 '12 at 02:20
  • @PointedEars -- Per http://stackoverflow.com/questions/3085937/safari-js-cannot-parse-yyyy-mm-dd-date-format, not all ECMAScript implementations properly parse `ISO 8601`. They ___all___ properly parse `YYYY/MM/DD`. Guess which one I'm going to use? The point is that I don't care whatsoever what specs say when specs can be incorrectly implemented. I care what works. –  Jan 09 '12 at 02:33
  • @cwolves Your logic is flawed. QED. – PointedEars Jan 09 '12 at 10:26
  • The argument "P is standardized. Q is proprietary. P does not work in A and B. Q works in B and C. Therefore, I am using Q *instead of* P." is a fallacy. The conclusion "Therefore, you are using and recommending *only* P." is a fallacy as well, as evidenced by my answer. – PointedEars Jan 09 '12 at 17:47
  • My argument is that B and C are real where A is imaginary. REAL WORLD. Sheesh –  Jan 09 '12 at 18:36
  • @PointedEars -- let me make this simple. Show me a JS engine where `YYYY/MM/DD` does _not_ work and I'll change my mind. Until then, I've shown you one where `ISO 8601` does _not_ work so your argument boils down to "Theory is more important than results" which is absurd and makes your argument invalid. –  Jan 09 '12 at 18:58
2

Here is an example:

Sample output. Notice how the DurationGMT & DurationLocal are different. When doing comparisons with dates always use GMT.

Now:         1,326,054,979,124 ms (Sun, 08 Jan 2012 20:36:19 GMT)

Start1:      1,325,376,000,000 ms (Sun, 01 Jan 2012 00:00:00 GMT)
Start2:      1,325,376,000,000 ms (Sun, 01 Jan 2012 00:00:00 GMT)
Start3:      1,325,376,000,000 ms (Sun, 01 Jan 2012 00:00:00 GMT)
DurationGMT: 678,979,124 ms (Accurate method)

StartLocal1:   1,325,397,600,000 ms (Sun, 01 Jan 2012 06:00:00 GMT)
DurationLocal: 657,379,124 ms !!! Don't use this method

Here are three methods to get a GMT date, #3 would be what you want.

var now = new Date();
var startOfYear1 = createGMTDate1(2012, 0, 1, 0, 0, 0, 0);
var startOfYear2 = createGMTDate2(2012, 0, 1, 0, 0, 0, 0);
var startOfYear3 = createGMTDate3(2012, 0, 1, 0, 0, 0, 0);
var durationGMTMillis = now.getTime() - startOfYear1.getTime(); // accurate

var startOfYearLocal1 = new Date(2012, 0, 1, 0, 0, 0, 0);
var durationLocalMillis = now.getTime() - startOfYearLocal1.getTime(); // inaccurate

function createGMTDate1(year, month, date, hours, mins, secs, millis) {
  var dateDefaultTz = new Date(year, month, date, hours, mins, secs, millis);
  var localeTzGMTMillis = dateDefaultTz.getTime();
  var localeTzGMTOffsetMillis = dateDefaultTz.getTimezoneOffset() * 60 * 1000;
  var dateGMT = new Date(localeTzGMTMillis - localeTzGMTOffsetMillis);
  return dateGMT;
}

function createGMTDate2(year, month, date, hours, mins, secs, millis) {
  var dateGMT = new Date(0);
  dateGMT.setUTCFullYear(year);
  dateGMT.setUTCMonth(month);
  dateGMT.setUTCDate(date);
  dateGMT.setUTCHours(hours);
  dateGMT.setUTCMinutes(mins);
  dateGMT.setUTCSeconds(secs);
  dateGMT.setUTCMilliseconds(millis);
  return dateGMT;
}

function createGMTDate3(year, month, date, hours, mins, secs, millis) {
  var dateGMT = new Date(Date.UTC(year, month, date, hours, mins, secs, millis));
  return dateGMT;
}
TJR
  • 3,617
  • 8
  • 38
  • 41
  • createGMTDate1() looks bogus. createGMTDate2() has too many calls. – PointedEars Jan 08 '12 at 20:09
  • @PointedEars, does it look bogus, or did you test it and it fails? Check out the link to execute the js. – TJR Jan 08 '12 at 20:12
  • Attempting to create a `Date` instance with a certain time value is *not* the same as computing a difference between time values. – PointedEars Jan 08 '12 at 20:17
  • @PointedEars, did you even read the answer? var durationMillis = now.getTime() - startOfYear1.getTime(); – TJR Jan 08 '12 at 20:19
  • As I suspected, `createGMTDate1()` fails during the DST switch. That is a common mistake. `createGMTDate1()` returns "Sun Mar 27 2011 03:00:00 GMT+0200 (CEST)", while `Date.UTC()` when passed the same arguments returns the time value for "Sun Mar 27 2011 04:00:00 GMT+0200 (CEST)" in Chromium 16.0.912.63 (Developer Build 113337 Linux). [Testcase](http://PointedEars.de/scripts/test/date-utc) – PointedEars Jan 09 '12 at 00:34
0

As others have said, the solution is subtracting Date instances:

var ms = now - before;

This works because the - operator converts its operands to Number (ECMAScript Language Specification, Edition 5.1, section 11.6.2). The corresponding ToNumber algorithm checks if the object has a valueOf method, and calls it if it exists (sections 9.3, 9.1, and 8.12.8).

It now happens that the Date.prototype.valueOf() method, that Date instances inherit, returns the same value as Date.prototype.getTime() for a given Date instance (section 15.9.5.8). Which is the number of milliseconds since January 1, 1970 (CE) 00:00:00.000 UTC ("epoch") (section 15.9.1.1).

The first operand is obvious if you want to compare against the local time:

var now = new Date();

The second part is a bit more tricky because you want to count from January 1, 2012 (CE) 00:00:00.000 GMT. For that you cannot use

var before = new Date(2012, 0, 1);

(or variations thereof) because it uses 00:00:00.000 local time (section 15.9.3.1). There are at least two ways to make this work:

  1. Use a string value in a date format that must be recognized by conforming implementations of ECMAScript Edition 5.1 (section 15.9.1.15):

    var ms = new Date() - new Date("2012-01-01T00:00:00.000Z");
    
  2. If you are concerned about backwards compatibility, you can set the time explicitly (section 15.9.5):

    var before = new Date();
    before.setUTCFullYear(2012, 0, 1);
    before.setUTCHours(0, 0, 0, 0);
    
    var ms = now - before;
    
PointedEars
  • 14,752
  • 4
  • 34
  • 33