2014-08-20 14:41:50 -04:00
//! moment.js
//! version : 2.8.1
//! authors : Tim Wood, Iskren Chernev, Moment.js contributors
//! license : MIT
//! momentjs.com
2013-06-06 18:49:09 -04:00
( function ( undefined ) {
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Constants
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
var moment ,
2014-08-20 14:41:50 -04:00
VERSION = '2.8.1' ,
// the global-scope this is NOT the global object in Node.js
globalScope = typeof global !== 'undefined' ? global : this ,
oldGlobalMoment ,
round = Math . round ,
i ,
YEAR = 0 ,
MONTH = 1 ,
DATE = 2 ,
HOUR = 3 ,
MINUTE = 4 ,
SECOND = 5 ,
MILLISECOND = 6 ,
// internal storage for locale config files
locales = { } ,
// extra moment internal properties (plugins register props here)
momentProperties = [ ] ,
2013-06-06 18:49:09 -04:00
// check for nodeJS
hasModule = ( typeof module !== 'undefined' && module . exports ) ,
// ASP.NET json date format regex
aspNetJsonRegex = /^\/?Date\((\-?\d+)/i ,
2014-08-20 14:41:50 -04:00
aspNetTimeSpanJsonRegex = /(\-)?(?:(\d*)\.)?(\d+)\:(\d+)(?:\:(\d+)\.?(\d{3})?)?/ ,
// from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html
// somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere
isoDurationRegex = /^(-)?P(?:(?:([0-9,.]*)Y)?(?:([0-9,.]*)M)?(?:([0-9,.]*)D)?(?:T(?:([0-9,.]*)H)?(?:([0-9,.]*)M)?(?:([0-9,.]*)S)?)?|([0-9,.]*)W)$/ ,
2013-06-06 18:49:09 -04:00
// format tokens
2014-08-20 14:41:50 -04:00
formattingTokens = /(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Q|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|S{1,4}|X|zz?|ZZ?|.)/g ,
2013-06-06 18:49:09 -04:00
localFormattingTokens = /(\[[^\[]*\])|(\\)?(LT|LL?L?L?|l{1,4})/g ,
// parsing token regexes
parseTokenOneOrTwoDigits = /\d\d?/ , // 0 - 99
parseTokenOneToThreeDigits = /\d{1,3}/ , // 0 - 999
2014-08-20 14:41:50 -04:00
parseTokenOneToFourDigits = /\d{1,4}/ , // 0 - 9999
parseTokenOneToSixDigits = /[+\-]?\d{1,6}/ , // -999,999 - 999,999
parseTokenDigits = /\d+/ , // nonzero number of digits
2013-06-06 18:49:09 -04:00
parseTokenWord = /[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i , // any word (or two) characters or numbers including two/three word month in arabic.
2014-08-20 14:41:50 -04:00
parseTokenTimezone = /Z|[\+\-]\d\d:?\d\d/gi , // +00:00 -00:00 +0000 -0000 or Z
parseTokenT = /T/i , // T (ISO separator)
2013-06-06 18:49:09 -04:00
parseTokenTimestampMs = /[\+\-]?\d+(\.\d{1,3})?/ , // 123456789 123456789.123
2014-08-20 14:41:50 -04:00
parseTokenOrdinal = /\d{1,2}/ ,
//strict parsing regexes
parseTokenOneDigit = /\d/ , // 0 - 9
parseTokenTwoDigits = /\d\d/ , // 00 - 99
parseTokenThreeDigits = /\d{3}/ , // 000 - 999
parseTokenFourDigits = /\d{4}/ , // 0000 - 9999
parseTokenSixDigits = /[+-]?\d{6}/ , // -999,999 - 999,999
parseTokenSignedNumber = /[+-]?\d+/ , // -inf - inf
// iso 8601 regex
// 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00)
isoRegex = /^\s*(?:[+-]\d{6}|\d{4})-(?:(\d\d-\d\d)|(W\d\d$)|(W\d\d-\d)|(\d\d\d))((T| )(\d\d(:\d\d(:\d\d(\.\d+)?)?)?)?([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/ ,
2013-06-06 18:49:09 -04:00
isoFormat = 'YYYY-MM-DDTHH:mm:ssZ' ,
2014-08-20 14:41:50 -04:00
isoDates = [
[ 'YYYYYY-MM-DD' , /[+-]\d{6}-\d{2}-\d{2}/ ] ,
[ 'YYYY-MM-DD' , /\d{4}-\d{2}-\d{2}/ ] ,
[ 'GGGG-[W]WW-E' , /\d{4}-W\d{2}-\d/ ] ,
[ 'GGGG-[W]WW' , /\d{4}-W\d{2}/ ] ,
[ 'YYYY-DDD' , /\d{4}-\d{3}/ ]
] ,
2013-06-06 18:49:09 -04:00
// iso time formats and regexes
isoTimes = [
2014-08-20 14:41:50 -04:00
[ 'HH:mm:ss.SSSS' , /(T| )\d\d:\d\d:\d\d\.\d+/ ] ,
2013-06-06 18:49:09 -04:00
[ 'HH:mm:ss' , /(T| )\d\d:\d\d:\d\d/ ] ,
[ 'HH:mm' , /(T| )\d\d:\d\d/ ] ,
[ 'HH' , /(T| )\d\d/ ]
] ,
// timezone chunker "+10:00" > ["10", "00"] or "-1530" > ["-15", "30"]
parseTimezoneChunker = /([\+\-]|\d\d)/gi ,
// getter and setter names
proxyGettersAndSetters = 'Date|Hours|Minutes|Seconds|Milliseconds' . split ( '|' ) ,
unitMillisecondFactors = {
'Milliseconds' : 1 ,
'Seconds' : 1e3 ,
'Minutes' : 6e4 ,
'Hours' : 36e5 ,
'Days' : 864e5 ,
'Months' : 2592e6 ,
'Years' : 31536e6
} ,
unitAliases = {
ms : 'millisecond' ,
s : 'second' ,
m : 'minute' ,
h : 'hour' ,
d : 'day' ,
2014-08-20 14:41:50 -04:00
D : 'date' ,
2013-06-06 18:49:09 -04:00
w : 'week' ,
2014-08-20 14:41:50 -04:00
W : 'isoWeek' ,
2013-06-06 18:49:09 -04:00
M : 'month' ,
2014-08-20 14:41:50 -04:00
Q : 'quarter' ,
y : 'year' ,
DDD : 'dayOfYear' ,
e : 'weekday' ,
E : 'isoWeekday' ,
gg : 'weekYear' ,
GG : 'isoWeekYear'
} ,
camelFunctions = {
dayofyear : 'dayOfYear' ,
isoweekday : 'isoWeekday' ,
isoweek : 'isoWeek' ,
weekyear : 'weekYear' ,
isoweekyear : 'isoWeekYear'
2013-06-06 18:49:09 -04:00
} ,
// format function strings
formatFunctions = { } ,
2014-08-20 14:41:50 -04:00
// default relative time thresholds
relativeTimeThresholds = {
s : 45 , // seconds to minute
m : 45 , // minutes to hour
h : 22 , // hours to day
d : 26 , // days to month
M : 11 // months to year
} ,
2013-06-06 18:49:09 -04:00
// tokens to ordinalize and pad
ordinalizeTokens = 'DDD w W M D d' . split ( ' ' ) ,
paddedTokens = 'M D H h m s w W' . split ( ' ' ) ,
formatTokenFunctions = {
M : function ( ) {
return this . month ( ) + 1 ;
} ,
MMM : function ( format ) {
2014-08-20 14:41:50 -04:00
return this . localeData ( ) . monthsShort ( this , format ) ;
2013-06-06 18:49:09 -04:00
} ,
MMMM : function ( format ) {
2014-08-20 14:41:50 -04:00
return this . localeData ( ) . months ( this , format ) ;
2013-06-06 18:49:09 -04:00
} ,
D : function ( ) {
return this . date ( ) ;
} ,
DDD : function ( ) {
return this . dayOfYear ( ) ;
} ,
d : function ( ) {
return this . day ( ) ;
} ,
dd : function ( format ) {
2014-08-20 14:41:50 -04:00
return this . localeData ( ) . weekdaysMin ( this , format ) ;
2013-06-06 18:49:09 -04:00
} ,
ddd : function ( format ) {
2014-08-20 14:41:50 -04:00
return this . localeData ( ) . weekdaysShort ( this , format ) ;
2013-06-06 18:49:09 -04:00
} ,
dddd : function ( format ) {
2014-08-20 14:41:50 -04:00
return this . localeData ( ) . weekdays ( this , format ) ;
2013-06-06 18:49:09 -04:00
} ,
w : function ( ) {
return this . week ( ) ;
} ,
W : function ( ) {
return this . isoWeek ( ) ;
} ,
YY : function ( ) {
return leftZeroFill ( this . year ( ) % 100 , 2 ) ;
} ,
YYYY : function ( ) {
return leftZeroFill ( this . year ( ) , 4 ) ;
} ,
YYYYY : function ( ) {
return leftZeroFill ( this . year ( ) , 5 ) ;
} ,
2014-08-20 14:41:50 -04:00
YYYYYY : function ( ) {
var y = this . year ( ) , sign = y >= 0 ? '+' : '-' ;
return sign + leftZeroFill ( Math . abs ( y ) , 6 ) ;
} ,
2013-06-06 18:49:09 -04:00
gg : function ( ) {
return leftZeroFill ( this . weekYear ( ) % 100 , 2 ) ;
} ,
gggg : function ( ) {
2014-08-20 14:41:50 -04:00
return leftZeroFill ( this . weekYear ( ) , 4 ) ;
2013-06-06 18:49:09 -04:00
} ,
ggggg : function ( ) {
return leftZeroFill ( this . weekYear ( ) , 5 ) ;
} ,
GG : function ( ) {
return leftZeroFill ( this . isoWeekYear ( ) % 100 , 2 ) ;
} ,
GGGG : function ( ) {
2014-08-20 14:41:50 -04:00
return leftZeroFill ( this . isoWeekYear ( ) , 4 ) ;
2013-06-06 18:49:09 -04:00
} ,
GGGGG : function ( ) {
return leftZeroFill ( this . isoWeekYear ( ) , 5 ) ;
} ,
e : function ( ) {
return this . weekday ( ) ;
} ,
E : function ( ) {
return this . isoWeekday ( ) ;
} ,
a : function ( ) {
2014-08-20 14:41:50 -04:00
return this . localeData ( ) . meridiem ( this . hours ( ) , this . minutes ( ) , true ) ;
2013-06-06 18:49:09 -04:00
} ,
A : function ( ) {
2014-08-20 14:41:50 -04:00
return this . localeData ( ) . meridiem ( this . hours ( ) , this . minutes ( ) , false ) ;
2013-06-06 18:49:09 -04:00
} ,
H : function ( ) {
return this . hours ( ) ;
} ,
h : function ( ) {
return this . hours ( ) % 12 || 12 ;
} ,
m : function ( ) {
return this . minutes ( ) ;
} ,
s : function ( ) {
return this . seconds ( ) ;
} ,
S : function ( ) {
2014-08-20 14:41:50 -04:00
return toInt ( this . milliseconds ( ) / 100 ) ;
2013-06-06 18:49:09 -04:00
} ,
SS : function ( ) {
2014-08-20 14:41:50 -04:00
return leftZeroFill ( toInt ( this . milliseconds ( ) / 10 ) , 2 ) ;
2013-06-06 18:49:09 -04:00
} ,
SSS : function ( ) {
return leftZeroFill ( this . milliseconds ( ) , 3 ) ;
} ,
2014-08-20 14:41:50 -04:00
SSSS : function ( ) {
return leftZeroFill ( this . milliseconds ( ) , 3 ) ;
} ,
2013-06-06 18:49:09 -04:00
Z : function ( ) {
var a = - this . zone ( ) ,
2014-08-20 14:41:50 -04:00
b = '+' ;
2013-06-06 18:49:09 -04:00
if ( a < 0 ) {
a = - a ;
2014-08-20 14:41:50 -04:00
b = '-' ;
2013-06-06 18:49:09 -04:00
}
2014-08-20 14:41:50 -04:00
return b + leftZeroFill ( toInt ( a / 60 ) , 2 ) + ':' + leftZeroFill ( toInt ( a ) % 60 , 2 ) ;
2013-06-06 18:49:09 -04:00
} ,
ZZ : function ( ) {
var a = - this . zone ( ) ,
2014-08-20 14:41:50 -04:00
b = '+' ;
2013-06-06 18:49:09 -04:00
if ( a < 0 ) {
a = - a ;
2014-08-20 14:41:50 -04:00
b = '-' ;
2013-06-06 18:49:09 -04:00
}
2014-08-20 14:41:50 -04:00
return b + leftZeroFill ( toInt ( a / 60 ) , 2 ) + leftZeroFill ( toInt ( a ) % 60 , 2 ) ;
2013-06-06 18:49:09 -04:00
} ,
z : function ( ) {
return this . zoneAbbr ( ) ;
} ,
zz : function ( ) {
return this . zoneName ( ) ;
} ,
X : function ( ) {
return this . unix ( ) ;
2014-08-20 14:41:50 -04:00
} ,
Q : function ( ) {
return this . quarter ( ) ;
2013-06-06 18:49:09 -04:00
}
2014-08-20 14:41:50 -04:00
} ,
deprecations = { } ,
lists = [ 'months' , 'monthsShort' , 'weekdays' , 'weekdaysShort' , 'weekdaysMin' ] ;
// Pick the first defined of two or three arguments. dfl comes from
// default.
function dfl ( a , b , c ) {
switch ( arguments . length ) {
case 2 : return a != null ? a : b ;
case 3 : return a != null ? a : b != null ? b : c ;
default : throw new Error ( 'Implement me' ) ;
}
}
function defaultParsingFlags ( ) {
// We need to deep clone this object, and es5 standard is not very
// helpful.
return {
empty : false ,
unusedTokens : [ ] ,
unusedInput : [ ] ,
overflow : - 2 ,
charsLeftOver : 0 ,
nullInput : false ,
invalidMonth : null ,
invalidFormat : false ,
userInvalidated : false ,
iso : false
2013-06-06 18:49:09 -04:00
} ;
2014-08-20 14:41:50 -04:00
}
function printMsg ( msg ) {
if ( moment . suppressDeprecationWarnings === false &&
typeof console !== 'undefined' && console . warn ) {
console . warn ( "Deprecation warning: " + msg ) ;
}
}
function deprecate ( msg , fn ) {
var firstTime = true ;
return extend ( function ( ) {
if ( firstTime ) {
printMsg ( msg ) ;
firstTime = false ;
}
return fn . apply ( this , arguments ) ;
} , fn ) ;
}
function deprecateSimple ( name , msg ) {
if ( ! deprecations [ name ] ) {
printMsg ( msg ) ;
deprecations [ name ] = true ;
}
}
2013-06-06 18:49:09 -04:00
function padToken ( func , count ) {
return function ( a ) {
return leftZeroFill ( func . call ( this , a ) , count ) ;
} ;
}
function ordinalizeToken ( func , period ) {
return function ( a ) {
2014-08-20 14:41:50 -04:00
return this . localeData ( ) . ordinal ( func . call ( this , a ) , period ) ;
2013-06-06 18:49:09 -04:00
} ;
}
while ( ordinalizeTokens . length ) {
i = ordinalizeTokens . pop ( ) ;
formatTokenFunctions [ i + 'o' ] = ordinalizeToken ( formatTokenFunctions [ i ] , i ) ;
}
while ( paddedTokens . length ) {
i = paddedTokens . pop ( ) ;
formatTokenFunctions [ i + i ] = padToken ( formatTokenFunctions [ i ] , 2 ) ;
}
formatTokenFunctions . DDDD = padToken ( formatTokenFunctions . DDD , 3 ) ;
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Constructors
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
2014-08-20 14:41:50 -04:00
function Locale ( ) {
2013-06-06 18:49:09 -04:00
}
// Moment prototype object
2014-08-20 14:41:50 -04:00
function Moment ( config , skipOverflow ) {
if ( skipOverflow !== false ) {
checkOverflow ( config ) ;
}
copyConfig ( this , config ) ;
this . _d = new Date ( + config . _d ) ;
2013-06-06 18:49:09 -04:00
}
// Duration Constructor
function Duration ( duration ) {
2014-08-20 14:41:50 -04:00
var normalizedInput = normalizeObjectUnits ( duration ) ,
years = normalizedInput . year || 0 ,
quarters = normalizedInput . quarter || 0 ,
months = normalizedInput . month || 0 ,
weeks = normalizedInput . week || 0 ,
days = normalizedInput . day || 0 ,
hours = normalizedInput . hour || 0 ,
minutes = normalizedInput . minute || 0 ,
seconds = normalizedInput . second || 0 ,
milliseconds = normalizedInput . millisecond || 0 ;
2013-06-06 18:49:09 -04:00
// representation for dateAddRemove
2014-08-20 14:41:50 -04:00
this . _milliseconds = + milliseconds +
2013-06-06 18:49:09 -04:00
seconds * 1e3 + // 1000
minutes * 6e4 + // 1000 * 60
hours * 36e5 ; // 1000 * 60 * 60
// Because of dateAddRemove treats 24 hours as different from a
// day when working around DST, we need to store them separately
2014-08-20 14:41:50 -04:00
this . _days = + days +
2013-06-06 18:49:09 -04:00
weeks * 7 ;
// It is impossible translate months into days without knowing
// which months you are are talking about, so we have to store
// it separately.
2014-08-20 14:41:50 -04:00
this . _months = + months +
quarters * 3 +
2013-06-06 18:49:09 -04:00
years * 12 ;
2014-08-20 14:41:50 -04:00
this . _data = { } ;
2013-06-06 18:49:09 -04:00
2014-08-20 14:41:50 -04:00
this . _locale = moment . localeData ( ) ;
2013-06-06 18:49:09 -04:00
2014-08-20 14:41:50 -04:00
this . _bubble ( ) ;
2013-06-06 18:49:09 -04:00
}
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Helpers
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
function extend ( a , b ) {
for ( var i in b ) {
if ( b . hasOwnProperty ( i ) ) {
a [ i ] = b [ i ] ;
}
}
2014-08-20 14:41:50 -04:00
if ( b . hasOwnProperty ( 'toString' ) ) {
a . toString = b . toString ;
}
if ( b . hasOwnProperty ( 'valueOf' ) ) {
a . valueOf = b . valueOf ;
}
2013-06-06 18:49:09 -04:00
return a ;
}
2014-08-20 14:41:50 -04:00
function copyConfig ( to , from ) {
var i , prop , val ;
if ( typeof from . _isAMomentObject !== 'undefined' ) {
to . _isAMomentObject = from . _isAMomentObject ;
}
if ( typeof from . _i !== 'undefined' ) {
to . _i = from . _i ;
}
if ( typeof from . _f !== 'undefined' ) {
to . _f = from . _f ;
}
if ( typeof from . _l !== 'undefined' ) {
to . _l = from . _l ;
}
if ( typeof from . _strict !== 'undefined' ) {
to . _strict = from . _strict ;
}
if ( typeof from . _tzm !== 'undefined' ) {
to . _tzm = from . _tzm ;
}
if ( typeof from . _isUTC !== 'undefined' ) {
to . _isUTC = from . _isUTC ;
}
if ( typeof from . _offset !== 'undefined' ) {
to . _offset = from . _offset ;
}
if ( typeof from . _pf !== 'undefined' ) {
to . _pf = from . _pf ;
}
if ( typeof from . _locale !== 'undefined' ) {
to . _locale = from . _locale ;
}
if ( momentProperties . length > 0 ) {
for ( i in momentProperties ) {
prop = momentProperties [ i ] ;
val = from [ prop ] ;
if ( typeof val !== 'undefined' ) {
to [ prop ] = val ;
}
}
}
return to ;
}
2013-06-06 18:49:09 -04:00
function absRound ( number ) {
if ( number < 0 ) {
return Math . ceil ( number ) ;
} else {
return Math . floor ( number ) ;
}
}
// left zero fill a number
// see http://jsperf.com/left-zero-filling for performance comparison
2014-08-20 14:41:50 -04:00
function leftZeroFill ( number , targetLength , forceSign ) {
var output = '' + Math . abs ( number ) ,
sign = number >= 0 ;
2013-06-06 18:49:09 -04:00
while ( output . length < targetLength ) {
output = '0' + output ;
}
2014-08-20 14:41:50 -04:00
return ( sign ? ( forceSign ? '+' : '' ) : '-' ) + output ;
}
function positiveMomentsDifference ( base , other ) {
var res = { milliseconds : 0 , months : 0 } ;
res . months = other . month ( ) - base . month ( ) +
( other . year ( ) - base . year ( ) ) * 12 ;
if ( base . clone ( ) . add ( res . months , 'M' ) . isAfter ( other ) ) {
-- res . months ;
}
res . milliseconds = + other - + ( base . clone ( ) . add ( res . months , 'M' ) ) ;
return res ;
}
function momentsDifference ( base , other ) {
var res ;
other = makeAs ( other , base ) ;
if ( base . isBefore ( other ) ) {
res = positiveMomentsDifference ( base , other ) ;
} else {
res = positiveMomentsDifference ( other , base ) ;
res . milliseconds = - res . milliseconds ;
res . months = - res . months ;
}
return res ;
}
// TODO: remove 'name' arg after deprecation is removed
function createAdder ( direction , name ) {
return function ( val , period ) {
var dur , tmp ;
//invert the arguments, but complain about it
if ( period !== null && ! isNaN ( + period ) ) {
deprecateSimple ( name , "moment()." + name + "(period, number) is deprecated. Please use moment()." + name + "(number, period)." ) ;
tmp = val ; val = period ; period = tmp ;
}
val = typeof val === 'string' ? + val : val ;
dur = moment . duration ( val , period ) ;
addOrSubtractDurationFromMoment ( this , dur , direction ) ;
return this ;
} ;
2013-06-06 18:49:09 -04:00
}
2014-08-20 14:41:50 -04:00
function addOrSubtractDurationFromMoment ( mom , duration , isAdding , updateOffset ) {
2013-06-06 18:49:09 -04:00
var milliseconds = duration . _milliseconds ,
days = duration . _days ,
2014-08-20 14:41:50 -04:00
months = duration . _months ;
updateOffset = updateOffset == null ? true : updateOffset ;
2013-06-06 18:49:09 -04:00
if ( milliseconds ) {
mom . _d . setTime ( + mom . _d + milliseconds * isAdding ) ;
}
if ( days ) {
2014-08-20 14:41:50 -04:00
rawSetter ( mom , 'Date' , rawGetter ( mom , 'Date' ) + days * isAdding ) ;
2013-06-06 18:49:09 -04:00
}
if ( months ) {
2014-08-20 14:41:50 -04:00
rawMonthSetter ( mom , rawGetter ( mom , 'Month' ) + months * isAdding ) ;
2013-06-06 18:49:09 -04:00
}
2014-08-20 14:41:50 -04:00
if ( updateOffset ) {
moment . updateOffset ( mom , days || months ) ;
2013-06-06 18:49:09 -04:00
}
}
// check if is an array
function isArray ( input ) {
return Object . prototype . toString . call ( input ) === '[object Array]' ;
}
2014-08-20 14:41:50 -04:00
function isDate ( input ) {
return Object . prototype . toString . call ( input ) === '[object Date]' ||
input instanceof Date ;
}
2013-06-06 18:49:09 -04:00
// compare two arrays, return the number of differences
2014-08-20 14:41:50 -04:00
function compareArrays ( array1 , array2 , dontConvert ) {
2013-06-06 18:49:09 -04:00
var len = Math . min ( array1 . length , array2 . length ) ,
lengthDiff = Math . abs ( array1 . length - array2 . length ) ,
diffs = 0 ,
i ;
for ( i = 0 ; i < len ; i ++ ) {
2014-08-20 14:41:50 -04:00
if ( ( dontConvert && array1 [ i ] !== array2 [ i ] ) ||
( ! dontConvert && toInt ( array1 [ i ] ) !== toInt ( array2 [ i ] ) ) ) {
2013-06-06 18:49:09 -04:00
diffs ++ ;
}
}
return diffs + lengthDiff ;
}
function normalizeUnits ( units ) {
2014-08-20 14:41:50 -04:00
if ( units ) {
var lowered = units . toLowerCase ( ) . replace ( /(.)s$/ , '$1' ) ;
units = unitAliases [ units ] || camelFunctions [ lowered ] || lowered ;
}
return units ;
}
function normalizeObjectUnits ( inputObject ) {
var normalizedInput = { } ,
normalizedProp ,
prop ;
for ( prop in inputObject ) {
if ( inputObject . hasOwnProperty ( prop ) ) {
normalizedProp = normalizeUnits ( prop ) ;
if ( normalizedProp ) {
normalizedInput [ normalizedProp ] = inputObject [ prop ] ;
}
}
}
return normalizedInput ;
}
function makeList ( field ) {
var count , setter ;
if ( field . indexOf ( 'week' ) === 0 ) {
count = 7 ;
setter = 'day' ;
}
else if ( field . indexOf ( 'month' ) === 0 ) {
count = 12 ;
setter = 'month' ;
}
else {
return ;
}
moment [ field ] = function ( format , index ) {
var i , getter ,
method = moment . _locale [ field ] ,
results = [ ] ;
if ( typeof format === 'number' ) {
index = format ;
format = undefined ;
}
getter = function ( i ) {
var m = moment ( ) . utc ( ) . set ( setter , i ) ;
return method . call ( moment . _locale , m , format || '' ) ;
} ;
if ( index != null ) {
return getter ( index ) ;
}
else {
for ( i = 0 ; i < count ; i ++ ) {
results . push ( getter ( i ) ) ;
}
return results ;
}
} ;
}
function toInt ( argumentForCoercion ) {
var coercedNumber = + argumentForCoercion ,
value = 0 ;
if ( coercedNumber !== 0 && isFinite ( coercedNumber ) ) {
if ( coercedNumber >= 0 ) {
value = Math . floor ( coercedNumber ) ;
} else {
value = Math . ceil ( coercedNumber ) ;
}
}
return value ;
}
function daysInMonth ( year , month ) {
return new Date ( Date . UTC ( year , month + 1 , 0 ) ) . getUTCDate ( ) ;
}
function weeksInYear ( year , dow , doy ) {
return weekOfYear ( moment ( [ year , 11 , 31 + dow - doy ] ) , dow , doy ) . week ;
}
function daysInYear ( year ) {
return isLeapYear ( year ) ? 366 : 365 ;
}
function isLeapYear ( year ) {
return ( year % 4 === 0 && year % 100 !== 0 ) || year % 400 === 0 ;
2013-06-06 18:49:09 -04:00
}
2014-08-20 14:41:50 -04:00
function checkOverflow ( m ) {
var overflow ;
if ( m . _a && m . _pf . overflow === - 2 ) {
overflow =
m . _a [ MONTH ] < 0 || m . _a [ MONTH ] > 11 ? MONTH :
m . _a [ DATE ] < 1 || m . _a [ DATE ] > daysInMonth ( m . _a [ YEAR ] , m . _a [ MONTH ] ) ? DATE :
m . _a [ HOUR ] < 0 || m . _a [ HOUR ] > 23 ? HOUR :
m . _a [ MINUTE ] < 0 || m . _a [ MINUTE ] > 59 ? MINUTE :
m . _a [ SECOND ] < 0 || m . _a [ SECOND ] > 59 ? SECOND :
m . _a [ MILLISECOND ] < 0 || m . _a [ MILLISECOND ] > 999 ? MILLISECOND :
- 1 ;
if ( m . _pf . _overflowDayOfYear && ( overflow < YEAR || overflow > DATE ) ) {
overflow = DATE ;
}
m . _pf . overflow = overflow ;
}
}
function isValid ( m ) {
if ( m . _isValid == null ) {
m . _isValid = ! isNaN ( m . _d . getTime ( ) ) &&
m . _pf . overflow < 0 &&
! m . _pf . empty &&
! m . _pf . invalidMonth &&
! m . _pf . nullInput &&
! m . _pf . invalidFormat &&
! m . _pf . userInvalidated ;
if ( m . _strict ) {
m . _isValid = m . _isValid &&
m . _pf . charsLeftOver === 0 &&
m . _pf . unusedTokens . length === 0 ;
}
}
return m . _isValid ;
}
function normalizeLocale ( key ) {
return key ? key . toLowerCase ( ) . replace ( '_' , '-' ) : key ;
}
// pick the locale from the array
// try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each
// substring from most specific to least, but move to the next array item if it's a more specific variant than the current root
function chooseLocale ( names ) {
var i = 0 , j , next , locale , split ;
while ( i < names . length ) {
split = normalizeLocale ( names [ i ] ) . split ( '-' ) ;
j = split . length ;
next = normalizeLocale ( names [ i + 1 ] ) ;
next = next ? next . split ( '-' ) : null ;
while ( j > 0 ) {
locale = loadLocale ( split . slice ( 0 , j ) . join ( '-' ) ) ;
if ( locale ) {
return locale ;
}
if ( next && next . length >= j && compareArrays ( split , next , true ) >= j - 1 ) {
//the next array item is better than a shallower substring of this one
break ;
}
j -- ;
}
i ++ ;
}
return null ;
}
function loadLocale ( name ) {
var oldLocale = null ;
if ( ! locales [ name ] && hasModule ) {
try {
oldLocale = moment . locale ( ) ;
require ( './locale/' + name ) ;
// because defineLocale currently also sets the global locale, we want to undo that for lazy loaded locales
moment . locale ( oldLocale ) ;
} catch ( e ) { }
}
return locales [ name ] ;
}
// Return a moment from input, that is local/utc/zone equivalent to model.
function makeAs ( input , model ) {
return model . _isUTC ? moment ( input ) . zone ( model . _offset || 0 ) :
moment ( input ) . local ( ) ;
}
2013-06-06 18:49:09 -04:00
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2014-08-20 14:41:50 -04:00
Locale
2013-06-06 18:49:09 -04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
2014-08-20 14:41:50 -04:00
extend ( Locale . prototype , {
2013-06-06 18:49:09 -04:00
set : function ( config ) {
var prop , i ;
for ( i in config ) {
prop = config [ i ] ;
if ( typeof prop === 'function' ) {
this [ i ] = prop ;
} else {
this [ '_' + i ] = prop ;
}
}
} ,
2014-08-20 14:41:50 -04:00
_months : 'January_February_March_April_May_June_July_August_September_October_November_December' . split ( '_' ) ,
2013-06-06 18:49:09 -04:00
months : function ( m ) {
return this . _months [ m . month ( ) ] ;
} ,
2014-08-20 14:41:50 -04:00
_monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec' . split ( '_' ) ,
2013-06-06 18:49:09 -04:00
monthsShort : function ( m ) {
return this . _monthsShort [ m . month ( ) ] ;
} ,
monthsParse : function ( monthName ) {
var i , mom , regex ;
if ( ! this . _monthsParse ) {
this . _monthsParse = [ ] ;
}
for ( i = 0 ; i < 12 ; i ++ ) {
// make the regex if we don't have it already
if ( ! this . _monthsParse [ i ] ) {
2014-08-20 14:41:50 -04:00
mom = moment . utc ( [ 2000 , i ] ) ;
2013-06-06 18:49:09 -04:00
regex = '^' + this . months ( mom , '' ) + '|^' + this . monthsShort ( mom , '' ) ;
this . _monthsParse [ i ] = new RegExp ( regex . replace ( '.' , '' ) , 'i' ) ;
}
// test the regex
if ( this . _monthsParse [ i ] . test ( monthName ) ) {
return i ;
}
}
} ,
2014-08-20 14:41:50 -04:00
_weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday' . split ( '_' ) ,
2013-06-06 18:49:09 -04:00
weekdays : function ( m ) {
return this . _weekdays [ m . day ( ) ] ;
} ,
2014-08-20 14:41:50 -04:00
_weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat' . split ( '_' ) ,
2013-06-06 18:49:09 -04:00
weekdaysShort : function ( m ) {
return this . _weekdaysShort [ m . day ( ) ] ;
} ,
2014-08-20 14:41:50 -04:00
_weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa' . split ( '_' ) ,
2013-06-06 18:49:09 -04:00
weekdaysMin : function ( m ) {
return this . _weekdaysMin [ m . day ( ) ] ;
} ,
weekdaysParse : function ( weekdayName ) {
var i , mom , regex ;
if ( ! this . _weekdaysParse ) {
this . _weekdaysParse = [ ] ;
}
for ( i = 0 ; i < 7 ; i ++ ) {
// make the regex if we don't have it already
if ( ! this . _weekdaysParse [ i ] ) {
mom = moment ( [ 2000 , 1 ] ) . day ( i ) ;
regex = '^' + this . weekdays ( mom , '' ) + '|^' + this . weekdaysShort ( mom , '' ) + '|^' + this . weekdaysMin ( mom , '' ) ;
this . _weekdaysParse [ i ] = new RegExp ( regex . replace ( '.' , '' ) , 'i' ) ;
}
// test the regex
if ( this . _weekdaysParse [ i ] . test ( weekdayName ) ) {
return i ;
}
}
} ,
_longDateFormat : {
2014-08-20 14:41:50 -04:00
LT : 'h:mm A' ,
L : 'MM/DD/YYYY' ,
LL : 'MMMM D, YYYY' ,
LLL : 'MMMM D, YYYY LT' ,
LLLL : 'dddd, MMMM D, YYYY LT'
2013-06-06 18:49:09 -04:00
} ,
longDateFormat : function ( key ) {
var output = this . _longDateFormat [ key ] ;
if ( ! output && this . _longDateFormat [ key . toUpperCase ( ) ] ) {
output = this . _longDateFormat [ key . toUpperCase ( ) ] . replace ( /MMMM|MM|DD|dddd/g , function ( val ) {
return val . slice ( 1 ) ;
} ) ;
this . _longDateFormat [ key ] = output ;
}
return output ;
} ,
isPM : function ( input ) {
2014-08-20 14:41:50 -04:00
// IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays
// Using charAt should be more compatible.
return ( ( input + '' ) . toLowerCase ( ) . charAt ( 0 ) === 'p' ) ;
2013-06-06 18:49:09 -04:00
} ,
_meridiemParse : /[ap]\.?m?\.?/i ,
meridiem : function ( hours , minutes , isLower ) {
if ( hours > 11 ) {
return isLower ? 'pm' : 'PM' ;
} else {
return isLower ? 'am' : 'AM' ;
}
} ,
_calendar : {
sameDay : '[Today at] LT' ,
nextDay : '[Tomorrow at] LT' ,
nextWeek : 'dddd [at] LT' ,
lastDay : '[Yesterday at] LT' ,
lastWeek : '[Last] dddd [at] LT' ,
sameElse : 'L'
} ,
calendar : function ( key , mom ) {
var output = this . _calendar [ key ] ;
return typeof output === 'function' ? output . apply ( mom ) : output ;
} ,
_relativeTime : {
2014-08-20 14:41:50 -04:00
future : 'in %s' ,
past : '%s ago' ,
s : 'a few seconds' ,
m : 'a minute' ,
mm : '%d minutes' ,
h : 'an hour' ,
hh : '%d hours' ,
d : 'a day' ,
dd : '%d days' ,
M : 'a month' ,
MM : '%d months' ,
y : 'a year' ,
yy : '%d years'
2013-06-06 18:49:09 -04:00
} ,
2014-08-20 14:41:50 -04:00
2013-06-06 18:49:09 -04:00
relativeTime : function ( number , withoutSuffix , string , isFuture ) {
var output = this . _relativeTime [ string ] ;
return ( typeof output === 'function' ) ?
output ( number , withoutSuffix , string , isFuture ) :
output . replace ( /%d/i , number ) ;
} ,
2014-08-20 14:41:50 -04:00
2013-06-06 18:49:09 -04:00
pastFuture : function ( diff , output ) {
var format = this . _relativeTime [ diff > 0 ? 'future' : 'past' ] ;
return typeof format === 'function' ? format ( output ) : format . replace ( /%s/i , output ) ;
} ,
ordinal : function ( number ) {
2014-08-20 14:41:50 -04:00
return this . _ordinal . replace ( '%d' , number ) ;
2013-06-06 18:49:09 -04:00
} ,
2014-08-20 14:41:50 -04:00
_ordinal : '%d' ,
2013-06-06 18:49:09 -04:00
preparse : function ( string ) {
return string ;
} ,
postformat : function ( string ) {
return string ;
} ,
week : function ( mom ) {
return weekOfYear ( mom , this . _week . dow , this . _week . doy ) . week ;
} ,
2014-08-20 14:41:50 -04:00
2013-06-06 18:49:09 -04:00
_week : {
dow : 0 , // Sunday is the first day of the week.
doy : 6 // The week that contains Jan 1st is the first week of the year.
2014-08-20 14:41:50 -04:00
} ,
2013-06-06 18:49:09 -04:00
2014-08-20 14:41:50 -04:00
_invalidDate : 'Invalid date' ,
invalidDate : function ( ) {
return this . _invalidDate ;
2013-06-06 18:49:09 -04:00
}
2014-08-20 14:41:50 -04:00
} ) ;
2013-06-06 18:49:09 -04:00
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Formatting
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
function removeFormattingTokens ( input ) {
2014-08-20 14:41:50 -04:00
if ( input . match ( /\[[\s\S]/ ) ) {
return input . replace ( /^\[|\]$/g , '' ) ;
2013-06-06 18:49:09 -04:00
}
2014-08-20 14:41:50 -04:00
return input . replace ( /\\/g , '' ) ;
2013-06-06 18:49:09 -04:00
}
function makeFormatFunction ( format ) {
var array = format . match ( formattingTokens ) , i , length ;
for ( i = 0 , length = array . length ; i < length ; i ++ ) {
if ( formatTokenFunctions [ array [ i ] ] ) {
array [ i ] = formatTokenFunctions [ array [ i ] ] ;
} else {
array [ i ] = removeFormattingTokens ( array [ i ] ) ;
}
}
return function ( mom ) {
2014-08-20 14:41:50 -04:00
var output = '' ;
2013-06-06 18:49:09 -04:00
for ( i = 0 ; i < length ; i ++ ) {
output += array [ i ] instanceof Function ? array [ i ] . call ( mom , format ) : array [ i ] ;
}
return output ;
} ;
}
// format date using native date object
function formatMoment ( m , format ) {
2014-08-20 14:41:50 -04:00
if ( ! m . isValid ( ) ) {
return m . localeData ( ) . invalidDate ( ) ;
2013-06-06 18:49:09 -04:00
}
2014-08-20 14:41:50 -04:00
format = expandFormat ( format , m . localeData ( ) ) ;
2013-06-06 18:49:09 -04:00
if ( ! formatFunctions [ format ] ) {
formatFunctions [ format ] = makeFormatFunction ( format ) ;
}
return formatFunctions [ format ] ( m ) ;
}
2014-08-20 14:41:50 -04:00
function expandFormat ( format , locale ) {
var i = 5 ;
function replaceLongDateFormatTokens ( input ) {
return locale . longDateFormat ( input ) || input ;
}
localFormattingTokens . lastIndex = 0 ;
while ( i >= 0 && localFormattingTokens . test ( format ) ) {
format = format . replace ( localFormattingTokens , replaceLongDateFormatTokens ) ;
localFormattingTokens . lastIndex = 0 ;
i -= 1 ;
}
return format ;
}
2013-06-06 18:49:09 -04:00
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Parsing
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
// get the regex to find the next token
function getParseRegexForToken ( token , config ) {
2014-08-20 14:41:50 -04:00
var a , strict = config . _strict ;
2013-06-06 18:49:09 -04:00
switch ( token ) {
2014-08-20 14:41:50 -04:00
case 'Q' :
return parseTokenOneDigit ;
2013-06-06 18:49:09 -04:00
case 'DDDD' :
return parseTokenThreeDigits ;
case 'YYYY' :
2014-08-20 14:41:50 -04:00
case 'GGGG' :
case 'gggg' :
return strict ? parseTokenFourDigits : parseTokenOneToFourDigits ;
case 'Y' :
case 'G' :
case 'g' :
return parseTokenSignedNumber ;
case 'YYYYYY' :
2013-06-06 18:49:09 -04:00
case 'YYYYY' :
2014-08-20 14:41:50 -04:00
case 'GGGGG' :
case 'ggggg' :
return strict ? parseTokenSixDigits : parseTokenOneToSixDigits ;
2013-06-06 18:49:09 -04:00
case 'S' :
2014-08-20 14:41:50 -04:00
if ( strict ) {
return parseTokenOneDigit ;
}
/* falls through */
2013-06-06 18:49:09 -04:00
case 'SS' :
2014-08-20 14:41:50 -04:00
if ( strict ) {
return parseTokenTwoDigits ;
}
/* falls through */
2013-06-06 18:49:09 -04:00
case 'SSS' :
2014-08-20 14:41:50 -04:00
if ( strict ) {
return parseTokenThreeDigits ;
}
/* falls through */
2013-06-06 18:49:09 -04:00
case 'DDD' :
return parseTokenOneToThreeDigits ;
case 'MMM' :
case 'MMMM' :
case 'dd' :
case 'ddd' :
case 'dddd' :
return parseTokenWord ;
case 'a' :
case 'A' :
2014-08-20 14:41:50 -04:00
return config . _locale . _meridiemParse ;
2013-06-06 18:49:09 -04:00
case 'X' :
return parseTokenTimestampMs ;
case 'Z' :
case 'ZZ' :
return parseTokenTimezone ;
case 'T' :
return parseTokenT ;
2014-08-20 14:41:50 -04:00
case 'SSSS' :
return parseTokenDigits ;
2013-06-06 18:49:09 -04:00
case 'MM' :
case 'DD' :
case 'YY' :
2014-08-20 14:41:50 -04:00
case 'GG' :
case 'gg' :
2013-06-06 18:49:09 -04:00
case 'HH' :
case 'hh' :
case 'mm' :
case 'ss' :
2014-08-20 14:41:50 -04:00
case 'ww' :
case 'WW' :
return strict ? parseTokenTwoDigits : parseTokenOneOrTwoDigits ;
2013-06-06 18:49:09 -04:00
case 'M' :
case 'D' :
case 'd' :
case 'H' :
case 'h' :
case 'm' :
case 's' :
2014-08-20 14:41:50 -04:00
case 'w' :
case 'W' :
case 'e' :
case 'E' :
2013-06-06 18:49:09 -04:00
return parseTokenOneOrTwoDigits ;
2014-08-20 14:41:50 -04:00
case 'Do' :
return parseTokenOrdinal ;
2013-06-06 18:49:09 -04:00
default :
2014-08-20 14:41:50 -04:00
a = new RegExp ( regexpEscape ( unescapeFormat ( token . replace ( '\\' , '' ) ) , 'i' ) ) ;
return a ;
2013-06-06 18:49:09 -04:00
}
}
function timezoneMinutesFromString ( string ) {
2014-08-20 14:41:50 -04:00
string = string || '' ;
var possibleTzMatches = ( string . match ( parseTokenTimezone ) || [ ] ) ,
tzChunk = possibleTzMatches [ possibleTzMatches . length - 1 ] || [ ] ,
parts = ( tzChunk + '' ) . match ( parseTimezoneChunker ) || [ '-' , 0 , 0 ] ,
minutes = + ( parts [ 1 ] * 60 ) + toInt ( parts [ 2 ] ) ;
2013-06-06 18:49:09 -04:00
return parts [ 0 ] === '+' ? - minutes : minutes ;
}
// function to convert string input to date
function addTimeToArrayFromToken ( token , input , config ) {
2014-08-20 14:41:50 -04:00
var a , datePartArray = config . _a ;
2013-06-06 18:49:09 -04:00
switch ( token ) {
2014-08-20 14:41:50 -04:00
// QUARTER
case 'Q' :
if ( input != null ) {
datePartArray [ MONTH ] = ( toInt ( input ) - 1 ) * 3 ;
}
break ;
2013-06-06 18:49:09 -04:00
// MONTH
case 'M' : // fall through to MM
case 'MM' :
2014-08-20 14:41:50 -04:00
if ( input != null ) {
datePartArray [ MONTH ] = toInt ( input ) - 1 ;
}
2013-06-06 18:49:09 -04:00
break ;
case 'MMM' : // fall through to MMMM
case 'MMMM' :
2014-08-20 14:41:50 -04:00
a = config . _locale . monthsParse ( input ) ;
2013-06-06 18:49:09 -04:00
// if we didn't find a month name, mark the date as invalid.
if ( a != null ) {
2014-08-20 14:41:50 -04:00
datePartArray [ MONTH ] = a ;
2013-06-06 18:49:09 -04:00
} else {
2014-08-20 14:41:50 -04:00
config . _pf . invalidMonth = input ;
2013-06-06 18:49:09 -04:00
}
break ;
// DAY OF MONTH
2014-08-20 14:41:50 -04:00
case 'D' : // fall through to DD
case 'DD' :
if ( input != null ) {
datePartArray [ DATE ] = toInt ( input ) ;
}
break ;
case 'Do' :
if ( input != null ) {
datePartArray [ DATE ] = toInt ( parseInt ( input , 10 ) ) ;
}
break ;
// DAY OF YEAR
2013-06-06 18:49:09 -04:00
case 'DDD' : // fall through to DDDD
case 'DDDD' :
if ( input != null ) {
2014-08-20 14:41:50 -04:00
config . _dayOfYear = toInt ( input ) ;
2013-06-06 18:49:09 -04:00
}
2014-08-20 14:41:50 -04:00
2013-06-06 18:49:09 -04:00
break ;
// YEAR
case 'YY' :
2014-08-20 14:41:50 -04:00
datePartArray [ YEAR ] = moment . parseTwoDigitYear ( input ) ;
2013-06-06 18:49:09 -04:00
break ;
case 'YYYY' :
case 'YYYYY' :
2014-08-20 14:41:50 -04:00
case 'YYYYYY' :
datePartArray [ YEAR ] = toInt ( input ) ;
2013-06-06 18:49:09 -04:00
break ;
// AM / PM
case 'a' : // fall through to A
case 'A' :
2014-08-20 14:41:50 -04:00
config . _isPm = config . _locale . isPM ( input ) ;
2013-06-06 18:49:09 -04:00
break ;
// 24 HOUR
case 'H' : // fall through to hh
case 'HH' : // fall through to hh
case 'h' : // fall through to hh
case 'hh' :
2014-08-20 14:41:50 -04:00
datePartArray [ HOUR ] = toInt ( input ) ;
2013-06-06 18:49:09 -04:00
break ;
// MINUTE
case 'm' : // fall through to mm
case 'mm' :
2014-08-20 14:41:50 -04:00
datePartArray [ MINUTE ] = toInt ( input ) ;
2013-06-06 18:49:09 -04:00
break ;
// SECOND
case 's' : // fall through to ss
case 'ss' :
2014-08-20 14:41:50 -04:00
datePartArray [ SECOND ] = toInt ( input ) ;
2013-06-06 18:49:09 -04:00
break ;
// MILLISECOND
case 'S' :
case 'SS' :
case 'SSS' :
2014-08-20 14:41:50 -04:00
case 'SSSS' :
datePartArray [ MILLISECOND ] = toInt ( ( '0.' + input ) * 1000 ) ;
2013-06-06 18:49:09 -04:00
break ;
// UNIX TIMESTAMP WITH MS
case 'X' :
config . _d = new Date ( parseFloat ( input ) * 1000 ) ;
break ;
// TIMEZONE
case 'Z' : // fall through to ZZ
case 'ZZ' :
config . _useUTC = true ;
config . _tzm = timezoneMinutesFromString ( input ) ;
break ;
2014-08-20 14:41:50 -04:00
// WEEKDAY - human
case 'dd' :
case 'ddd' :
case 'dddd' :
a = config . _locale . weekdaysParse ( input ) ;
// if we didn't get a weekday name, mark the date as invalid
if ( a != null ) {
config . _w = config . _w || { } ;
config . _w [ 'd' ] = a ;
} else {
config . _pf . invalidWeekday = input ;
}
break ;
// WEEK, WEEK DAY - numeric
case 'w' :
case 'ww' :
case 'W' :
case 'WW' :
case 'd' :
case 'e' :
case 'E' :
token = token . substr ( 0 , 1 ) ;
/* falls through */
case 'gggg' :
case 'GGGG' :
case 'GGGGG' :
token = token . substr ( 0 , 2 ) ;
if ( input ) {
config . _w = config . _w || { } ;
config . _w [ token ] = toInt ( input ) ;
}
break ;
case 'gg' :
case 'GG' :
config . _w = config . _w || { } ;
config . _w [ token ] = moment . parseTwoDigitYear ( input ) ;
2013-06-06 18:49:09 -04:00
}
2014-08-20 14:41:50 -04:00
}
2013-06-06 18:49:09 -04:00
2014-08-20 14:41:50 -04:00
function dayOfYearFromWeekInfo ( config ) {
var w , weekYear , week , weekday , dow , doy , temp ;
w = config . _w ;
if ( w . GG != null || w . W != null || w . E != null ) {
dow = 1 ;
doy = 4 ;
// TODO: We need to take the current isoWeekYear, but that depends on
// how we interpret now (local, utc, fixed offset). So create
// a now version of current config (take local/utc/offset flags, and
// create now).
weekYear = dfl ( w . GG , config . _a [ YEAR ] , weekOfYear ( moment ( ) , 1 , 4 ) . year ) ;
week = dfl ( w . W , 1 ) ;
weekday = dfl ( w . E , 1 ) ;
} else {
dow = config . _locale . _week . dow ;
doy = config . _locale . _week . doy ;
weekYear = dfl ( w . gg , config . _a [ YEAR ] , weekOfYear ( moment ( ) , dow , doy ) . year ) ;
week = dfl ( w . w , 1 ) ;
if ( w . d != null ) {
// weekday -- low day numbers are considered next week
weekday = w . d ;
if ( weekday < dow ) {
++ week ;
}
} else if ( w . e != null ) {
// local weekday -- counting starts from begining of week
weekday = w . e + dow ;
} else {
// default to begining of week
weekday = dow ;
}
2013-06-06 18:49:09 -04:00
}
2014-08-20 14:41:50 -04:00
temp = dayOfYearFromWeeks ( weekYear , week , weekday , doy , dow ) ;
config . _a [ YEAR ] = temp . year ;
config . _dayOfYear = temp . dayOfYear ;
2013-06-06 18:49:09 -04:00
}
// convert an array to a date.
// the array should mirror the parameters below
// note: all values past the year are optional and will default to the lowest possible value.
// [year, month, day , hour, minute, second, millisecond]
2014-08-20 14:41:50 -04:00
function dateFromConfig ( config ) {
var i , date , input = [ ] , currentDate , yearToUse ;
2013-06-06 18:49:09 -04:00
if ( config . _d ) {
return ;
}
2014-08-20 14:41:50 -04:00
currentDate = currentDateArray ( config ) ;
//compute day of the year from weeks and weekdays
if ( config . _w && config . _a [ DATE ] == null && config . _a [ MONTH ] == null ) {
dayOfYearFromWeekInfo ( config ) ;
}
//if the day of the year is set, figure out what it is
if ( config . _dayOfYear ) {
yearToUse = dfl ( config . _a [ YEAR ] , currentDate [ YEAR ] ) ;
if ( config . _dayOfYear > daysInYear ( yearToUse ) ) {
config . _pf . _overflowDayOfYear = true ;
}
date = makeUTCDate ( yearToUse , 0 , config . _dayOfYear ) ;
config . _a [ MONTH ] = date . getUTCMonth ( ) ;
config . _a [ DATE ] = date . getUTCDate ( ) ;
}
// Default to current date.
// * if no year, month, day of month are given, default to today
// * if day of month is given, default month and year
// * if month is given, default only year
// * if year is given, don't default anything
for ( i = 0 ; i < 3 && config . _a [ i ] == null ; ++ i ) {
config . _a [ i ] = input [ i ] = currentDate [ i ] ;
}
// Zero out whatever was not defaulted, including time
for ( ; i < 7 ; i ++ ) {
2013-06-06 18:49:09 -04:00
config . _a [ i ] = input [ i ] = ( config . _a [ i ] == null ) ? ( i === 2 ? 1 : 0 ) : config . _a [ i ] ;
}
2014-08-20 14:41:50 -04:00
config . _d = ( config . _useUTC ? makeUTCDate : makeDate ) . apply ( null , input ) ;
// Apply timezone offset from input. The actual zone can be changed
// with parseZone.
if ( config . _tzm != null ) {
config . _d . setUTCMinutes ( config . _d . getUTCMinutes ( ) + config . _tzm ) ;
}
}
function dateFromObject ( config ) {
var normalizedInput ;
if ( config . _d ) {
return ;
}
2013-06-06 18:49:09 -04:00
2014-08-20 14:41:50 -04:00
normalizedInput = normalizeObjectUnits ( config . _i ) ;
config . _a = [
normalizedInput . year ,
normalizedInput . month ,
normalizedInput . day ,
normalizedInput . hour ,
normalizedInput . minute ,
normalizedInput . second ,
normalizedInput . millisecond
] ;
dateFromConfig ( config ) ;
}
2013-06-06 18:49:09 -04:00
2014-08-20 14:41:50 -04:00
function currentDateArray ( config ) {
var now = new Date ( ) ;
2013-06-06 18:49:09 -04:00
if ( config . _useUTC ) {
2014-08-20 14:41:50 -04:00
return [
now . getUTCFullYear ( ) ,
now . getUTCMonth ( ) ,
now . getUTCDate ( )
] ;
2013-06-06 18:49:09 -04:00
} else {
2014-08-20 14:41:50 -04:00
return [ now . getFullYear ( ) , now . getMonth ( ) , now . getDate ( ) ] ;
2013-06-06 18:49:09 -04:00
}
}
// date from string and format string
function makeDateFromStringAndFormat ( config ) {
2014-08-20 14:41:50 -04:00
if ( config . _f === moment . ISO _8601 ) {
parseISO ( config ) ;
return ;
}
2013-06-06 18:49:09 -04:00
config . _a = [ ] ;
2014-08-20 14:41:50 -04:00
config . _pf . empty = true ;
// This array is used to make a Date, either with `new Date` or `Date.UTC`
var string = '' + config . _i ,
i , parsedInput , tokens , token , skipped ,
stringLength = string . length ,
totalParsedInputLength = 0 ;
tokens = expandFormat ( config . _f , config . _locale ) . match ( formattingTokens ) || [ ] ;
2013-06-06 18:49:09 -04:00
for ( i = 0 ; i < tokens . length ; i ++ ) {
2014-08-20 14:41:50 -04:00
token = tokens [ i ] ;
parsedInput = ( string . match ( getParseRegexForToken ( token , config ) ) || [ ] ) [ 0 ] ;
2013-06-06 18:49:09 -04:00
if ( parsedInput ) {
2014-08-20 14:41:50 -04:00
skipped = string . substr ( 0 , string . indexOf ( parsedInput ) ) ;
if ( skipped . length > 0 ) {
config . _pf . unusedInput . push ( skipped ) ;
}
2013-06-06 18:49:09 -04:00
string = string . slice ( string . indexOf ( parsedInput ) + parsedInput . length ) ;
2014-08-20 14:41:50 -04:00
totalParsedInputLength += parsedInput . length ;
2013-06-06 18:49:09 -04:00
}
2014-08-20 14:41:50 -04:00
// don't parse if it's not a known token
if ( formatTokenFunctions [ token ] ) {
if ( parsedInput ) {
config . _pf . empty = false ;
}
else {
config . _pf . unusedTokens . push ( token ) ;
}
addTimeToArrayFromToken ( token , parsedInput , config ) ;
}
else if ( config . _strict && ! parsedInput ) {
config . _pf . unusedTokens . push ( token ) ;
2013-06-06 18:49:09 -04:00
}
}
2014-08-20 14:41:50 -04:00
// add remaining unparsed input length to the string
config . _pf . charsLeftOver = stringLength - totalParsedInputLength ;
if ( string . length > 0 ) {
config . _pf . unusedInput . push ( string ) ;
2013-06-06 18:49:09 -04:00
}
// handle am pm
2014-08-20 14:41:50 -04:00
if ( config . _isPm && config . _a [ HOUR ] < 12 ) {
config . _a [ HOUR ] += 12 ;
2013-06-06 18:49:09 -04:00
}
// if is 12 am, change hours to 0
2014-08-20 14:41:50 -04:00
if ( config . _isPm === false && config . _a [ HOUR ] === 12 ) {
config . _a [ HOUR ] = 0 ;
2013-06-06 18:49:09 -04:00
}
2014-08-20 14:41:50 -04:00
dateFromConfig ( config ) ;
checkOverflow ( config ) ;
}
function unescapeFormat ( s ) {
return s . replace ( /\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g , function ( matched , p1 , p2 , p3 , p4 ) {
return p1 || p2 || p3 || p4 ;
} ) ;
}
// Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript
function regexpEscape ( s ) {
return s . replace ( /[-\/\\^$*+?.()|[\]{}]/g , '\\$&' ) ;
2013-06-06 18:49:09 -04:00
}
// date from string and array of format strings
function makeDateFromStringAndArray ( config ) {
var tempConfig ,
bestMoment ,
2014-08-20 14:41:50 -04:00
scoreToBeat ,
2013-06-06 18:49:09 -04:00
i ,
currentScore ;
2014-08-20 14:41:50 -04:00
if ( config . _f . length === 0 ) {
config . _pf . invalidFormat = true ;
config . _d = new Date ( NaN ) ;
return ;
}
2013-06-06 18:49:09 -04:00
for ( i = 0 ; i < config . _f . length ; i ++ ) {
2014-08-20 14:41:50 -04:00
currentScore = 0 ;
tempConfig = copyConfig ( { } , config ) ;
tempConfig . _pf = defaultParsingFlags ( ) ;
2013-06-06 18:49:09 -04:00
tempConfig . _f = config . _f [ i ] ;
makeDateFromStringAndFormat ( tempConfig ) ;
2014-08-20 14:41:50 -04:00
if ( ! isValid ( tempConfig ) ) {
continue ;
2013-06-06 18:49:09 -04:00
}
2014-08-20 14:41:50 -04:00
// if there is any input that was not parsed add a penalty for that format
currentScore += tempConfig . _pf . charsLeftOver ;
//or tokens
currentScore += tempConfig . _pf . unusedTokens . length * 10 ;
tempConfig . _pf . score = currentScore ;
if ( scoreToBeat == null || currentScore < scoreToBeat ) {
2013-06-06 18:49:09 -04:00
scoreToBeat = currentScore ;
2014-08-20 14:41:50 -04:00
bestMoment = tempConfig ;
2013-06-06 18:49:09 -04:00
}
}
2014-08-20 14:41:50 -04:00
extend ( config , bestMoment || tempConfig ) ;
2013-06-06 18:49:09 -04:00
}
// date from iso format
2014-08-20 14:41:50 -04:00
function parseISO ( config ) {
var i , l ,
2013-06-06 18:49:09 -04:00
string = config . _i ,
match = isoRegex . exec ( string ) ;
if ( match ) {
2014-08-20 14:41:50 -04:00
config . _pf . iso = true ;
for ( i = 0 , l = isoDates . length ; i < l ; i ++ ) {
if ( isoDates [ i ] [ 1 ] . exec ( string ) ) {
// match[5] should be "T" or undefined
config . _f = isoDates [ i ] [ 0 ] + ( match [ 6 ] || ' ' ) ;
break ;
}
}
for ( i = 0 , l = isoTimes . length ; i < l ; i ++ ) {
2013-06-06 18:49:09 -04:00
if ( isoTimes [ i ] [ 1 ] . exec ( string ) ) {
config . _f += isoTimes [ i ] [ 0 ] ;
break ;
}
}
2014-08-20 14:41:50 -04:00
if ( string . match ( parseTokenTimezone ) ) {
config . _f += 'Z' ;
2013-06-06 18:49:09 -04:00
}
makeDateFromStringAndFormat ( config ) ;
} else {
2014-08-20 14:41:50 -04:00
config . _isValid = false ;
2013-06-06 18:49:09 -04:00
}
}
2014-08-20 14:41:50 -04:00
// date from iso format or fallback
function makeDateFromString ( config ) {
parseISO ( config ) ;
if ( config . _isValid === false ) {
delete config . _isValid ;
moment . createFromInputFallback ( config ) ;
}
}
2013-06-06 18:49:09 -04:00
2014-08-20 14:41:50 -04:00
function makeDateFromInput ( config ) {
var input = config . _i , matched ;
2013-06-06 18:49:09 -04:00
if ( input === undefined ) {
config . _d = new Date ( ) ;
2014-08-20 14:41:50 -04:00
} else if ( isDate ( input ) ) {
config . _d = new Date ( + input ) ;
} else if ( ( matched = aspNetJsonRegex . exec ( input ) ) !== null ) {
2013-06-06 18:49:09 -04:00
config . _d = new Date ( + matched [ 1 ] ) ;
} else if ( typeof input === 'string' ) {
makeDateFromString ( config ) ;
} else if ( isArray ( input ) ) {
config . _a = input . slice ( 0 ) ;
2014-08-20 14:41:50 -04:00
dateFromConfig ( config ) ;
} else if ( typeof ( input ) === 'object' ) {
dateFromObject ( config ) ;
} else if ( typeof ( input ) === 'number' ) {
// from milliseconds
config . _d = new Date ( input ) ;
2013-06-06 18:49:09 -04:00
} else {
2014-08-20 14:41:50 -04:00
moment . createFromInputFallback ( config ) ;
2013-06-06 18:49:09 -04:00
}
}
2014-08-20 14:41:50 -04:00
function makeDate ( y , m , d , h , M , s , ms ) {
//can't just apply() to create a date:
//http://stackoverflow.com/questions/181348/instantiating-a-javascript-object-by-calling-prototype-constructor-apply
var date = new Date ( y , m , d , h , M , s , ms ) ;
//the date constructor doesn't accept years < 1970
if ( y < 1970 ) {
date . setFullYear ( y ) ;
}
return date ;
}
function makeUTCDate ( y ) {
var date = new Date ( Date . UTC . apply ( null , arguments ) ) ;
if ( y < 1970 ) {
date . setUTCFullYear ( y ) ;
}
return date ;
}
function parseWeekday ( input , locale ) {
if ( typeof input === 'string' ) {
if ( ! isNaN ( input ) ) {
input = parseInt ( input , 10 ) ;
}
else {
input = locale . weekdaysParse ( input ) ;
if ( typeof input !== 'number' ) {
return null ;
}
}
}
return input ;
}
2013-06-06 18:49:09 -04:00
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Relative Time
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
// helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize
2014-08-20 14:41:50 -04:00
function substituteTimeAgo ( string , number , withoutSuffix , isFuture , locale ) {
return locale . relativeTime ( number || 1 , ! ! withoutSuffix , string , isFuture ) ;
2013-06-06 18:49:09 -04:00
}
2014-08-20 14:41:50 -04:00
function relativeTime ( posNegDuration , withoutSuffix , locale ) {
var duration = moment . duration ( posNegDuration ) . abs ( ) ,
seconds = round ( duration . as ( 's' ) ) ,
minutes = round ( duration . as ( 'm' ) ) ,
hours = round ( duration . as ( 'h' ) ) ,
days = round ( duration . as ( 'd' ) ) ,
months = round ( duration . as ( 'M' ) ) ,
years = round ( duration . as ( 'y' ) ) ,
args = seconds < relativeTimeThresholds . s && [ 's' , seconds ] ||
2013-06-06 18:49:09 -04:00
minutes === 1 && [ 'm' ] ||
2014-08-20 14:41:50 -04:00
minutes < relativeTimeThresholds . m && [ 'mm' , minutes ] ||
2013-06-06 18:49:09 -04:00
hours === 1 && [ 'h' ] ||
2014-08-20 14:41:50 -04:00
hours < relativeTimeThresholds . h && [ 'hh' , hours ] ||
2013-06-06 18:49:09 -04:00
days === 1 && [ 'd' ] ||
2014-08-20 14:41:50 -04:00
days < relativeTimeThresholds . d && [ 'dd' , days ] ||
months === 1 && [ 'M' ] ||
months < relativeTimeThresholds . M && [ 'MM' , months ] ||
2013-06-06 18:49:09 -04:00
years === 1 && [ 'y' ] || [ 'yy' , years ] ;
2014-08-20 14:41:50 -04:00
2013-06-06 18:49:09 -04:00
args [ 2 ] = withoutSuffix ;
2014-08-20 14:41:50 -04:00
args [ 3 ] = + posNegDuration > 0 ;
args [ 4 ] = locale ;
2013-06-06 18:49:09 -04:00
return substituteTimeAgo . apply ( { } , args ) ;
}
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Week of Year
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
// firstDayOfWeek 0 = sun, 6 = sat
// the day of the week that starts the week
// (usually sunday or monday)
// firstDayOfWeekOfYear 0 = sun, 6 = sat
// the first week is the week that contains the first
// of this day of the week
// (eg. ISO weeks use thursday (4))
function weekOfYear ( mom , firstDayOfWeek , firstDayOfWeekOfYear ) {
var end = firstDayOfWeekOfYear - firstDayOfWeek ,
daysToDayOfWeek = firstDayOfWeekOfYear - mom . day ( ) ,
adjustedMoment ;
if ( daysToDayOfWeek > end ) {
daysToDayOfWeek -= 7 ;
}
if ( daysToDayOfWeek < end - 7 ) {
daysToDayOfWeek += 7 ;
}
2014-08-20 14:41:50 -04:00
adjustedMoment = moment ( mom ) . add ( daysToDayOfWeek , 'd' ) ;
2013-06-06 18:49:09 -04:00
return {
week : Math . ceil ( adjustedMoment . dayOfYear ( ) / 7 ) ,
year : adjustedMoment . year ( )
} ;
}
2014-08-20 14:41:50 -04:00
//http://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday
function dayOfYearFromWeeks ( year , week , weekday , firstDayOfWeekOfYear , firstDayOfWeek ) {
var d = makeUTCDate ( year , 0 , 1 ) . getUTCDay ( ) , daysToAdd , dayOfYear ;
d = d === 0 ? 7 : d ;
weekday = weekday != null ? weekday : firstDayOfWeek ;
daysToAdd = firstDayOfWeek - d + ( d > firstDayOfWeekOfYear ? 7 : 0 ) - ( d < firstDayOfWeek ? 7 : 0 ) ;
dayOfYear = 7 * ( week - 1 ) + ( weekday - firstDayOfWeek ) + daysToAdd + 1 ;
return {
year : dayOfYear > 0 ? year : year - 1 ,
dayOfYear : dayOfYear > 0 ? dayOfYear : daysInYear ( year - 1 ) + dayOfYear
} ;
}
2013-06-06 18:49:09 -04:00
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Top Level Functions
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
function makeMoment ( config ) {
var input = config . _i ,
format = config . _f ;
2014-08-20 14:41:50 -04:00
config . _locale = config . _locale || moment . localeData ( config . _l ) ;
if ( input === null || ( format === undefined && input === '' ) ) {
return moment . invalid ( { nullInput : true } ) ;
2013-06-06 18:49:09 -04:00
}
if ( typeof input === 'string' ) {
2014-08-20 14:41:50 -04:00
config . _i = input = config . _locale . preparse ( input ) ;
2013-06-06 18:49:09 -04:00
}
if ( moment . isMoment ( input ) ) {
2014-08-20 14:41:50 -04:00
return new Moment ( input , true ) ;
2013-06-06 18:49:09 -04:00
} else if ( format ) {
if ( isArray ( format ) ) {
makeDateFromStringAndArray ( config ) ;
} else {
makeDateFromStringAndFormat ( config ) ;
}
} else {
makeDateFromInput ( config ) ;
}
return new Moment ( config ) ;
}
2014-08-20 14:41:50 -04:00
moment = function ( input , format , locale , strict ) {
var c ;
if ( typeof ( locale ) === "boolean" ) {
strict = locale ;
locale = undefined ;
}
// object construction must be done this way.
// https://github.com/moment/moment/issues/1423
c = { } ;
c . _isAMomentObject = true ;
c . _i = input ;
c . _f = format ;
c . _l = locale ;
c . _strict = strict ;
c . _isUTC = false ;
c . _pf = defaultParsingFlags ( ) ;
return makeMoment ( c ) ;
} ;
moment . suppressDeprecationWarnings = false ;
moment . createFromInputFallback = deprecate (
'moment construction falls back to js Date. This is ' +
'discouraged and will be removed in upcoming major ' +
'release. Please refer to ' +
'https://github.com/moment/moment/issues/1407 for more info.' ,
function ( config ) {
config . _d = new Date ( config . _i ) ;
}
) ;
// Pick a moment m from moments so that m[fn](other) is true for all
// other. This relies on the function fn to be transitive.
//
// moments should either be an array of moment objects or an array, whose
// first element is an array of moment objects.
function pickBy ( fn , moments ) {
var res , i ;
if ( moments . length === 1 && isArray ( moments [ 0 ] ) ) {
moments = moments [ 0 ] ;
}
if ( ! moments . length ) {
return moment ( ) ;
}
res = moments [ 0 ] ;
for ( i = 1 ; i < moments . length ; ++ i ) {
if ( moments [ i ] [ fn ] ( res ) ) {
res = moments [ i ] ;
}
}
return res ;
}
moment . min = function ( ) {
var args = [ ] . slice . call ( arguments , 0 ) ;
return pickBy ( 'isBefore' , args ) ;
} ;
moment . max = function ( ) {
var args = [ ] . slice . call ( arguments , 0 ) ;
return pickBy ( 'isAfter' , args ) ;
2013-06-06 18:49:09 -04:00
} ;
// creating with utc
2014-08-20 14:41:50 -04:00
moment . utc = function ( input , format , locale , strict ) {
var c ;
if ( typeof ( locale ) === "boolean" ) {
strict = locale ;
locale = undefined ;
}
// object construction must be done this way.
// https://github.com/moment/moment/issues/1423
c = { } ;
c . _isAMomentObject = true ;
c . _useUTC = true ;
c . _isUTC = true ;
c . _l = locale ;
c . _i = input ;
c . _f = format ;
c . _strict = strict ;
c . _pf = defaultParsingFlags ( ) ;
return makeMoment ( c ) . utc ( ) ;
2013-06-06 18:49:09 -04:00
} ;
// creating with unix timestamp (in seconds)
moment . unix = function ( input ) {
return moment ( input * 1000 ) ;
} ;
// duration
moment . duration = function ( input , key ) {
2014-08-20 14:41:50 -04:00
var duration = input ,
// matching against regexp is expensive, do it on demand
match = null ,
2013-06-06 18:49:09 -04:00
sign ,
2014-08-20 14:41:50 -04:00
ret ,
parseIso ,
diffRes ;
2013-06-06 18:49:09 -04:00
2014-08-20 14:41:50 -04:00
if ( moment . isDuration ( input ) ) {
duration = {
ms : input . _milliseconds ,
d : input . _days ,
M : input . _months
} ;
} else if ( typeof input === 'number' ) {
duration = { } ;
2013-06-06 18:49:09 -04:00
if ( key ) {
duration [ key ] = input ;
} else {
duration . milliseconds = input ;
}
2014-08-20 14:41:50 -04:00
} else if ( ! ! ( match = aspNetTimeSpanJsonRegex . exec ( input ) ) ) {
sign = ( match [ 1 ] === '-' ) ? - 1 : 1 ;
2013-06-06 18:49:09 -04:00
duration = {
y : 0 ,
2014-08-20 14:41:50 -04:00
d : toInt ( match [ DATE ] ) * sign ,
h : toInt ( match [ HOUR ] ) * sign ,
m : toInt ( match [ MINUTE ] ) * sign ,
s : toInt ( match [ SECOND ] ) * sign ,
ms : toInt ( match [ MILLISECOND ] ) * sign
2013-06-06 18:49:09 -04:00
} ;
2014-08-20 14:41:50 -04:00
} else if ( ! ! ( match = isoDurationRegex . exec ( input ) ) ) {
sign = ( match [ 1 ] === '-' ) ? - 1 : 1 ;
parseIso = function ( inp ) {
// We'd normally use ~~inp for this, but unfortunately it also
// converts floats to ints.
// inp may be undefined, so careful calling replace on it.
var res = inp && parseFloat ( inp . replace ( ',' , '.' ) ) ;
// apply sign while we're at it
return ( isNaN ( res ) ? 0 : res ) * sign ;
} ;
duration = {
y : parseIso ( match [ 2 ] ) ,
M : parseIso ( match [ 3 ] ) ,
d : parseIso ( match [ 4 ] ) ,
h : parseIso ( match [ 5 ] ) ,
m : parseIso ( match [ 6 ] ) ,
s : parseIso ( match [ 7 ] ) ,
w : parseIso ( match [ 8 ] )
} ;
} else if ( typeof duration === 'object' &&
( 'from' in duration || 'to' in duration ) ) {
diffRes = momentsDifference ( moment ( duration . from ) , moment ( duration . to ) ) ;
duration = { } ;
duration . ms = diffRes . milliseconds ;
duration . M = diffRes . months ;
2013-06-06 18:49:09 -04:00
}
ret = new Duration ( duration ) ;
2014-08-20 14:41:50 -04:00
if ( moment . isDuration ( input ) && input . hasOwnProperty ( '_locale' ) ) {
ret . _locale = input . _locale ;
2013-06-06 18:49:09 -04:00
}
return ret ;
} ;
// version number
moment . version = VERSION ;
// default format
moment . defaultFormat = isoFormat ;
2014-08-20 14:41:50 -04:00
// constant that refers to the ISO standard
moment . ISO _8601 = function ( ) { } ;
// Plugins that add properties should also add the key here (null value),
// so we can properly clone ourselves.
moment . momentProperties = momentProperties ;
2013-06-06 18:49:09 -04:00
// This function will be called whenever a moment is mutated.
// It is intended to keep the offset in sync with the timezone.
moment . updateOffset = function ( ) { } ;
2014-08-20 14:41:50 -04:00
// This function allows you to set a threshold for relative time strings
moment . relativeTimeThreshold = function ( threshold , limit ) {
if ( relativeTimeThresholds [ threshold ] === undefined ) {
return false ;
}
if ( limit === undefined ) {
return relativeTimeThresholds [ threshold ] ;
}
relativeTimeThresholds [ threshold ] = limit ;
return true ;
} ;
moment . lang = deprecate (
"moment.lang is deprecated. Use moment.locale instead." ,
function ( key , value ) {
return moment . locale ( key , value ) ;
}
) ;
// This function will load locale and then set the global locale. If
2013-06-06 18:49:09 -04:00
// no arguments are passed in, it will simply return the current global
2014-08-20 14:41:50 -04:00
// locale key.
moment . locale = function ( key , values ) {
var data ;
if ( key ) {
if ( typeof ( values ) !== "undefined" ) {
data = moment . defineLocale ( key , values ) ;
}
else {
data = moment . localeData ( key ) ;
}
2013-06-06 18:49:09 -04:00
2014-08-20 14:41:50 -04:00
if ( data ) {
moment . duration . _locale = moment . _locale = data ;
}
2013-06-06 18:49:09 -04:00
}
2014-08-20 14:41:50 -04:00
return moment . _locale . _abbr ;
} ;
moment . defineLocale = function ( name , values ) {
if ( values !== null ) {
values . abbr = name ;
if ( ! locales [ name ] ) {
locales [ name ] = new Locale ( ) ;
}
locales [ name ] . set ( values ) ;
// backwards compat for now: also set the locale
moment . locale ( name ) ;
return locales [ name ] ;
} else {
// useful for testing
delete locales [ name ] ;
return null ;
2013-06-06 18:49:09 -04:00
}
} ;
2014-08-20 14:41:50 -04:00
moment . langData = deprecate (
"moment.langData is deprecated. Use moment.localeData instead." ,
function ( key ) {
return moment . localeData ( key ) ;
}
) ;
// returns locale data
moment . localeData = function ( key ) {
var locale ;
if ( key && key . _locale && key . _locale . _abbr ) {
key = key . _locale . _abbr ;
}
if ( ! key ) {
return moment . _locale ;
}
if ( ! isArray ( key ) ) {
//short-circuit everything else
locale = loadLocale ( key ) ;
if ( locale ) {
return locale ;
}
key = [ key ] ;
2013-06-06 18:49:09 -04:00
}
2014-08-20 14:41:50 -04:00
return chooseLocale ( key ) ;
2013-06-06 18:49:09 -04:00
} ;
// compare moment object
moment . isMoment = function ( obj ) {
2014-08-20 14:41:50 -04:00
return obj instanceof Moment ||
( obj != null && obj . hasOwnProperty ( '_isAMomentObject' ) ) ;
2013-06-06 18:49:09 -04:00
} ;
// for typechecking Duration objects
moment . isDuration = function ( obj ) {
return obj instanceof Duration ;
} ;
2014-08-20 14:41:50 -04:00
for ( i = lists . length - 1 ; i >= 0 ; -- i ) {
makeList ( lists [ i ] ) ;
}
moment . normalizeUnits = function ( units ) {
return normalizeUnits ( units ) ;
} ;
moment . invalid = function ( flags ) {
var m = moment . utc ( NaN ) ;
if ( flags != null ) {
extend ( m . _pf , flags ) ;
}
else {
m . _pf . userInvalidated = true ;
}
return m ;
} ;
moment . parseZone = function ( ) {
return moment . apply ( null , arguments ) . parseZone ( ) ;
} ;
moment . parseTwoDigitYear = function ( input ) {
return toInt ( input ) + ( toInt ( input ) > 68 ? 1900 : 2000 ) ;
} ;
2013-06-06 18:49:09 -04:00
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Moment Prototype
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
2014-08-20 14:41:50 -04:00
extend ( moment . fn = Moment . prototype , {
2013-06-06 18:49:09 -04:00
clone : function ( ) {
return moment ( this ) ;
} ,
valueOf : function ( ) {
return + this . _d + ( ( this . _offset || 0 ) * 60000 ) ;
} ,
unix : function ( ) {
return Math . floor ( + this / 1 0 0 0 ) ;
} ,
toString : function ( ) {
2014-08-20 14:41:50 -04:00
return this . clone ( ) . locale ( 'en' ) . format ( "ddd MMM DD YYYY HH:mm:ss [GMT]ZZ" ) ;
2013-06-06 18:49:09 -04:00
} ,
toDate : function ( ) {
return this . _offset ? new Date ( + this ) : this . _d ;
} ,
toISOString : function ( ) {
2014-08-20 14:41:50 -04:00
var m = moment ( this ) . utc ( ) ;
if ( 0 < m . year ( ) && m . year ( ) <= 9999 ) {
return formatMoment ( m , 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]' ) ;
} else {
return formatMoment ( m , 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]' ) ;
}
2013-06-06 18:49:09 -04:00
} ,
toArray : function ( ) {
var m = this ;
return [
m . year ( ) ,
m . month ( ) ,
m . date ( ) ,
m . hours ( ) ,
m . minutes ( ) ,
m . seconds ( ) ,
m . milliseconds ( )
] ;
} ,
isValid : function ( ) {
2014-08-20 14:41:50 -04:00
return isValid ( this ) ;
} ,
isDSTShifted : function ( ) {
if ( this . _a ) {
return this . isValid ( ) && compareArrays ( this . _a , ( this . _isUTC ? moment . utc ( this . _a ) : moment ( this . _a ) ) . toArray ( ) ) > 0 ;
2013-06-06 18:49:09 -04:00
}
2014-08-20 14:41:50 -04:00
return false ;
2013-06-06 18:49:09 -04:00
} ,
2014-08-20 14:41:50 -04:00
parsingFlags : function ( ) {
return extend ( { } , this . _pf ) ;
2013-06-06 18:49:09 -04:00
} ,
2014-08-20 14:41:50 -04:00
invalidAt : function ( ) {
return this . _pf . overflow ;
2013-06-06 18:49:09 -04:00
} ,
2014-08-20 14:41:50 -04:00
utc : function ( keepLocalTime ) {
return this . zone ( 0 , keepLocalTime ) ;
2013-06-06 18:49:09 -04:00
} ,
2014-08-20 14:41:50 -04:00
local : function ( keepLocalTime ) {
if ( this . _isUTC ) {
this . zone ( 0 , keepLocalTime ) ;
this . _isUTC = false ;
if ( keepLocalTime ) {
this . add ( this . _d . getTimezoneOffset ( ) , 'm' ) ;
}
2013-06-06 18:49:09 -04:00
}
return this ;
} ,
2014-08-20 14:41:50 -04:00
format : function ( inputString ) {
var output = formatMoment ( this , inputString || moment . defaultFormat ) ;
return this . localeData ( ) . postformat ( output ) ;
2013-06-06 18:49:09 -04:00
} ,
2014-08-20 14:41:50 -04:00
add : createAdder ( 1 , 'add' ) ,
subtract : createAdder ( - 1 , 'subtract' ) ,
2013-06-06 18:49:09 -04:00
diff : function ( input , units , asFloat ) {
2014-08-20 14:41:50 -04:00
var that = makeAs ( input , this ) ,
2013-06-06 18:49:09 -04:00
zoneDiff = ( this . zone ( ) - that . zone ( ) ) * 6e4 ,
diff , output ;
units = normalizeUnits ( units ) ;
if ( units === 'year' || units === 'month' ) {
2014-08-20 14:41:50 -04:00
// average number of days in the months in the given dates
2013-06-06 18:49:09 -04:00
diff = ( this . daysInMonth ( ) + that . daysInMonth ( ) ) * 432e5 ; // 24 * 60 * 60 * 1000 / 2
2014-08-20 14:41:50 -04:00
// difference in months
2013-06-06 18:49:09 -04:00
output = ( ( this . year ( ) - that . year ( ) ) * 12 ) + ( this . month ( ) - that . month ( ) ) ;
2014-08-20 14:41:50 -04:00
// adjust by taking difference in days, average number of days
// and dst in the given months.
output += ( ( this - moment ( this ) . startOf ( 'month' ) ) -
( that - moment ( that ) . startOf ( 'month' ) ) ) / diff ;
// same as above but with zones, to negate all dst
output -= ( ( this . zone ( ) - moment ( this ) . startOf ( 'month' ) . zone ( ) ) -
( that . zone ( ) - moment ( that ) . startOf ( 'month' ) . zone ( ) ) ) * 6e4 / diff ;
2013-06-06 18:49:09 -04:00
if ( units === 'year' ) {
output = output / 12 ;
}
} else {
2014-08-20 14:41:50 -04:00
diff = ( this - that ) ;
2013-06-06 18:49:09 -04:00
output = units === 'second' ? diff / 1e3 : // 1000
units === 'minute' ? diff / 6e4 : // 1000 * 60
units === 'hour' ? diff / 36e5 : // 1000 * 60 * 60
2014-08-20 14:41:50 -04:00
units === 'day' ? ( diff - zoneDiff ) / 864e5 : // 1000 * 60 * 60 * 24, negate dst
units === 'week' ? ( diff - zoneDiff ) / 6048e5 : // 1000 * 60 * 60 * 24 * 7, negate dst
2013-06-06 18:49:09 -04:00
diff ;
}
return asFloat ? output : absRound ( output ) ;
} ,
from : function ( time , withoutSuffix ) {
2014-08-20 14:41:50 -04:00
return moment . duration ( { to : this , from : time } ) . locale ( this . locale ( ) ) . humanize ( ! withoutSuffix ) ;
2013-06-06 18:49:09 -04:00
} ,
fromNow : function ( withoutSuffix ) {
return this . from ( moment ( ) , withoutSuffix ) ;
} ,
2014-08-20 14:41:50 -04:00
calendar : function ( time ) {
// We want to compare the start of today, vs this.
// Getting start-of-today depends on whether we're zone'd or not.
var now = time || moment ( ) ,
sod = makeAs ( now , this ) . startOf ( 'day' ) ,
diff = this . diff ( sod , 'days' , true ) ,
2013-06-06 18:49:09 -04:00
format = diff < - 6 ? 'sameElse' :
2014-08-20 14:41:50 -04:00
diff < - 1 ? 'lastWeek' :
diff < 0 ? 'lastDay' :
diff < 1 ? 'sameDay' :
diff < 2 ? 'nextDay' :
diff < 7 ? 'nextWeek' : 'sameElse' ;
return this . format ( this . localeData ( ) . calendar ( format , this ) ) ;
2013-06-06 18:49:09 -04:00
} ,
isLeapYear : function ( ) {
2014-08-20 14:41:50 -04:00
return isLeapYear ( this . year ( ) ) ;
2013-06-06 18:49:09 -04:00
} ,
isDST : function ( ) {
return ( this . zone ( ) < this . clone ( ) . month ( 0 ) . zone ( ) ||
this . zone ( ) < this . clone ( ) . month ( 5 ) . zone ( ) ) ;
} ,
day : function ( input ) {
var day = this . _isUTC ? this . _d . getUTCDay ( ) : this . _d . getDay ( ) ;
if ( input != null ) {
2014-08-20 14:41:50 -04:00
input = parseWeekday ( input , this . localeData ( ) ) ;
return this . add ( input - day , 'd' ) ;
2013-06-06 18:49:09 -04:00
} else {
return day ;
}
} ,
2014-08-20 14:41:50 -04:00
month : makeAccessor ( 'Month' , true ) ,
2013-06-06 18:49:09 -04:00
2014-08-20 14:41:50 -04:00
startOf : function ( units ) {
2013-06-06 18:49:09 -04:00
units = normalizeUnits ( units ) ;
// the following switch intentionally omits break keywords
// to utilize falling through the cases.
switch ( units ) {
case 'year' :
this . month ( 0 ) ;
/* falls through */
2014-08-20 14:41:50 -04:00
case 'quarter' :
2013-06-06 18:49:09 -04:00
case 'month' :
this . date ( 1 ) ;
/* falls through */
case 'week' :
2014-08-20 14:41:50 -04:00
case 'isoWeek' :
2013-06-06 18:49:09 -04:00
case 'day' :
this . hours ( 0 ) ;
/* falls through */
case 'hour' :
this . minutes ( 0 ) ;
/* falls through */
case 'minute' :
this . seconds ( 0 ) ;
/* falls through */
case 'second' :
this . milliseconds ( 0 ) ;
/* falls through */
}
// weeks are a special case
if ( units === 'week' ) {
this . weekday ( 0 ) ;
2014-08-20 14:41:50 -04:00
} else if ( units === 'isoWeek' ) {
this . isoWeekday ( 1 ) ;
}
// quarters are also special
if ( units === 'quarter' ) {
this . month ( Math . floor ( this . month ( ) / 3 ) * 3 ) ;
2013-06-06 18:49:09 -04:00
}
return this ;
} ,
endOf : function ( units ) {
2014-08-20 14:41:50 -04:00
units = normalizeUnits ( units ) ;
return this . startOf ( units ) . add ( 1 , ( units === 'isoWeek' ? 'week' : units ) ) . subtract ( 1 , 'ms' ) ;
2013-06-06 18:49:09 -04:00
} ,
isAfter : function ( input , units ) {
units = typeof units !== 'undefined' ? units : 'millisecond' ;
return + this . clone ( ) . startOf ( units ) > + moment ( input ) . startOf ( units ) ;
} ,
isBefore : function ( input , units ) {
units = typeof units !== 'undefined' ? units : 'millisecond' ;
return + this . clone ( ) . startOf ( units ) < + moment ( input ) . startOf ( units ) ;
} ,
isSame : function ( input , units ) {
2014-08-20 14:41:50 -04:00
units = units || 'ms' ;
return + this . clone ( ) . startOf ( units ) === + makeAs ( input , this ) . startOf ( units ) ;
} ,
min : deprecate (
'moment().min is deprecated, use moment.min instead. https://github.com/moment/moment/issues/1548' ,
function ( other ) {
other = moment . apply ( null , arguments ) ;
return other < this ? this : other ;
}
) ,
max : deprecate (
'moment().max is deprecated, use moment.max instead. https://github.com/moment/moment/issues/1548' ,
function ( other ) {
other = moment . apply ( null , arguments ) ;
return other > this ? this : other ;
}
) ,
// keepLocalTime = true means only change the timezone, without
// affecting the local hour. So 5:31:26 +0300 --[zone(2, true)]-->
// 5:31:26 +0200 It is possible that 5:31:26 doesn't exist int zone
// +0200, so we adjust the time as needed, to be valid.
//
// Keeping the time actually adds/subtracts (one hour)
// from the actual represented time. That is why we call updateOffset
// a second time. In case it wants us to change the offset again
// _changeInProgress == true case, then we have to adjust, because
// there is no such time in the given timezone.
zone : function ( input , keepLocalTime ) {
var offset = this . _offset || 0 ,
localAdjust ;
2013-06-06 18:49:09 -04:00
if ( input != null ) {
2014-08-20 14:41:50 -04:00
if ( typeof input === 'string' ) {
2013-06-06 18:49:09 -04:00
input = timezoneMinutesFromString ( input ) ;
}
if ( Math . abs ( input ) < 16 ) {
input = input * 60 ;
}
2014-08-20 14:41:50 -04:00
if ( ! this . _isUTC && keepLocalTime ) {
localAdjust = this . _d . getTimezoneOffset ( ) ;
}
2013-06-06 18:49:09 -04:00
this . _offset = input ;
this . _isUTC = true ;
2014-08-20 14:41:50 -04:00
if ( localAdjust != null ) {
this . subtract ( localAdjust , 'm' ) ;
}
2013-06-06 18:49:09 -04:00
if ( offset !== input ) {
2014-08-20 14:41:50 -04:00
if ( ! keepLocalTime || this . _changeInProgress ) {
addOrSubtractDurationFromMoment ( this ,
moment . duration ( offset - input , 'm' ) , 1 , false ) ;
} else if ( ! this . _changeInProgress ) {
this . _changeInProgress = true ;
moment . updateOffset ( this , true ) ;
this . _changeInProgress = null ;
}
2013-06-06 18:49:09 -04:00
}
} else {
return this . _isUTC ? offset : this . _d . getTimezoneOffset ( ) ;
}
return this ;
} ,
zoneAbbr : function ( ) {
2014-08-20 14:41:50 -04:00
return this . _isUTC ? 'UTC' : '' ;
2013-06-06 18:49:09 -04:00
} ,
zoneName : function ( ) {
2014-08-20 14:41:50 -04:00
return this . _isUTC ? 'Coordinated Universal Time' : '' ;
} ,
parseZone : function ( ) {
if ( this . _tzm ) {
this . zone ( this . _tzm ) ;
} else if ( typeof this . _i === 'string' ) {
this . zone ( this . _i ) ;
}
return this ;
} ,
hasAlignedHourOffset : function ( input ) {
if ( ! input ) {
input = 0 ;
}
else {
input = moment ( input ) . zone ( ) ;
}
return ( this . zone ( ) - input ) % 60 === 0 ;
2013-06-06 18:49:09 -04:00
} ,
daysInMonth : function ( ) {
2014-08-20 14:41:50 -04:00
return daysInMonth ( this . year ( ) , this . month ( ) ) ;
2013-06-06 18:49:09 -04:00
} ,
dayOfYear : function ( input ) {
var dayOfYear = round ( ( moment ( this ) . startOf ( 'day' ) - moment ( this ) . startOf ( 'year' ) ) / 864e5 ) + 1 ;
2014-08-20 14:41:50 -04:00
return input == null ? dayOfYear : this . add ( ( input - dayOfYear ) , 'd' ) ;
} ,
quarter : function ( input ) {
return input == null ? Math . ceil ( ( this . month ( ) + 1 ) / 3 ) : this . month ( ( input - 1 ) * 3 + this . month ( ) % 3 ) ;
2013-06-06 18:49:09 -04:00
} ,
weekYear : function ( input ) {
2014-08-20 14:41:50 -04:00
var year = weekOfYear ( this , this . localeData ( ) . _week . dow , this . localeData ( ) . _week . doy ) . year ;
return input == null ? year : this . add ( ( input - year ) , 'y' ) ;
2013-06-06 18:49:09 -04:00
} ,
isoWeekYear : function ( input ) {
var year = weekOfYear ( this , 1 , 4 ) . year ;
2014-08-20 14:41:50 -04:00
return input == null ? year : this . add ( ( input - year ) , 'y' ) ;
2013-06-06 18:49:09 -04:00
} ,
week : function ( input ) {
2014-08-20 14:41:50 -04:00
var week = this . localeData ( ) . week ( this ) ;
return input == null ? week : this . add ( ( input - week ) * 7 , 'd' ) ;
2013-06-06 18:49:09 -04:00
} ,
isoWeek : function ( input ) {
var week = weekOfYear ( this , 1 , 4 ) . week ;
2014-08-20 14:41:50 -04:00
return input == null ? week : this . add ( ( input - week ) * 7 , 'd' ) ;
2013-06-06 18:49:09 -04:00
} ,
weekday : function ( input ) {
2014-08-20 14:41:50 -04:00
var weekday = ( this . day ( ) + 7 - this . localeData ( ) . _week . dow ) % 7 ;
return input == null ? weekday : this . add ( input - weekday , 'd' ) ;
2013-06-06 18:49:09 -04:00
} ,
isoWeekday : function ( input ) {
2014-08-20 14:41:50 -04:00
// behaves the same as moment#day except
// as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)
// as a setter, sunday should belong to the previous week.
return input == null ? this . day ( ) || 7 : this . day ( this . day ( ) % 7 ? input : input - 7 ) ;
} ,
isoWeeksInYear : function ( ) {
return weeksInYear ( this . year ( ) , 1 , 4 ) ;
} ,
weeksInYear : function ( ) {
var weekInfo = this . localeData ( ) . _week ;
return weeksInYear ( this . year ( ) , weekInfo . dow , weekInfo . doy ) ;
} ,
get : function ( units ) {
units = normalizeUnits ( units ) ;
return this [ units ] ( ) ;
} ,
set : function ( units , value ) {
units = normalizeUnits ( units ) ;
if ( typeof this [ units ] === 'function' ) {
this [ units ] ( value ) ;
}
return this ;
2013-06-06 18:49:09 -04:00
} ,
2014-08-20 14:41:50 -04:00
// If passed a locale key, it will set the locale for this
// instance. Otherwise, it will return the locale configuration
2013-06-06 18:49:09 -04:00
// variables for this instance.
2014-08-20 14:41:50 -04:00
locale : function ( key ) {
2013-06-06 18:49:09 -04:00
if ( key === undefined ) {
2014-08-20 14:41:50 -04:00
return this . _locale . _abbr ;
2013-06-06 18:49:09 -04:00
} else {
2014-08-20 14:41:50 -04:00
this . _locale = moment . localeData ( key ) ;
2013-06-06 18:49:09 -04:00
return this ;
}
2014-08-20 14:41:50 -04:00
} ,
lang : deprecate (
"moment().lang() is deprecated. Use moment().localeData() instead." ,
function ( key ) {
if ( key === undefined ) {
return this . localeData ( ) ;
} else {
this . _locale = moment . localeData ( key ) ;
return this ;
}
}
) ,
localeData : function ( ) {
return this . _locale ;
2013-06-06 18:49:09 -04:00
}
2014-08-20 14:41:50 -04:00
} ) ;
2013-06-06 18:49:09 -04:00
2014-08-20 14:41:50 -04:00
function rawMonthSetter ( mom , value ) {
var dayOfMonth ;
// TODO: Move this out of here!
if ( typeof value === 'string' ) {
value = mom . localeData ( ) . monthsParse ( value ) ;
// TODO: Another silent failure?
if ( typeof value !== 'number' ) {
return mom ;
}
}
dayOfMonth = Math . min ( mom . date ( ) ,
daysInMonth ( mom . year ( ) , value ) ) ;
mom . _d [ 'set' + ( mom . _isUTC ? 'UTC' : '' ) + 'Month' ] ( value , dayOfMonth ) ;
return mom ;
}
function rawGetter ( mom , unit ) {
return mom . _d [ 'get' + ( mom . _isUTC ? 'UTC' : '' ) + unit ] ( ) ;
}
function rawSetter ( mom , unit , value ) {
if ( unit === 'Month' ) {
return rawMonthSetter ( mom , value ) ;
} else {
return mom . _d [ 'set' + ( mom . _isUTC ? 'UTC' : '' ) + unit ] ( value ) ;
}
}
function makeAccessor ( unit , keepTime ) {
return function ( value ) {
if ( value != null ) {
rawSetter ( this , unit , value ) ;
moment . updateOffset ( this , keepTime ) ;
2013-06-06 18:49:09 -04:00
return this ;
} else {
2014-08-20 14:41:50 -04:00
return rawGetter ( this , unit ) ;
2013-06-06 18:49:09 -04:00
}
} ;
}
2014-08-20 14:41:50 -04:00
moment . fn . millisecond = moment . fn . milliseconds = makeAccessor ( 'Milliseconds' , false ) ;
moment . fn . second = moment . fn . seconds = makeAccessor ( 'Seconds' , false ) ;
moment . fn . minute = moment . fn . minutes = makeAccessor ( 'Minutes' , false ) ;
// Setting the hour should keep the time, because the user explicitly
// specified which hour he wants. So trying to maintain the same hour (in
// a new timezone) makes sense. Adding/subtracting hours does not follow
// this rule.
moment . fn . hour = moment . fn . hours = makeAccessor ( 'Hours' , true ) ;
// moment.fn.month is defined separately
moment . fn . date = makeAccessor ( 'Date' , true ) ;
moment . fn . dates = deprecate ( 'dates accessor is deprecated. Use date instead.' , makeAccessor ( 'Date' , true ) ) ;
moment . fn . year = makeAccessor ( 'FullYear' , true ) ;
moment . fn . years = deprecate ( 'years accessor is deprecated. Use year instead.' , makeAccessor ( 'FullYear' , true ) ) ;
2013-06-06 18:49:09 -04:00
// add plural methods
moment . fn . days = moment . fn . day ;
moment . fn . months = moment . fn . month ;
moment . fn . weeks = moment . fn . week ;
moment . fn . isoWeeks = moment . fn . isoWeek ;
2014-08-20 14:41:50 -04:00
moment . fn . quarters = moment . fn . quarter ;
2013-06-06 18:49:09 -04:00
// add aliased format methods
moment . fn . toJSON = moment . fn . toISOString ;
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Duration Prototype
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
2014-08-20 14:41:50 -04:00
function daysToYears ( days ) {
// 400 years have 146097 days (taking into account leap year rules)
return days * 400 / 146097 ;
}
function yearsToDays ( years ) {
// years * 365 + absRound(years / 4) -
// absRound(years / 100) + absRound(years / 400);
return years * 146097 / 400 ;
}
extend ( moment . duration . fn = Duration . prototype , {
_bubble : function ( ) {
var milliseconds = this . _milliseconds ,
days = this . _days ,
months = this . _months ,
data = this . _data ,
seconds , minutes , hours , years = 0 ;
// The following code bubbles up values, see the tests for
// examples of what that means.
data . milliseconds = milliseconds % 1000 ;
seconds = absRound ( milliseconds / 1000 ) ;
data . seconds = seconds % 60 ;
minutes = absRound ( seconds / 60 ) ;
data . minutes = minutes % 60 ;
hours = absRound ( minutes / 60 ) ;
data . hours = hours % 24 ;
days += absRound ( hours / 24 ) ;
// Accurately convert days to years, assume start from year 0.
years = absRound ( daysToYears ( days ) ) ;
days -= absRound ( yearsToDays ( years ) ) ;
// 30 days to a month
// TODO (iskren): Use anchor date (like 1st Jan) to compute this.
months += absRound ( days / 30 ) ;
days %= 30 ;
// 12 months -> 1 year
years += absRound ( months / 12 ) ;
months %= 12 ;
data . days = days ;
data . months = months ;
data . years = years ;
} ,
abs : function ( ) {
this . _milliseconds = Math . abs ( this . _milliseconds ) ;
this . _days = Math . abs ( this . _days ) ;
this . _months = Math . abs ( this . _months ) ;
this . _data . milliseconds = Math . abs ( this . _data . milliseconds ) ;
this . _data . seconds = Math . abs ( this . _data . seconds ) ;
this . _data . minutes = Math . abs ( this . _data . minutes ) ;
this . _data . hours = Math . abs ( this . _data . hours ) ;
this . _data . months = Math . abs ( this . _data . months ) ;
this . _data . years = Math . abs ( this . _data . years ) ;
return this ;
} ,
2013-06-06 18:49:09 -04:00
weeks : function ( ) {
return absRound ( this . days ( ) / 7 ) ;
} ,
valueOf : function ( ) {
return this . _milliseconds +
this . _days * 864e5 +
( this . _months % 12 ) * 2592e6 +
2014-08-20 14:41:50 -04:00
toInt ( this . _months / 12 ) * 31536e6 ;
2013-06-06 18:49:09 -04:00
} ,
humanize : function ( withSuffix ) {
2014-08-20 14:41:50 -04:00
var output = relativeTime ( this , ! withSuffix , this . localeData ( ) ) ;
2013-06-06 18:49:09 -04:00
if ( withSuffix ) {
2014-08-20 14:41:50 -04:00
output = this . localeData ( ) . pastFuture ( + this , output ) ;
2013-06-06 18:49:09 -04:00
}
2014-08-20 14:41:50 -04:00
return this . localeData ( ) . postformat ( output ) ;
2013-06-06 18:49:09 -04:00
} ,
add : function ( input , val ) {
// supports only 2.0-style add(1, 's') or add(moment)
var dur = moment . duration ( input , val ) ;
this . _milliseconds += dur . _milliseconds ;
this . _days += dur . _days ;
this . _months += dur . _months ;
2014-08-20 14:41:50 -04:00
this . _bubble ( ) ;
2013-06-06 18:49:09 -04:00
return this ;
} ,
subtract : function ( input , val ) {
var dur = moment . duration ( input , val ) ;
this . _milliseconds -= dur . _milliseconds ;
this . _days -= dur . _days ;
this . _months -= dur . _months ;
2014-08-20 14:41:50 -04:00
this . _bubble ( ) ;
2013-06-06 18:49:09 -04:00
return this ;
} ,
get : function ( units ) {
units = normalizeUnits ( units ) ;
return this [ units . toLowerCase ( ) + 's' ] ( ) ;
} ,
as : function ( units ) {
2014-08-20 14:41:50 -04:00
var days , months ;
2013-06-06 18:49:09 -04:00
units = normalizeUnits ( units ) ;
2014-08-20 14:41:50 -04:00
days = this . _days + this . _milliseconds / 864e5 ;
if ( units === 'month' || units === 'year' ) {
months = this . _months + daysToYears ( days ) * 12 ;
return units === 'month' ? months : months / 12 ;
} else {
days += yearsToDays ( this . _months / 12 ) ;
switch ( units ) {
case 'week' : return days / 7 ;
case 'day' : return days ;
case 'hour' : return days * 24 ;
case 'minute' : return days * 24 * 60 ;
case 'second' : return days * 24 * 60 * 60 ;
case 'millisecond' : return days * 24 * 60 * 60 * 1000 ;
default : throw new Error ( 'Unknown unit ' + units ) ;
}
}
2013-06-06 18:49:09 -04:00
} ,
2014-08-20 14:41:50 -04:00
lang : moment . fn . lang ,
locale : moment . fn . locale ,
toIsoString : deprecate (
"toIsoString() is deprecated. Please use toISOString() instead " +
"(notice the capitals)" ,
function ( ) {
return this . toISOString ( ) ;
}
) ,
toISOString : function ( ) {
// inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js
var years = Math . abs ( this . years ( ) ) ,
months = Math . abs ( this . months ( ) ) ,
days = Math . abs ( this . days ( ) ) ,
hours = Math . abs ( this . hours ( ) ) ,
minutes = Math . abs ( this . minutes ( ) ) ,
seconds = Math . abs ( this . seconds ( ) + this . milliseconds ( ) / 1000 ) ;
if ( ! this . asSeconds ( ) ) {
// this is the same as C#'s (Noda) and python (isodate)...
// but not other JS (goog.date)
return 'P0D' ;
}
return ( this . asSeconds ( ) < 0 ? '-' : '' ) +
'P' +
( years ? years + 'Y' : '' ) +
( months ? months + 'M' : '' ) +
( days ? days + 'D' : '' ) +
( ( hours || minutes || seconds ) ? 'T' : '' ) +
( hours ? hours + 'H' : '' ) +
( minutes ? minutes + 'M' : '' ) +
( seconds ? seconds + 'S' : '' ) ;
} ,
localeData : function ( ) {
return this . _locale ;
}
} ) ;
2013-06-06 18:49:09 -04:00
function makeDurationGetter ( name ) {
moment . duration . fn [ name ] = function ( ) {
return this . _data [ name ] ;
} ;
}
for ( i in unitMillisecondFactors ) {
if ( unitMillisecondFactors . hasOwnProperty ( i ) ) {
makeDurationGetter ( i . toLowerCase ( ) ) ;
}
}
2014-08-20 14:41:50 -04:00
moment . duration . fn . asMilliseconds = function ( ) {
return this . as ( 'ms' ) ;
} ;
moment . duration . fn . asSeconds = function ( ) {
return this . as ( 's' ) ;
} ;
moment . duration . fn . asMinutes = function ( ) {
return this . as ( 'm' ) ;
} ;
moment . duration . fn . asHours = function ( ) {
return this . as ( 'h' ) ;
} ;
moment . duration . fn . asDays = function ( ) {
return this . as ( 'd' ) ;
} ;
moment . duration . fn . asWeeks = function ( ) {
return this . as ( 'weeks' ) ;
} ;
2013-06-06 18:49:09 -04:00
moment . duration . fn . asMonths = function ( ) {
2014-08-20 14:41:50 -04:00
return this . as ( 'M' ) ;
} ;
moment . duration . fn . asYears = function ( ) {
return this . as ( 'y' ) ;
2013-06-06 18:49:09 -04:00
} ;
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2014-08-20 14:41:50 -04:00
Default Locale
2013-06-06 18:49:09 -04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
2014-08-20 14:41:50 -04:00
// Set default locale, other locale will inherit from English.
moment . locale ( 'en' , {
2013-06-06 18:49:09 -04:00
ordinal : function ( number ) {
var b = number % 10 ,
2014-08-20 14:41:50 -04:00
output = ( toInt ( number % 100 / 10 ) === 1 ) ? 'th' :
2013-06-06 18:49:09 -04:00
( b === 1 ) ? 'st' :
( b === 2 ) ? 'nd' :
( b === 3 ) ? 'rd' : 'th' ;
return number + output ;
}
} ) ;
2014-08-20 14:41:50 -04:00
/* EMBED_LOCALES */
2013-06-06 18:49:09 -04:00
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Exposing Moment
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
2014-08-20 14:41:50 -04:00
function makeGlobal ( shouldDeprecate ) {
/*global ender:false */
if ( typeof ender !== 'undefined' ) {
return ;
}
oldGlobalMoment = globalScope . moment ;
if ( shouldDeprecate ) {
globalScope . moment = deprecate (
'Accessing Moment through the global scope is ' +
'deprecated, and will be removed in an upcoming ' +
'release.' ,
moment ) ;
} else {
globalScope . moment = moment ;
}
}
2013-06-06 18:49:09 -04:00
// CommonJS module is defined
if ( hasModule ) {
module . exports = moment ;
2014-08-20 14:41:50 -04:00
} else if ( typeof define === 'function' && define . amd ) {
define ( 'moment' , function ( require , exports , module ) {
if ( module . config && module . config ( ) && module . config ( ) . noGlobal === true ) {
// release the global variable
globalScope . moment = oldGlobalMoment ;
}
2013-06-06 18:49:09 -04:00
return moment ;
} ) ;
2014-08-20 14:41:50 -04:00
makeGlobal ( true ) ;
} else {
makeGlobal ( ) ;
2013-06-06 18:49:09 -04:00
}
} ) . call ( this ) ;