mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-11-10 13:18:45 +02:00
--HG-- extra : commitid : F2OWKTvXUO4 extra : rebase_source : ec68631342e0edc59d77b6bab1cdc975ad175327
481 lines
9.7 KiB
JavaScript
481 lines
9.7 KiB
JavaScript
/*!
|
|
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 || {}));
|