/ Published in: JavaScript
                    
                                        
This requires my [date formatting script](http://snipplr.com/view/54806/javascript-date-formatting/).
(date).toISO() converts the Date object to an ISO 8601 string
Date.fromISO() converts an ISO 8601 string to a Date object
                (date).toISO() converts the Date object to an ISO 8601 string
Date.fromISO() converts an ISO 8601 string to a Date object
                            
                                Expand |
                                Embed | Plain Text
                            
                        
                        Copy this code and paste it in your HTML
/* ISO 8601 Date conversions v2.0
*
* This work is licensed under a Creative Commons Attribution 3.0 Unported License
* http://creativecommons.org/licenses/by/3.0/
*
* Author: Andy Harrison, http://dragonzreef.com/
* Date: 16 September 2011
*/
//formats the Date into a string according to the Internet profile of ISO 8601 described in RFC 3339
//see http://tools.ietf.org/html/rfc3339
//time zone is always UTC
if(!Date.prototype.toISOString) Date.prototype.toISOString = function(){ return this.format("%Y-%M-%DT%I:%N:%S.%ZZ", true); }
//creates a Date object from a basic ISO 8601 formatted string
//expanded years are not supported
//see http://tools.ietf.org/html/rfc3339#section-5.6
// http://en.wikipedia.org/wiki/Iso8601
Date.fromISO = function(isoStr)
{
var rxpCalendarDate = "(\\d{4})(?:(-?)(\\d{2})(?:\\2(\\d{2}))?)?";
var rxpWeekDate = "(\\d{4})(-?)[Ww](\\d{2})(?:\\2(\\d))?";
var rxpOrdinalDate = "(\\d{4})-?(\\d{3})";
var rxpTime = "(\\d{2})(?:(:?)(\\d{2})(?:\\2(\\d{2}))?)?(?:[.,](\\d+))?";
var rxpOffset = "(?:([Zz])|([+-])(\\d{2})(?::?(\\d{2}))?)";
var rxpFullDate = "^(?:(\\d{4})(?:(-?)(\\d{2})(?:\\2(\\d{2}))?)?|(\\d{4})(-?)[Ww](\\d{2})(?:\\6(\\d))?|(\\d{4})-?(\\d{3}))(?=[Tt]|$)"
var rxpFullTime = rxpTime+rxpOffset+"?$";
if(!( RegExp(rxpFullDate+"$").test(isoStr) ||
RegExp("^"+rxpFullTime).test(isoStr) ||
(RegExp(rxpFullDate+"[Tt].*").test(isoStr) && RegExp("^[^Tt]+[Tt]"+rxpFullTime).test(isoStr)) )) return null; //not a supported ISO 8601 string
var now = new Date();
var parts = {year:now.getFullYear(), month:now.getMonth(), day:now.getDate(), hour:0, minute:0, second:0, fraction:0}; //default is midnight this morning, local time
var rxp;
var isoDate = RegExp(rxpFullDate).exec(isoStr);
if(isoDate) //string includes a date
{
try{
isoDate = isoDate[0];
if((rxp = RegExp("^"+rxpCalendarDate+"$")).exec(isoDate)) //calendar date
{
isoDate.replace(rxp, function(match, y, dash, m, d){
if(m!="" && (m<1 || m>12)) throw new RangeError("Month is out of range");
if(d!="" && (d<1 || d>31)) throw new RangeError("Day is out of range");
parts.year = y;
parts.month = m=="" ? 0 : m-1;
parts.day = d=="" ? 1 : d;
if(parts.day > Date.daysInMonth(parts.year, parts.month)) throw new RangeError("Day is out of range");
});
}
else if((rxp = RegExp("^"+rxpWeekDate+"$")).exec(isoDate)) //week date
{
isoDate.replace(rxp, function(match, y, dash, w, d){
if(w<1 || w>53) throw new RangeError("Week number is out of range");
if(d!="" && (d<1 || d>7)) throw new RangeError("Weekday number is out of range");
var jan4th = new Date(y, 0, 4);
var dayOfJan4th = (jan4th.getDay()+6)%7; //0-6 == Mon-Sun
var firstMonday = new Date(jan4th.valueOf() - dayOfJan4th*86400000);
if(w == 53)
{
var mondayAfter52Weeks = (new Date(firstMonday.valueOf() + 52*7*86400000)).getDate();
//if the 53rd week is actually the first week of next year (i.e., it includes Jan 4th), throw range error
if(!(mondayAfter52Weeks > 4 && mondayAfter52Weeks < 29)) throw new RangeError("Week number is out of range");
}
var weekday = d=="" ? 0 : d-1; //0-6 == Mon-Sun
var date = new Date(firstMonday.valueOf() + weekday*86400000 + (w-1)*7*86400000);
parts.year = date.getFullYear();
parts.month = date.getMonth();
parts.day = date.getDate();
});
}
else //ordinal date
{
isoDate.replace(RegExp("^"+rxpOrdinalDate+"$"), function(match, y, d){
if(d > (Date.isLeapYear(y)?366:365)) throw new RangeError("Day number is out of range");
parts.year = y;
var date = new Date((new Date(y, 0, 1)).valueOf() + (d-1)*86400000);
parts.month = date.getMonth();
parts.day = date.getDate();
});
}
}catch(err){
return null; //date string is invalid
}
}
var isoTime = RegExp("(?:^|[Tt])"+rxpFullTime).exec(isoStr);
if(isoTime) //string includes a time
{
try{
isoTime = isoTime[0];
if(isoTime[0].toUpperCase() == "T") isoTime = isoTime.slice(1);
if(RegExp("^"+rxpTime+"$").exec(isoTime)) //if there is no time zone designator
{
//use local time
var date = new Date(parts.year, parts.month, parts.day);
//add hours, minutes, and seconds to date
isoTime.replace(RegExp("^"+rxpTime+"$"), function(match, h, colon, m, s, f){
if(h>24) throw new RangeError("Hour is out of range");
if(m!="" && m>59) throw new RangeError("Minute is out of range");
if(s!="" && s>60) throw new RangeError("Second is out of range");
var val = date.valueOf();
val += h*3600000;
if(m) val += m*60000;
if(s) val += s*1000;
if(f) val += 1000*("."+f.substr(0,3));
date = new Date(val);
});
}
else //there is a time zone designator
{
//use UTC time as base
var date = new Date(Date.UTC(parts.year, parts.month, parts.day));
//add hours, minutes, seconds, and offset to date
isoTime.replace(RegExp("^"+rxpTime+rxpOffset+"$"), function(match, h, colon, m, s, f, z, sign, oh, om){
if(h>24) throw new RangeError("Hour is out of range");
if(m!="" && m>59) throw new RangeError("Minute is out of range");
if(s!="" && s>60) throw new RangeError("Second is out of range");
if(oh!="" && oh>23) throw new RangeError("Offset hour is out of range");
if(om!="" && om>59) throw new RangeError("Offset minute is out of range");
var val = date.valueOf();
val += h*3600000;
if(m) val += m*60000;
if(s) val += s*1000;
if(f) val += 1000*("."+f.substr(0,3));
if(!z) //if there is an offset from UTC time
{
//adjust time according to offset (i.e., convert to UTC time)
sign = sign=="-" ? 1 : -1;
val += sign*oh*3600000;
if(om != "") val += sign*om*60000;
}
date = new Date(val);
});
}
parts.year = date.getFullYear();
parts.month = date.getMonth();
parts.day = date.getDate();
parts.hour = date.getHours();
parts.minute = date.getMinutes();
parts.second = date.getSeconds();
parts.fraction = date.getMilliseconds();
}catch(err){
return null; //time string is invalid
}
}
return new Date(parts.year, parts.month, parts.day, parts.hour, parts.minute, parts.second, parts.fraction);
}
Comments
 Subscribe to comments
                    Subscribe to comments
                
                