JavaScript Date to Time

Subtle differences sometimes indicate the proficiency of a programmer.

Here are three ways to get the current time in JavaScript:

var t1 = (new Date()).getTime(); // 1
var t2 = new Date().getTime(); // 2
var t3 = (new Date).getTime(); // 3

The bracket placement is as much about language awareness as personal taste. In JavaScript, the brackets are optional for a zero-argument constructor: new Date creates a new Date instance without requiring brackets. But due to JavaScript operator precedence, you can’t write new Date.getTime() because the interpreter sees that as trying to call the constructor for a Date.getTime class (cf. MyPackage.MyClass) – in this case the brackets are required for the statement to parse as intended.

Reflecting on the three versions above: Version 1 doesn’t do anything to show a deep understanding of JavaScript. Version 2 and 3 are sort of interchangeable, but version 3 just edges ahead because the coder’s displayed knowledge to drop the optional brackets.

Of course, if you want the most compact code possible, you’d write:

var t4 = +new Date; // 4

This little gem creates a new Date, then coerces it into a number using a unary + operator – and coercing a Date to a number is defined in the language spec to go via valueOf and getTime.

Checking the character-count: (new Date).getTime() is 20 characters, while +new Date is 9.

That 11 character saving might come in handy on, say, the new Google home-page, where they currently use (new Date).getTime() seven times.

Posted Thursday, December 3rd, 2009 under JavaScript.

8 comments

  1. I applied for a Javascript job and the interviewer seemed to know all Javascript’s implicit type conversions and operator precedence – far better than me.

    And then he said that JS inheritance was like cloning.

    To me that’s kind of like using a blunt knife to cut instead of a spoon.
    It’s not particularly better for easy things and it doesn’t help for hard things.

    Given that gzip will significantly reduce the difference between
    +new Date
    and
    (new Date).getTime()
    then (without further evidence) just put it down to personal taste or styling convention.

  2. Let me explain better what I mean by cloning. JavaScript is a class free language. Being such a dynamic language however you can simulate classes. There are many different libraries you can use for this simulation. However you are simulating, this is not how inheritance is intended to work in JavaScript though. It is a prototypal language.

    Prototypal inheritance does not have classes. It works by cloning ‘prototype’ objects and manipulating them. This manipulated object can then be used as a prototype for another object and so on. For a full description, check Wikipedia http://en.wikipedia.org/wiki/Prototype-based_programming.

  3. I’m not convinced that showing the depth of one’s knowledge is at all a good motivation in the choice of coding style.

  4. Me neither. I do think that embracing the nature of the language rather than molding it into another is.

  5. @Tim,

    I agree – using dark magic can make code awkward to understand and hard to maintain.

    However, I came across the three styles in the bowels of widespread JavaScript libraries which aim for stability and compactness. In these cases I’d expect the libraries to go with the most compact and efficient implementation.

    There’s another widespread idiom that avoids deep JavaScript knowledge: do you feel the same way about this – checking the end of a string:

    var summat = "foobar", tail = "bar";
    // common idiom for Java's endsWith:
    if (summat.substring(summat.length - tail.length) == tail) …
    
    // using knowledge of substr:
    if (summat.substr(-tail.length) == tail) …
    
    // For hard-coded tails - compare the substring and substr versions:
    if (path.substring(path.length - 1) == '/') …
    
    if (path.substr(-1) == '/') …
    

    I’d guess a lot of JavaScript coders don’t know they can use negative offsets in substr, but it doesn’t seem quite so deep as +new Date.

  6. Ash,

    You’ve saved us some time and a few characters with the few things we just learned from this post, haha:

    1) + converts to a number (by implicitly calling valueOf)
    2) default constructors require no () at the end, that’s cool
    3) you can use a negative index in String.prototype.substr

    We knew PHP had this functionality (in substr()), but we had no clue you could do this in JavaScript without modifying String’s prototype.

    Thank you,

    All my future websites

  7. Hi Dan,

    I’m still learning myself…

    There’s an annoying caveat with substr: you can pass negative indexes as the first parameter, but not the second. Fortunately slice has you covered:

    
    // from the bowels of jQuery (removeClass)
    var className = " " + elem.className + " ";
    // remove named classes (omitted), and replace:
    elem.className = className.substring(1, className.length - 1);
    
    // use slice to remove single leading and trailing space:
    elem.className = className.slice(1, -1);
    
  8. Ash,

    I have nothing but approval and joy for negative offsets in substr and slice. I think it’s pretty intuitive and much easier to read than the equivalent with messing around with subtracting the string’s length. It doesn’t at all look as though it’s showing off, unlike +new Date.

    As it happens, I knew about the unary + operator and optional parentheses for constructors but not the negative offsets for slice and substr, so thank you for alerting me to that.

    Tim