diff options
Diffstat (limited to 'toolkit/components/microformats/test/lib/isodate.js')
-rw-r--r-- | toolkit/components/microformats/test/lib/isodate.js | 481 |
1 files changed, 481 insertions, 0 deletions
diff --git a/toolkit/components/microformats/test/lib/isodate.js b/toolkit/components/microformats/test/lib/isodate.js new file mode 100644 index 000000000..30f35f35d --- /dev/null +++ b/toolkit/components/microformats/test/lib/isodate.js @@ -0,0 +1,481 @@ +/*! + iso date + This module was built for the exact needs of parsing ISO dates to the microformats standard. + + * Parses and builds ISO dates to the W3C note, HTML5 or RFC3339 profiles. + * Also allows for profile detection using 'auto' + * Outputs to the same level of specificity of date and time that was input + + Copyright (C) 2010 - 2015 Glenn Jones. All Rights Reserved. + MIT License: https://raw.github.com/glennjones/microformat-shiv/master/license.txt + */ + + + +var Modules = (function (modules) { + + + /** + * constructor + * parses text to find just the date element of an ISO date/time string i.e. 2008-05-01 + * + * @param {String} dateString + * @param {String} format + * @return {String} + */ + modules.ISODate = function ( dateString, format ) { + this.clear(); + + this.format = (format)? format : 'auto'; // auto or W3C or RFC3339 or HTML5 + this.setFormatSep(); + + // optional should be full iso date/time string + if(arguments[0]) { + this.parse(dateString, format); + } + }; + + + modules.ISODate.prototype = { + + + /** + * clear all states + * + */ + clear: function(){ + this.clearDate(); + this.clearTime(); + this.clearTimeZone(); + this.setAutoProfileState(); + }, + + + /** + * clear date states + * + */ + clearDate: function(){ + this.dY = -1; + this.dM = -1; + this.dD = -1; + this.dDDD = -1; + }, + + + /** + * clear time states + * + */ + clearTime: function(){ + this.tH = -1; + this.tM = -1; + this.tS = -1; + this.tD = -1; + }, + + + /** + * clear timezone states + * + */ + clearTimeZone: function(){ + this.tzH = -1; + this.tzM = -1; + this.tzPN = '+'; + this.z = false; + }, + + + /** + * resets the auto profile state + * + */ + setAutoProfileState: function(){ + this.autoProfile = { + sep: 'T', + dsep: '-', + tsep: ':', + tzsep: ':', + tzZulu: 'Z' + }; + }, + + + /** + * parses text to find ISO date/time string i.e. 2008-05-01T15:45:19Z + * + * @param {String} dateString + * @param {String} format + * @return {String} + */ + parse: function( dateString, format ) { + this.clear(); + + var parts = [], + tzArray = [], + position = 0, + datePart = '', + timePart = '', + timeZonePart = ''; + + if(format){ + this.format = format; + } + + + + // discover date time separtor for auto profile + // Set to 'T' by default + if(dateString.indexOf('t') > -1) { + this.autoProfile.sep = 't'; + } + if(dateString.indexOf('z') > -1) { + this.autoProfile.tzZulu = 'z'; + } + if(dateString.indexOf('Z') > -1) { + this.autoProfile.tzZulu = 'Z'; + } + if(dateString.toUpperCase().indexOf('T') === -1) { + this.autoProfile.sep = ' '; + } + + + dateString = dateString.toUpperCase().replace(' ','T'); + + // break on 'T' divider or space + if(dateString.indexOf('T') > -1) { + parts = dateString.split('T'); + datePart = parts[0]; + timePart = parts[1]; + + // zulu UTC + if(timePart.indexOf( 'Z' ) > -1) { + this.z = true; + } + + // timezone + if(timePart.indexOf( '+' ) > -1 || timePart.indexOf( '-' ) > -1) { + tzArray = timePart.split( 'Z' ); // incase of incorrect use of Z + timePart = tzArray[0]; + timeZonePart = tzArray[1]; + + // timezone + if(timePart.indexOf( '+' ) > -1 || timePart.indexOf( '-' ) > -1) { + position = 0; + + if(timePart.indexOf( '+' ) > -1) { + position = timePart.indexOf( '+' ); + } else { + position = timePart.indexOf( '-' ); + } + + timeZonePart = timePart.substring( position, timePart.length ); + timePart = timePart.substring( 0, position ); + } + } + + } else { + datePart = dateString; + } + + if(datePart !== '') { + this.parseDate( datePart ); + if(timePart !== '') { + this.parseTime( timePart ); + if(timeZonePart !== '') { + this.parseTimeZone( timeZonePart ); + } + } + } + return this.toString( format ); + }, + + + /** + * parses text to find just the date element of an ISO date/time string i.e. 2008-05-01 + * + * @param {String} dateString + * @param {String} format + * @return {String} + */ + parseDate: function( dateString, format ) { + this.clearDate(); + + var parts = []; + + // discover timezone separtor for auto profile // default is ':' + if(dateString.indexOf('-') === -1) { + this.autoProfile.tsep = ''; + } + + // YYYY-DDD + parts = dateString.match( /(\d\d\d\d)-(\d\d\d)/ ); + if(parts) { + if(parts[1]) { + this.dY = parts[1]; + } + if(parts[2]) { + this.dDDD = parts[2]; + } + } + + if(this.dDDD === -1) { + // YYYY-MM-DD ie 2008-05-01 and YYYYMMDD ie 20080501 + parts = dateString.match( /(\d\d\d\d)?-?(\d\d)?-?(\d\d)?/ ); + if(parts[1]) { + this.dY = parts[1]; + } + if(parts[2]) { + this.dM = parts[2]; + } + if(parts[3]) { + this.dD = parts[3]; + } + } + return this.toString(format); + }, + + + /** + * parses text to find just the time element of an ISO date/time string i.e. 13:30:45 + * + * @param {String} timeString + * @param {String} format + * @return {String} + */ + parseTime: function( timeString, format ) { + this.clearTime(); + var parts = []; + + // discover date separtor for auto profile // default is ':' + if(timeString.indexOf(':') === -1) { + this.autoProfile.tsep = ''; + } + + // finds timezone HH:MM:SS and HHMMSS ie 13:30:45, 133045 and 13:30:45.0135 + parts = timeString.match( /(\d\d)?:?(\d\d)?:?(\d\d)?.?([0-9]+)?/ ); + if(parts[1]) { + this.tH = parts[1]; + } + if(parts[2]) { + this.tM = parts[2]; + } + if(parts[3]) { + this.tS = parts[3]; + } + if(parts[4]) { + this.tD = parts[4]; + } + return this.toTimeString(format); + }, + + + /** + * parses text to find just the time element of an ISO date/time string i.e. +08:00 + * + * @param {String} timeString + * @param {String} format + * @return {String} + */ + parseTimeZone: function( timeString, format ) { + this.clearTimeZone(); + var parts = []; + + if(timeString.toLowerCase() === 'z'){ + this.z = true; + // set case for z + this.autoProfile.tzZulu = (timeString === 'z')? 'z' : 'Z'; + }else{ + + // discover timezone separtor for auto profile // default is ':' + if(timeString.indexOf(':') === -1) { + this.autoProfile.tzsep = ''; + } + + // finds timezone +HH:MM and +HHMM ie +13:30 and +1330 + parts = timeString.match( /([\-\+]{1})?(\d\d)?:?(\d\d)?/ ); + if(parts[1]) { + this.tzPN = parts[1]; + } + if(parts[2]) { + this.tzH = parts[2]; + } + if(parts[3]) { + this.tzM = parts[3]; + } + + + } + this.tzZulu = 'z'; + return this.toTimeString( format ); + }, + + + /** + * returns ISO date/time string in W3C Note, RFC 3339, HTML5, or auto profile + * + * @param {String} format + * @return {String} + */ + toString: function( format ) { + var output = ''; + + if(format){ + this.format = format; + } + this.setFormatSep(); + + if(this.dY > -1) { + output = this.dY; + if(this.dM > 0 && this.dM < 13) { + output += this.dsep + this.dM; + if(this.dD > 0 && this.dD < 32) { + output += this.dsep + this.dD; + if(this.tH > -1 && this.tH < 25) { + output += this.sep + this.toTimeString( format ); + } + } + } + if(this.dDDD > -1) { + output += this.dsep + this.dDDD; + } + } else if(this.tH > -1) { + output += this.toTimeString( format ); + } + + return output; + }, + + + /** + * returns just the time string element of an ISO date/time + * in W3C Note, RFC 3339, HTML5, or auto profile + * + * @param {String} format + * @return {String} + */ + toTimeString: function( format ) { + var out = ''; + + if(format){ + this.format = format; + } + this.setFormatSep(); + + // time can only be created with a full date + if(this.tH) { + if(this.tH > -1 && this.tH < 25) { + out += this.tH; + if(this.tM > -1 && this.tM < 61){ + out += this.tsep + this.tM; + if(this.tS > -1 && this.tS < 61){ + out += this.tsep + this.tS; + if(this.tD > -1){ + out += '.' + this.tD; + } + } + } + + + + // time zone offset + if(this.z) { + out += this.tzZulu; + } else { + if(this.tzH && this.tzH > -1 && this.tzH < 25) { + out += this.tzPN + this.tzH; + if(this.tzM > -1 && this.tzM < 61){ + out += this.tzsep + this.tzM; + } + } + } + } + } + return out; + }, + + + /** + * set the current profile to W3C Note, RFC 3339, HTML5, or auto profile + * + */ + setFormatSep: function() { + switch( this.format.toLowerCase() ) { + case 'rfc3339': + this.sep = 'T'; + this.dsep = ''; + this.tsep = ''; + this.tzsep = ''; + this.tzZulu = 'Z'; + break; + case 'w3c': + this.sep = 'T'; + this.dsep = '-'; + this.tsep = ':'; + this.tzsep = ':'; + this.tzZulu = 'Z'; + break; + case 'html5': + this.sep = ' '; + this.dsep = '-'; + this.tsep = ':'; + this.tzsep = ':'; + this.tzZulu = 'Z'; + break; + default: + // auto - defined by format of input string + this.sep = this.autoProfile.sep; + this.dsep = this.autoProfile.dsep; + this.tsep = this.autoProfile.tsep; + this.tzsep = this.autoProfile.tzsep; + this.tzZulu = this.autoProfile.tzZulu; + } + }, + + + /** + * does current data contain a full date i.e. 2015-03-23 + * + * @return {Boolean} + */ + hasFullDate: function() { + return(this.dY !== -1 && this.dM !== -1 && this.dD !== -1); + }, + + + /** + * does current data contain a minimum date which is just a year number i.e. 2015 + * + * @return {Boolean} + */ + hasDate: function() { + return(this.dY !== -1); + }, + + + /** + * does current data contain a minimum time which is just a hour number i.e. 13 + * + * @return {Boolean} + */ + hasTime: function() { + return(this.tH !== -1); + }, + + /** + * does current data contain a minimum timezone i.e. -1 || +1 || z + * + * @return {Boolean} + */ + hasTimeZone: function() { + return(this.tzH !== -1); + } + + }; + + modules.ISODate.prototype.constructor = modules.ISODate; + + return modules; + +} (Modules || {})); |