101

I need help/tips on converting an ISO 8601 date with the following structure into JavaScript:

CCYY-MM-DDThh:mm:ssTZD

I'd like to format the date like so:

January 28, 2011 - 7:30PM EST

I'd like to keep this solution as clean and minimal as possible.

1
  • 1
    I know this is an old post, but this library does what you want: github.com/csnover/js-iso8601 Commented Nov 16, 2012 at 22:56

5 Answers 5

141

The Date object handles 8601 as its first parameter:

var d = new Date("2014-04-07T13:58:10.104Z");
console.log(d.toString());

Sign up to request clarification or add additional context in comments.

13 Comments

Not in all browsers. Keep in mind, ECMA specification was or still is vague about the parameter format of Date(). That's why even IE11 can't handle what you are suggesting.
@RenéStalder I actually just tested this in IE11 and it works. Did you test in other IE versions?
@RenéStalder Just tested in IE9 on Win7 too and it works there as well. In fact so far I haven't found a single browser that doesn't support it.
Doesn't work in IE 9: Quirks mode for sure. Some of us need browser compatability.
Date parsing is implementation dependent until ES5. Old browsers will display inconsistent results.
|
35

datejs could parse following, you might want to try out.

Date.parse('1997-07-16T19:20:15')           // ISO 8601 Formats
Date.parse('1997-07-16T19:20:30+01:00')     // ISO 8601 with Timezone offset

Edit: Regex version

x = "2011-01-28T19:30:00EST"

MM = ["January", "February","March","April","May","June","July","August","September","October","November", "December"]

xx = x.replace(
    /(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):\d{2}(\w{3})/,
    function($0,$1,$2,$3,$4,$5,$6){
        return MM[$2-1]+" "+$3+", "+$1+" - "+$4%12+":"+$5+(+$4>12?"PM":"AM")+" "+$6
    }
)

Result

January 28, 2011 - 7:30PM EST

Edit2: I changed my timezone to EST and now I got following

x = "2011-01-28T19:30:00-05:00"

MM = {Jan:"January", Feb:"February", Mar:"March", Apr:"April", May:"May", Jun:"June", Jul:"July", Aug:"August", Sep:"September", Oct:"October", Nov:"November", Dec:"December"}

xx = String(new Date(x)).replace(
    /\w{3} (\w{3}) (\d{2}) (\d{4}) (\d{2}):(\d{2}):[^(]+\(([A-Z]{3})\)/,
    function($0,$1,$2,$3,$4,$5,$6){
        return MM[$1]+" "+$2+", "+$3+" - "+$4%12+":"+$5+(+$4>12?"PM":"AM")+" "+$6 
    }
)

return

January 28, 2011 - 7:30PM EST

Basically

String(new Date(x))

return

Fri Jan 28 2011 19:30:00 GMT-0500 (EST)

regex parts just converting above string to your required format.

January 28, 2011 - 7:30PM EST

15 Comments

I'm making a widget and would prefer if I could just have a simple function which I could throw in my JS file. I think datajs might be overkill for this? Thanks for the suggestion and quick reply!!
@Slythic, I will write regex then, pls hold on.
@Slythic, Updated, let me know if there is any bug.
Hmm... not working as expected. I should have added this before! Here is an example of a returned date: "2011-01-28T19:30:00-05:00"
ah, ok, timezone is not a string, let me figure out, how to parse that.
|
25

If you want to keep it simple, this should suffice:

function parseIsoDatetime(dtstr) {
    var dt = dtstr.split(/[: T-]/).map(parseFloat);
    return new Date(dt[0], dt[1] - 1, dt[2], dt[3] || 0, dt[4] || 0, dt[5] || 0, 0);
}

note parseFloat is must, parseInt doesn't always work. Map requires IE9 or later.

Works for formats:

  • 2014-12-28 15:30:30
  • 2014-12-28T15:30:30
  • 2014-12-28

Not valid for timezones, see other answers about those.

5 Comments

+1 simple and portable. I made this change to interpret dates as UTC: return new Date(Date.UTC(dt[0], dt[1] - 1, dt[2], dt[3] || 0, dt[4] || 0, dt[5] || 0, 0));
Very nice little function that handles the most important part: fixing that dang month index.
Sigh, IE11 Enterprise (basically IE8) doesn't support map. Groan
Found a polyfill and it's all working for IE8 too (just change .map to .myMap): Array.prototype.myMap = function(callbackFn) { var arr = []; for (var i = 0; i < this.length; i++) { arr.push(callbackFn(this[i], i, this)); } return arr; }
To get the timezone with this approach, you can take the return of the above function (call it "d"), and run it through toLocaleTimeString(): d.toLocaleTimeString([], { month: 'long', day: 'numeric', year: 'numeric', hour: 'numeric', minute: 'numeric', timeZone: 'America/Chicago', timeZoneName: 'short' }) This converts the date string 2022-10-03T14:43:51.000000Z> to October 3, 2022 at 2:43 PM CDT
4

Maybe, you can use moment.js which in my opinion is the best JavaScript library for parsing, formatting and working with dates client-side. You could use something like:

var momentDate = moment('1890-09-30T23:59:59+01:16:20', 'YYYY-MM-DDTHH:mm:ss+-HH:mm:ss');
var jsDate = momentDate.toDate();

// Now, you can run any JavaScript Date method

jsDate.toLocaleString();

The advantage of using a library like moment.js is that your code will work perfectly even in legacy browsers like IE 8+.

Here is the documenation about parsing methods: https://momentjs.com/docs/#/parsing/

1 Comment

Moment is now in legacy mode and has been replaced by luxon and/or standard JS
-2

According to MSDN, the JavaScript Date object does not provide any specific date formatting methods (as you may see with other programming languages). However, you can use a few of the Date methods and formatting to accomplish your goal:

function dateToString (date) {
  // Use an array to format the month numbers
  var months = [
    "January",
    "February",
    "March",
    ...
  ];

  // Use an object to format the timezone identifiers
  var timeZones = {
    "360": "EST",
    ...
  };

  var month = months[date.getMonth()];
  var day = date.getDate();
  var year = date.getFullYear();

  var hours = date.getHours();
  var minutes = date.getMinutes();
  var time = (hours > 11 ? (hours - 11) : (hours + 1)) + ":" + minutes + (hours > 11 ? "PM" : "AM");
  var timezone = timeZones[date.getTimezoneOffset()];

  // Returns formatted date as string (e.g. January 28, 2011 - 7:30PM EST)
  return month + " " + day + ", " + year + " - " + time + " " + timezone;
}

var date = new Date("2011-01-28T19:30:00-05:00");

alert(dateToString(date));

You could even take it one step further and override the Date.toString() method:

function dateToString () { // No date argument this time
  // Use an array to format the month numbers
  var months = [
    "January",
    "February",
    "March",
    ...
  ];

  // Use an object to format the timezone identifiers
  var timeZones = {
    "360": "EST",
    ...
  };

  var month = months[*this*.getMonth()];
  var day = *this*.getDate();
  var year = *this*.getFullYear();

  var hours = *this*.getHours();
  var minutes = *this*.getMinutes();
  var time = (hours > 11 ? (hours - 11) : (hours + 1)) + ":" + minutes + (hours > 11 ? "PM" : "AM");
  var timezone = timeZones[*this*.getTimezoneOffset()];

  // Returns formatted date as string (e.g. January 28, 2011 - 7:30PM EST)
  return month + " " + day + ", " + year + " - " + time + " " + timezone;
}

var date = new Date("2011-01-28T19:30:00-05:00");
Date.prototype.toString = dateToString;

alert(date.toString());

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.