20

I've been trying to convert a date value into a more readable format. To do that, I'm trying to parse the date using the JavaScript Date.parse() method. That however does not work on the input (eg: "2007-09-21T14:15:34.058-07:00") that I have. The end goal is to output a date string like "January 30th, 2008 @ 2:15PM".

Any ideas?

1
  • UTC is timezone 00:00. Do you mean ISO 8601 format? Commented Jan 31, 2009 at 10:28

2 Answers 2

20

You should probably use the datejs that f3lix recommended, however I was bored and threw together a little object that does exactly what you asked for:

September 25, 2012: Cleaned code, allow non-extended format, eg 20120925T164740+0200

December 1, 2011: fixed a bug in the month string. August was missing

var ISODate = {
  convert :
    function (input){
      if (!(typeof input === "string")) throw "ISODate, convert: input must be a string";
      var d = input.match(/^(\d{4})-?(\d{2})-?(\d{2})[T ](\d{2}):?(\d{2}):?(\d{2})(\.\d+)?(Z|(?:([+-])(\d{2}):?(\d{2})))$/i);
      if (!d) throw "ISODate, convert: Illegal format";
      return new Date(
        Date.UTC(
          d[1], d[2]-1, d[3],
          d[4], d[5], d[6], d[7] || 0 % 1 * 1000 | 0
        ) + (
          d[8].toUpperCase() === "Z" ? 0 :
            (d[10]*3600 + d[11]*60) * (d[9] === "-" ? 1000 : -1000)
        )
      );
    },
  format :
    function(date, utc){
      if (typeof date === "string") date = this.convert(date);
      if (!(date instanceof Date)) throw "ISODate, format: t is not a date object";

      var t={'FullYear':0, 'Month':0, 'Date':0, 'Hours':0, 'Minutes':0, 'Seconds':0};
      for (var key in t) {
        if (t.hasOwnProperty(key)) t[key] = date["get" +(utc ? "UTC" :"") + key]()
      }

      return this.month[t.Month]
        + " "
        + this.ordinal(t.Date)
        + ", "
        + t.FullYear
        + " @ "
        + this.clock12(t.Hours,t.Minutes);
      },
  month:
    [
      "January", "February", "March", "April", "May", "June",
      "July", "August", "September", "October", "November", "December"
    ],
  ordinal:
    function(n) {
      return n+(
        [
          "th", "st", "nd", "rd"
        ][
          (( n % 100 / 10) | 0) === 1 ? 0 : n % 10 < 4 ? n % 10 : 0
        ]
      );
  },
  clock12:
    function(h24, m, s){
      h24%=24;
      var h12 = (h24 % 12) || 12;
      return h12 + ":" +
        (m < 10 ? "0" + m : m) +
        (isFinite(s) ? ":" + (s < 10 ? "0" + s : s ) : "") +
        (h24 < 12 ? "AM" : "PM");
      }
};

Example:

//Shows the date in the users timezone:
alert(ISODate.format("2007-09-21T14:15:34.058-07:00"));

//Show the date in UTC (Timezone Z, 00:00)
alert(ISODate.format("2007-09-21T14:15:34.058-07:00",true));

Explanation:

convert takes a string as an input and returns a date object if successful or throws an exception if not. The string must be in one of the following formats:

  • YYYY-MM-DDThh:mm:ss.sZ
  • YYYY-MM-DDThh:mm:ss.sXaa:bb

Where:

  • YYYY is the year as an 4 digit integer
  • MM is the month as an 2 digit integer
  • DD is the date of month as an 2 digit integer
  • T is the character T or space (\x20)
  • hh is the hour in 24 hour format, as an 2 digit integer
  • mm is the minute as an 2 digit integer
  • ss.s is the second, either as an 2 digit integer or as a floating point with 2 digits followed by a period followed by one or more digits.
  • Z is the character Z (indicating timezone Z, UTC+00:00)
  • X is either a plus (+) or minus (-) sign of the timeoffset to UTC
  • aa is the hour of timeoffset to UTC as a 2 digit integer
  • bb is the minute of timeoffset to ITC as a 2 digit integer

format takes a string in the above format or a date-object and returns a string formated as:

  • M D, Y @ h:mm

Where - M is the full English name of the month - D is the date of month with a numerical order suffix (1-2 digits) - Y is the year (1 or more digits) - h is the hour in 12 hour format (1-2 digits) - m is the minute (2 digits)

month is an array with the name of the months

ordinal is a function that takes a number as input and return the number with English ordinal suffix.

clock12 is a function that takes hour, minute and second in 24h format and converts it to a string in the US 12h format. The seconds is optional.

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

7 Comments

This answer was very educational, but the first one i think is more poweful.
I agree that datejs is more powerful and I understand that you selected that answer.
datejs is more powerful but does have a footprint. If the above conversion is all you need to do, use it. But there is a minor bug - swap "this.month[t[1]-1]" instead of "this.month[t[1]]" in the format: method.
@Jeffrey Schrab: As I said at the top of my answer: "You should probably use the datejs...". There was a bug in the code but not where you thought it was. The zero-indexed-month is handled in the convert function. You actually introduced another bug with your fix. The real bug was in the array with the names of the months: It had no "August". Thanks for making me notice it!
This one is much better for me, looking for a lightweight solution for talkatv.
|
12

Try http://www.datejs.com/. It is a JavaScript Date Library with an extended Date.parse method and a Date.parseExact method, which lets you specify a format string. See DateJS APIDocumentation.

1 Comment

Worth pointing out that it doesn't seem perfect, and development seems to have halted. Example with the British file: console.log(Date.parse('1997-07-16T19:20:30+01:00')); outputs null, and if the timezone part is removed it works, but in the American format (Wed Jul 16 1997 19:20:30 GMT+0100 (BST)), whereas "Wed 16th Jul, 1997…" would have been a bit more British.

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.