2
var date = '2014-02-02T20:10:00';
console.log(date);

Why does this return the following?:

'2014-02-02T20:10:00' //ok

but:

var date = new Date(date);
console.log(date);

returns:

Sun Feb 02 2014 21:10:00 GMT+0100 //bad

I would like to receive the following, where there is no offset:

Sun Feb 02 2014 20:10:00 GMT

How can I make it so?

Xotic750
  • 22,914
  • 8
  • 57
  • 79
  • 1
    You wouldn't happen to mean `Sun Feb 02 2014 20:10:00 GMT +0000`, would you? – t0mppa Feb 02 '14 at 22:23
  • I would like receive object without +1 hours added to my date – user3264008 Feb 02 '14 at 22:23
  • http://stackoverflow.com/questions/8883362/javascript-date-preserve-timezone-offset and http://stackoverflow.com/questions/17751698/stop-javascript-date-function-from-changing-timezone-offset – Andy Novocin Feb 02 '14 at 22:26
  • 1
    Since the date string does not contain a time zone offset, the date is assumed to be UTC. If you use `'2014-02-02T20:10:00+0100'`, it should work fine. [This question](http://stackoverflow.com/q/9062863/218196) shows another reason why this would be good to do in any case. – Felix Kling Feb 02 '14 at 22:29
  • 1
    In the first code snippet you are printing a string object in the console, while in the second code snippet you print a Date object that is converted to a string. @AndyNovocin gives some good links, I would also suggest checking the date.js plugin http://www.datejs.com/ – Tasos K. Feb 02 '14 at 22:32
  • 1
    @Felix Kling According to the ISO8601:2004 spec, such a timestamp without an offset is assumed to be local and not UTC. There were errata added to the ECMA5 spec that brought this into line with ISO later. So some browser implementations do one thing and some another. I have only just found this out myself and need to go back over some answers and correct my assumptions (from reading) too. – Xotic750 Feb 05 '14 at 13:45

3 Answers3

2

You can not rely on Date to parse a string correctly (here is a comparison and that's before the introduction of ISO8601 parsing - ECMA5) into a Date object, so for cross browser it is best to do it yourself. You also can not rely on the string returned from Date.toString() and again for cross browser you will need to format it yourself, or use a library like moments.js. It's that simple.

The string you have is a date stamp in ISO8601 format and specifically, by the ISO8601 specification, is assumed to be local time as no offset is supplied, I am going to assume it is UTC. Many browsers and libraries, the W3C and the ECMA5 spec (that have errata that change the assumption) disagree on this, and you can not take it for granted that local time is assumed.

You obviously have a browser that supports these strings. But when you output Date.toString you are asking for the local time (as per your environment), but you want UTC (assumed) and so you need Date.toUTCString(), but these methods are implementation dependant and you may not get the same string in different environments.

Javascript

function parseMyDateString(str) {
    var parts = str.split(/[\-T:]/);

    parts[1] -= 1;

    return new Date(Date.UTC.apply(undefined, parts));
}

function padLeft(arg) {
    var str = String(arg);

    if (str.length < 2) {
        str = '0' + str;
    }

    return str;
}

function formatMyDateString(date) {
    var days = [
            'Sun',
            'Mon',
            'Tue',
            'Wed',
            'Thu',
            'Fri',
            'Sat'
        ],
        months = [
            'Jan',
            'Feb',
            'Mar',
            'Apr',
            'May',
            'Jun',
            'Jul',
            'Aug',
            'Sep',
            'Oct',
            'Nov',
            'Dec'
        ],
        dateString = [
            days[date.getUTCDay()],
            months[date.getUTCMonth()],
            padLeft(date.getUTCDate()),
            date.getUTCFullYear()
        ].join(' '),
        timeString = [
            padLeft(date.getUTCHours()),
            padLeft(date.getUTCMinutes()),
            padLeft(date.getUTCSeconds())
        ].join(':');

    return [
            dateString,
            timeString,
            'GMT'
        ].join(' ');
}

var iso8601String = '2014-02-02T20:10:00',
    dateObject = parseMyDateString(iso8601String),
    myDateString = formatMyDateString(dateObject);

console.log(myDateString);

Output

Sun Feb 02 2014 20:10:00 GMT 

On jsFiddle

Xotic750
  • 22,914
  • 8
  • 57
  • 79
-1

The issue is timezone adjustment, the following has an additional line of code which fixes your problem:

var date = '2014-02-02T20:10:00'; console.log(date);
var date = new Date(date);
date.setHours(date.getHours() + (date.getTimezoneOffset()/60));
console.log(date);

Here is a working code sample

Andy Novocin
  • 454
  • 3
  • 14
  • That just creates further issues, you should resolve it using UTC rather than changing the local time. – Xotic750 Feb 03 '14 at 01:30
  • I do apologise, it does seem that the ISO standard assumes local time rather than UTC and so this could possibly be a valid fix in this case, depending on the browser implementation, due to errata in the ECMA5 spec. – Xotic750 Feb 05 '14 at 13:42
-2

Take a look at this post on W3 Schools. It goes over the date object. There are several different methods there that you could use to get the date format you're looking for.

Zach Russell
  • 1,060
  • 2
  • 13
  • 27