2014-07-25 03:00:29 -04:00
//! moment.js
//! version : 2.2.1
//! authors : Tim Wood, Iskren Chernev, Moment.js contributors
//! license : MIT
//! momentjs.com
2013-05-06 03:38:29 -04:00
( function ( undefined ) {
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Constants
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
var moment ,
2014-07-25 03:00:29 -04:00
VERSION = "2.2.1" ,
2013-05-06 03:38:29 -04:00
round = Math . round , i ,
// internal storage for language config files
languages = { } ,
// check for nodeJS
hasModule = ( typeof module !== 'undefined' && module . exports ) ,
// ASP.NET json date format regex
aspNetJsonRegex = /^\/?Date\((\-?\d+)/i ,
2014-07-25 03:00:29 -04:00
aspNetTimeSpanJsonRegex = /(\-)?(?:(\d*)\.)?(\d+)\:(\d+)\:(\d+)\.?(\d{3})?/ ,
2013-05-06 03:38:29 -04:00
// format tokens
2014-07-25 03:00:29 -04:00
formattingTokens = /(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|SS?S?|X|zz?|ZZ?|.)/g ,
2013-05-06 03:38:29 -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
parseTokenThreeDigits = /\d{3}/ , // 000 - 999
parseTokenFourDigits = /\d{1,4}/ , // 0 - 9999
parseTokenSixDigits = /[+\-]?\d{1,6}/ , // -999,999 - 999,999
2014-07-25 03:00:29 -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.
2013-05-06 03:38:29 -04:00
parseTokenTimezone = /Z|[\+\-]\d\d:?\d\d/i , // +00:00 -00:00 +0000 -0000 or Z
parseTokenT = /T/i , // T (ISO seperator)
parseTokenTimestampMs = /[\+\-]?\d+(\.\d{1,3})?/ , // 123456789 123456789.123
// preliminary iso regex
// 0000-00-00 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000
isoRegex = /^\s*\d{4}-\d\d-\d\d((T| )(\d\d(:\d\d(:\d\d(\.\d\d?\d?)?)?)?)?([\+\-]\d\d:?\d\d)?)?/ ,
isoFormat = 'YYYY-MM-DDTHH:mm:ssZ' ,
// iso time formats and regexes
isoTimes = [
[ 'HH:mm:ss.S' , /(T| )\d\d:\d\d:\d\d\.\d{1,3}/ ] ,
[ '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
2014-07-25 03:00:29 -04:00
proxyGettersAndSetters = 'Date|Hours|Minutes|Seconds|Milliseconds' . split ( '|' ) ,
2013-05-06 03:38:29 -04:00
unitMillisecondFactors = {
'Milliseconds' : 1 ,
'Seconds' : 1e3 ,
'Minutes' : 6e4 ,
'Hours' : 36e5 ,
'Days' : 864e5 ,
'Months' : 2592e6 ,
'Years' : 31536e6
} ,
2014-07-25 03:00:29 -04:00
unitAliases = {
ms : 'millisecond' ,
s : 'second' ,
m : 'minute' ,
h : 'hour' ,
d : 'day' ,
w : 'week' ,
W : 'isoweek' ,
M : 'month' ,
y : 'year'
} ,
2013-05-06 03:38:29 -04:00
// format function strings
formatFunctions = { } ,
// 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 ) {
return this . lang ( ) . monthsShort ( this , format ) ;
} ,
MMMM : function ( format ) {
return this . lang ( ) . months ( this , format ) ;
} ,
D : function ( ) {
return this . date ( ) ;
} ,
DDD : function ( ) {
return this . dayOfYear ( ) ;
} ,
d : function ( ) {
return this . day ( ) ;
} ,
dd : function ( format ) {
return this . lang ( ) . weekdaysMin ( this , format ) ;
} ,
ddd : function ( format ) {
return this . lang ( ) . weekdaysShort ( this , format ) ;
} ,
dddd : function ( format ) {
return this . lang ( ) . weekdays ( this , format ) ;
} ,
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-07-25 03:00:29 -04:00
gg : function ( ) {
return leftZeroFill ( this . weekYear ( ) % 100 , 2 ) ;
} ,
gggg : function ( ) {
return this . weekYear ( ) ;
} ,
ggggg : function ( ) {
return leftZeroFill ( this . weekYear ( ) , 5 ) ;
} ,
GG : function ( ) {
return leftZeroFill ( this . isoWeekYear ( ) % 100 , 2 ) ;
} ,
GGGG : function ( ) {
return this . isoWeekYear ( ) ;
} ,
GGGGG : function ( ) {
return leftZeroFill ( this . isoWeekYear ( ) , 5 ) ;
} ,
e : function ( ) {
return this . weekday ( ) ;
} ,
E : function ( ) {
return this . isoWeekday ( ) ;
} ,
2013-05-06 03:38:29 -04:00
a : function ( ) {
return this . lang ( ) . meridiem ( this . hours ( ) , this . minutes ( ) , true ) ;
} ,
A : function ( ) {
return this . lang ( ) . meridiem ( this . hours ( ) , this . minutes ( ) , false ) ;
} ,
H : function ( ) {
return this . hours ( ) ;
} ,
h : function ( ) {
return this . hours ( ) % 12 || 12 ;
} ,
m : function ( ) {
return this . minutes ( ) ;
} ,
s : function ( ) {
return this . seconds ( ) ;
} ,
S : function ( ) {
return ~ ~ ( this . milliseconds ( ) / 100 ) ;
} ,
SS : function ( ) {
return leftZeroFill ( ~ ~ ( this . milliseconds ( ) / 10 ) , 2 ) ;
} ,
SSS : function ( ) {
return leftZeroFill ( this . milliseconds ( ) , 3 ) ;
} ,
Z : function ( ) {
var a = - this . zone ( ) ,
b = "+" ;
if ( a < 0 ) {
a = - a ;
b = "-" ;
}
return b + leftZeroFill ( ~ ~ ( a / 60 ) , 2 ) + ":" + leftZeroFill ( ~ ~ a % 60 , 2 ) ;
} ,
ZZ : function ( ) {
var a = - this . zone ( ) ,
b = "+" ;
if ( a < 0 ) {
a = - a ;
b = "-" ;
}
return b + leftZeroFill ( ~ ~ ( 10 * a / 6 ) , 4 ) ;
} ,
2014-07-25 03:00:29 -04:00
z : function ( ) {
return this . zoneAbbr ( ) ;
} ,
zz : function ( ) {
return this . zoneName ( ) ;
} ,
2013-05-06 03:38:29 -04:00
X : function ( ) {
return this . unix ( ) ;
}
} ;
function padToken ( func , count ) {
return function ( a ) {
return leftZeroFill ( func . call ( this , a ) , count ) ;
} ;
}
2014-07-25 03:00:29 -04:00
function ordinalizeToken ( func , period ) {
2013-05-06 03:38:29 -04:00
return function ( a ) {
2014-07-25 03:00:29 -04:00
return this . lang ( ) . ordinal ( func . call ( this , a ) , period ) ;
2013-05-06 03:38:29 -04:00
} ;
}
while ( ordinalizeTokens . length ) {
i = ordinalizeTokens . pop ( ) ;
2014-07-25 03:00:29 -04:00
formatTokenFunctions [ i + 'o' ] = ordinalizeToken ( formatTokenFunctions [ i ] , i ) ;
2013-05-06 03:38:29 -04:00
}
while ( paddedTokens . length ) {
i = paddedTokens . pop ( ) ;
formatTokenFunctions [ i + i ] = padToken ( formatTokenFunctions [ i ] , 2 ) ;
}
formatTokenFunctions . DDDD = padToken ( formatTokenFunctions . DDD , 3 ) ;
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Constructors
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
function Language ( ) {
}
// Moment prototype object
function Moment ( config ) {
extend ( this , config ) ;
}
// Duration Constructor
function Duration ( duration ) {
2014-07-25 03:00:29 -04:00
var years = duration . years || duration . year || duration . y || 0 ,
2013-05-06 03:38:29 -04:00
months = duration . months || duration . month || duration . M || 0 ,
weeks = duration . weeks || duration . week || duration . w || 0 ,
days = duration . days || duration . day || duration . d || 0 ,
hours = duration . hours || duration . hour || duration . h || 0 ,
minutes = duration . minutes || duration . minute || duration . m || 0 ,
seconds = duration . seconds || duration . second || duration . s || 0 ,
milliseconds = duration . milliseconds || duration . millisecond || duration . ms || 0 ;
2014-07-25 03:00:29 -04:00
// store reference to input for deterministic cloning
this . _input = duration ;
2013-05-06 03:38:29 -04:00
// representation for dateAddRemove
2014-07-25 03:00:29 -04:00
this . _milliseconds = + milliseconds +
2013-05-06 03:38:29 -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-07-25 03:00:29 -04:00
this . _days = + days +
2013-05-06 03:38:29 -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-07-25 03:00:29 -04:00
this . _months = + months +
2013-05-06 03:38:29 -04:00
years * 12 ;
2014-07-25 03:00:29 -04:00
this . _data = { } ;
2013-05-06 03:38:29 -04:00
2014-07-25 03:00:29 -04:00
this . _bubble ( ) ;
2013-05-06 03:38:29 -04:00
}
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Helpers
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
function extend ( a , b ) {
for ( var i in b ) {
if ( b . hasOwnProperty ( i ) ) {
a [ i ] = b [ i ] ;
}
}
return a ;
}
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
function leftZeroFill ( number , targetLength ) {
var output = number + '' ;
while ( output . length < targetLength ) {
output = '0' + output ;
}
return output ;
}
// helper function for _.addTime and _.subtractTime
2014-07-25 03:00:29 -04:00
function addOrSubtractDurationFromMoment ( mom , duration , isAdding , ignoreUpdateOffset ) {
var milliseconds = duration . _milliseconds ,
days = duration . _days ,
months = duration . _months ,
minutes ,
hours ;
if ( milliseconds ) {
mom . _d . setTime ( + mom . _d + milliseconds * isAdding ) ;
}
// store the minutes and hours so we can restore them
if ( days || months ) {
minutes = mom . minute ( ) ;
hours = mom . hour ( ) ;
}
if ( days ) {
mom . date ( mom . date ( ) + days * isAdding ) ;
2013-05-06 03:38:29 -04:00
}
2014-07-25 03:00:29 -04:00
if ( months ) {
mom . month ( mom . month ( ) + months * isAdding ) ;
2013-05-06 03:38:29 -04:00
}
2014-07-25 03:00:29 -04:00
if ( milliseconds && ! ignoreUpdateOffset ) {
moment . updateOffset ( mom ) ;
}
// restore the minutes and hours after possibly changing dst
if ( days || months ) {
mom . minute ( minutes ) ;
mom . hour ( hours ) ;
2013-05-06 03:38:29 -04:00
}
}
// check if is an array
function isArray ( input ) {
return Object . prototype . toString . call ( input ) === '[object Array]' ;
}
// compare two arrays, return the number of differences
function compareArrays ( array1 , array2 ) {
var len = Math . min ( array1 . length , array2 . length ) ,
lengthDiff = Math . abs ( array1 . length - array2 . length ) ,
diffs = 0 ,
i ;
for ( i = 0 ; i < len ; i ++ ) {
if ( ~ ~ array1 [ i ] !== ~ ~ array2 [ i ] ) {
diffs ++ ;
}
}
return diffs + lengthDiff ;
}
2014-07-25 03:00:29 -04:00
function normalizeUnits ( units ) {
return units ? unitAliases [ units ] || units . toLowerCase ( ) . replace ( /(.)s$/ , '$1' ) : units ;
}
2013-05-06 03:38:29 -04:00
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Languages
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
2014-07-25 03:00:29 -04:00
extend ( Language . prototype , {
2013-05-06 03:38:29 -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 ;
}
}
} ,
_months : "January_February_March_April_May_June_July_August_September_October_November_December" . split ( "_" ) ,
months : function ( m ) {
return this . _months [ m . month ( ) ] ;
} ,
_monthsShort : "Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec" . split ( "_" ) ,
monthsShort : function ( m ) {
return this . _monthsShort [ m . month ( ) ] ;
} ,
monthsParse : function ( monthName ) {
2014-07-25 03:00:29 -04:00
var i , mom , regex ;
2013-05-06 03:38:29 -04:00
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-07-25 03:00:29 -04:00
mom = moment . utc ( [ 2000 , i ] ) ;
2013-05-06 03:38:29 -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 ;
}
}
} ,
_weekdays : "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday" . split ( "_" ) ,
weekdays : function ( m ) {
return this . _weekdays [ m . day ( ) ] ;
} ,
_weekdaysShort : "Sun_Mon_Tue_Wed_Thu_Fri_Sat" . split ( "_" ) ,
weekdaysShort : function ( m ) {
return this . _weekdaysShort [ m . day ( ) ] ;
} ,
_weekdaysMin : "Su_Mo_Tu_We_Th_Fr_Sa" . split ( "_" ) ,
weekdaysMin : function ( m ) {
return this . _weekdaysMin [ m . day ( ) ] ;
} ,
2014-07-25 03:00:29 -04:00
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 ;
}
}
} ,
2013-05-06 03:38:29 -04:00
_longDateFormat : {
LT : "h:mm A" ,
L : "MM/DD/YYYY" ,
LL : "MMMM D YYYY" ,
LLL : "MMMM D YYYY LT" ,
LLLL : "dddd, MMMM D YYYY LT"
} ,
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 ;
} ,
2014-07-25 03:00:29 -04:00
isPM : function ( input ) {
// 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' ) ;
} ,
_meridiemParse : /[ap]\.?m?\.?/i ,
2013-05-06 03:38:29 -04:00
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' ,
2014-07-25 03:00:29 -04:00
lastWeek : '[Last] dddd [at] LT' ,
2013-05-06 03:38:29 -04:00
sameElse : 'L'
} ,
calendar : function ( key , mom ) {
var output = this . _calendar [ key ] ;
return typeof output === 'function' ? output . apply ( mom ) : output ;
} ,
_relativeTime : {
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"
} ,
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 ) ;
} ,
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 ) {
return this . _ordinal . replace ( "%d" , number ) ;
} ,
_ordinal : "%d" ,
preparse : function ( string ) {
return string ;
} ,
postformat : function ( string ) {
return string ;
} ,
week : function ( mom ) {
2014-07-25 03:00:29 -04:00
return weekOfYear ( mom , this . _week . dow , this . _week . doy ) . week ;
2013-05-06 03:38:29 -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-07-25 03:00:29 -04:00
} ) ;
2013-05-06 03:38:29 -04:00
// Loads a language definition into the `languages` cache. The function
// takes a key and optionally values. If not in the browser and no values
// are provided, it will load the language file module. As a convenience,
// this function also returns the language values.
function loadLang ( key , values ) {
values . abbr = key ;
if ( ! languages [ key ] ) {
languages [ key ] = new Language ( ) ;
}
languages [ key ] . set ( values ) ;
return languages [ key ] ;
}
2014-07-25 03:00:29 -04:00
// Remove a language from the `languages` cache. Mostly useful in tests.
function unloadLang ( key ) {
delete languages [ key ] ;
}
2013-05-06 03:38:29 -04:00
// Determines which language definition to use and returns it.
//
// With no parameters, it will return the global language. If you
// pass in a language key, such as 'en', it will return the
// definition for 'en', so long as 'en' has already been loaded using
// moment.lang.
function getLangDefinition ( key ) {
if ( ! key ) {
return moment . fn . _lang ;
}
if ( ! languages [ key ] && hasModule ) {
2014-07-25 03:00:29 -04:00
try {
require ( './lang/' + key ) ;
} catch ( e ) {
// call with no params to set to default
return moment . fn . _lang ;
}
2013-05-06 03:38:29 -04:00
}
2014-07-25 03:00:29 -04:00
return languages [ key ] || moment . fn . _lang ;
2013-05-06 03:38:29 -04:00
}
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Formatting
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
function removeFormattingTokens ( input ) {
if ( input . match ( /\[.*\]/ ) ) {
return input . replace ( /^\[|\]$/g , "" ) ;
}
return input . replace ( /\\/g , "" ) ;
}
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 ) {
var output = "" ;
for ( i = 0 ; i < length ; i ++ ) {
2014-07-25 03:00:29 -04:00
output += array [ i ] instanceof Function ? array [ i ] . call ( mom , format ) : array [ i ] ;
2013-05-06 03:38:29 -04:00
}
return output ;
} ;
}
// format date using native date object
function formatMoment ( m , format ) {
2014-07-25 03:00:29 -04:00
format = expandFormat ( format , m . lang ( ) ) ;
if ( ! formatFunctions [ format ] ) {
formatFunctions [ format ] = makeFormatFunction ( format ) ;
}
return formatFunctions [ format ] ( m ) ;
}
function expandFormat ( format , lang ) {
2013-05-06 03:38:29 -04:00
var i = 5 ;
function replaceLongDateFormatTokens ( input ) {
2014-07-25 03:00:29 -04:00
return lang . longDateFormat ( input ) || input ;
2013-05-06 03:38:29 -04:00
}
2014-07-25 03:00:29 -04:00
while ( i -- && ( localFormattingTokens . lastIndex = 0 ,
localFormattingTokens . test ( format ) ) ) {
2013-05-06 03:38:29 -04:00
format = format . replace ( localFormattingTokens , replaceLongDateFormatTokens ) ;
}
2014-07-25 03:00:29 -04:00
return format ;
2013-05-06 03:38:29 -04:00
}
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Parsing
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
// get the regex to find the next token
2014-07-25 03:00:29 -04:00
function getParseRegexForToken ( token , config ) {
2013-05-06 03:38:29 -04:00
switch ( token ) {
case 'DDDD' :
return parseTokenThreeDigits ;
case 'YYYY' :
return parseTokenFourDigits ;
case 'YYYYY' :
return parseTokenSixDigits ;
case 'S' :
case 'SS' :
case 'SSS' :
case 'DDD' :
return parseTokenOneToThreeDigits ;
case 'MMM' :
case 'MMMM' :
case 'dd' :
case 'ddd' :
case 'dddd' :
2014-07-25 03:00:29 -04:00
return parseTokenWord ;
2013-05-06 03:38:29 -04:00
case 'a' :
case 'A' :
2014-07-25 03:00:29 -04:00
return getLangDefinition ( config . _l ) . _meridiemParse ;
2013-05-06 03:38:29 -04:00
case 'X' :
return parseTokenTimestampMs ;
case 'Z' :
case 'ZZ' :
return parseTokenTimezone ;
case 'T' :
return parseTokenT ;
case 'MM' :
case 'DD' :
case 'YY' :
case 'HH' :
case 'hh' :
case 'mm' :
case 'ss' :
case 'M' :
case 'D' :
case 'd' :
case 'H' :
case 'h' :
case 'm' :
case 's' :
return parseTokenOneOrTwoDigits ;
default :
return new RegExp ( token . replace ( '\\' , '' ) ) ;
}
}
2014-07-25 03:00:29 -04:00
function timezoneMinutesFromString ( string ) {
var tzchunk = ( parseTokenTimezone . exec ( string ) || [ ] ) [ 0 ] ,
parts = ( tzchunk + '' ) . match ( parseTimezoneChunker ) || [ '-' , 0 , 0 ] ,
minutes = + ( parts [ 1 ] * 60 ) + ~ ~ parts [ 2 ] ;
return parts [ 0 ] === '+' ? - minutes : minutes ;
}
2013-05-06 03:38:29 -04:00
// function to convert string input to date
function addTimeToArrayFromToken ( token , input , config ) {
2014-07-25 03:00:29 -04:00
var a , datePartArray = config . _a ;
2013-05-06 03:38:29 -04:00
switch ( token ) {
// MONTH
case 'M' : // fall through to MM
case 'MM' :
2014-07-25 03:00:29 -04:00
if ( input != null ) {
datePartArray [ 1 ] = ~ ~ input - 1 ;
}
2013-05-06 03:38:29 -04:00
break ;
case 'MMM' : // fall through to MMMM
case 'MMMM' :
a = getLangDefinition ( config . _l ) . monthsParse ( input ) ;
// if we didn't find a month name, mark the date as invalid.
if ( a != null ) {
datePartArray [ 1 ] = a ;
} else {
config . _isValid = false ;
}
break ;
// DAY OF MONTH
2014-07-25 03:00:29 -04:00
case 'D' : // fall through to DD
case 'DD' :
if ( input != null ) {
datePartArray [ 2 ] = ~ ~ input ;
}
break ;
// DAY OF YEAR
2013-05-06 03:38:29 -04:00
case 'DDD' : // fall through to DDDD
case 'DDDD' :
if ( input != null ) {
2014-07-25 03:00:29 -04:00
datePartArray [ 1 ] = 0 ;
2013-05-06 03:38:29 -04:00
datePartArray [ 2 ] = ~ ~ input ;
}
break ;
// YEAR
case 'YY' :
datePartArray [ 0 ] = ~ ~ input + ( ~ ~ input > 68 ? 1900 : 2000 ) ;
break ;
case 'YYYY' :
case 'YYYYY' :
datePartArray [ 0 ] = ~ ~ input ;
break ;
// AM / PM
case 'a' : // fall through to A
case 'A' :
2014-07-25 03:00:29 -04:00
config . _isPm = getLangDefinition ( config . _l ) . isPM ( input ) ;
2013-05-06 03:38:29 -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' :
datePartArray [ 3 ] = ~ ~ input ;
break ;
// MINUTE
case 'm' : // fall through to mm
case 'mm' :
datePartArray [ 4 ] = ~ ~ input ;
break ;
// SECOND
case 's' : // fall through to ss
case 'ss' :
datePartArray [ 5 ] = ~ ~ input ;
break ;
// MILLISECOND
case 'S' :
case 'SS' :
case 'SSS' :
datePartArray [ 6 ] = ~ ~ ( ( '0.' + input ) * 1000 ) ;
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 ;
2014-07-25 03:00:29 -04:00
config . _tzm = timezoneMinutesFromString ( input ) ;
2013-05-06 03:38:29 -04:00
break ;
}
// if the input is null, the date is not valid
if ( input == null ) {
config . _isValid = false ;
}
}
// 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]
function dateFromArray ( config ) {
2014-07-25 03:00:29 -04:00
var i , date , input = [ ] , currentDate ;
2013-05-06 03:38:29 -04:00
if ( config . _d ) {
return ;
}
2014-07-25 03:00:29 -04:00
// 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
currentDate = currentDateArray ( config ) ;
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-05-06 03:38:29 -04:00
config . _a [ i ] = input [ i ] = ( config . _a [ i ] == null ) ? ( i === 2 ? 1 : 0 ) : config . _a [ i ] ;
}
// add the offsets to the time to be parsed so that we can have a clean array for checking isValid
2014-07-25 03:00:29 -04:00
input [ 3 ] += ~ ~ ( ( config . _tzm || 0 ) / 60 ) ;
input [ 4 ] += ~ ~ ( ( config . _tzm || 0 ) % 60 ) ;
2013-05-06 03:38:29 -04:00
date = new Date ( 0 ) ;
if ( config . _useUTC ) {
date . setUTCFullYear ( input [ 0 ] , input [ 1 ] , input [ 2 ] ) ;
date . setUTCHours ( input [ 3 ] , input [ 4 ] , input [ 5 ] , input [ 6 ] ) ;
} else {
date . setFullYear ( input [ 0 ] , input [ 1 ] , input [ 2 ] ) ;
date . setHours ( input [ 3 ] , input [ 4 ] , input [ 5 ] , input [ 6 ] ) ;
}
config . _d = date ;
}
2014-07-25 03:00:29 -04:00
function dateFromObject ( config ) {
var o = config . _i ;
if ( config . _d ) {
return ;
}
config . _a = [
o . years || o . year || o . y ,
o . months || o . month || o . M ,
o . days || o . day || o . d ,
o . hours || o . hour || o . h ,
o . minutes || o . minute || o . m ,
o . seconds || o . second || o . s ,
o . milliseconds || o . millisecond || o . ms
] ;
dateFromArray ( config ) ;
}
function currentDateArray ( config ) {
var now = new Date ( ) ;
if ( config . _useUTC ) {
return [
now . getUTCFullYear ( ) ,
now . getUTCMonth ( ) ,
now . getUTCDate ( )
] ;
} else {
return [ now . getFullYear ( ) , now . getMonth ( ) , now . getDate ( ) ] ;
}
}
2013-05-06 03:38:29 -04:00
// date from string and format string
function makeDateFromStringAndFormat ( config ) {
// This array is used to make a Date, either with `new Date` or `Date.UTC`
2014-07-25 03:00:29 -04:00
var lang = getLangDefinition ( config . _l ) ,
string = '' + config . _i ,
i , parsedInput , tokens ;
tokens = expandFormat ( config . _f , lang ) . match ( formattingTokens ) ;
2013-05-06 03:38:29 -04:00
config . _a = [ ] ;
for ( i = 0 ; i < tokens . length ; i ++ ) {
2014-07-25 03:00:29 -04:00
parsedInput = ( getParseRegexForToken ( tokens [ i ] , config ) . exec ( string ) || [ ] ) [ 0 ] ;
2013-05-06 03:38:29 -04:00
if ( parsedInput ) {
string = string . slice ( string . indexOf ( parsedInput ) + parsedInput . length ) ;
}
// don't parse if its not a known token
if ( formatTokenFunctions [ tokens [ i ] ] ) {
addTimeToArrayFromToken ( tokens [ i ] , parsedInput , config ) ;
}
}
2014-07-25 03:00:29 -04:00
// add remaining unparsed input to the string
if ( string ) {
config . _il = string ;
}
2013-05-06 03:38:29 -04:00
// handle am pm
if ( config . _isPm && config . _a [ 3 ] < 12 ) {
config . _a [ 3 ] += 12 ;
}
// if is 12 am, change hours to 0
if ( config . _isPm === false && config . _a [ 3 ] === 12 ) {
config . _a [ 3 ] = 0 ;
}
// return
dateFromArray ( config ) ;
}
// date from string and array of format strings
function makeDateFromStringAndArray ( config ) {
var tempConfig ,
tempMoment ,
bestMoment ,
scoreToBeat = 99 ,
i ,
currentScore ;
2014-07-25 03:00:29 -04:00
for ( i = 0 ; i < config . _f . length ; i ++ ) {
2013-05-06 03:38:29 -04:00
tempConfig = extend ( { } , config ) ;
2014-07-25 03:00:29 -04:00
tempConfig . _f = config . _f [ i ] ;
2013-05-06 03:38:29 -04:00
makeDateFromStringAndFormat ( tempConfig ) ;
tempMoment = new Moment ( tempConfig ) ;
currentScore = compareArrays ( tempConfig . _a , tempMoment . toArray ( ) ) ;
2014-07-25 03:00:29 -04:00
// if there is any input that was not parsed
// add a penalty for that format
if ( tempMoment . _il ) {
currentScore += tempMoment . _il . length ;
}
2013-05-06 03:38:29 -04:00
if ( currentScore < scoreToBeat ) {
scoreToBeat = currentScore ;
bestMoment = tempMoment ;
}
}
extend ( config , bestMoment ) ;
}
// date from iso format
function makeDateFromString ( config ) {
var i ,
2014-07-25 03:00:29 -04:00
string = config . _i ,
match = isoRegex . exec ( string ) ;
if ( match ) {
// match[2] should be "T" or undefined
config . _f = 'YYYY-MM-DD' + ( match [ 2 ] || " " ) ;
2013-05-06 03:38:29 -04:00
for ( i = 0 ; i < 4 ; i ++ ) {
if ( isoTimes [ i ] [ 1 ] . exec ( string ) ) {
config . _f += isoTimes [ i ] [ 0 ] ;
break ;
}
}
if ( parseTokenTimezone . exec ( string ) ) {
config . _f += " Z" ;
}
makeDateFromStringAndFormat ( config ) ;
} else {
config . _d = new Date ( string ) ;
}
}
function makeDateFromInput ( config ) {
var input = config . _i ,
matched = aspNetJsonRegex . exec ( input ) ;
if ( input === undefined ) {
config . _d = new Date ( ) ;
} else if ( matched ) {
config . _d = new Date ( + matched [ 1 ] ) ;
} else if ( typeof input === 'string' ) {
makeDateFromString ( config ) ;
} else if ( isArray ( input ) ) {
config . _a = input . slice ( 0 ) ;
dateFromArray ( config ) ;
2014-07-25 03:00:29 -04:00
} else if ( input instanceof Date ) {
config . _d = new Date ( + input ) ;
} else if ( typeof ( input ) === 'object' ) {
dateFromObject ( config ) ;
2013-05-06 03:38:29 -04:00
} else {
2014-07-25 03:00:29 -04:00
config . _d = new Date ( input ) ;
2013-05-06 03:38:29 -04:00
}
}
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Relative Time
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
// helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize
function substituteTimeAgo ( string , number , withoutSuffix , isFuture , lang ) {
return lang . relativeTime ( number || 1 , ! ! withoutSuffix , string , isFuture ) ;
}
function relativeTime ( milliseconds , withoutSuffix , lang ) {
var seconds = round ( Math . abs ( milliseconds ) / 1000 ) ,
minutes = round ( seconds / 60 ) ,
hours = round ( minutes / 60 ) ,
days = round ( hours / 24 ) ,
years = round ( days / 365 ) ,
args = seconds < 45 && [ 's' , seconds ] ||
minutes === 1 && [ 'm' ] ||
minutes < 45 && [ 'mm' , minutes ] ||
hours === 1 && [ 'h' ] ||
hours < 22 && [ 'hh' , hours ] ||
days === 1 && [ 'd' ] ||
days <= 25 && [ 'dd' , days ] ||
days <= 45 && [ 'M' ] ||
days < 345 && [ 'MM' , round ( days / 30 ) ] ||
years === 1 && [ 'y' ] || [ 'yy' , years ] ;
args [ 2 ] = withoutSuffix ;
args [ 3 ] = milliseconds > 0 ;
args [ 4 ] = lang ;
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 ,
2014-07-25 03:00:29 -04:00
daysToDayOfWeek = firstDayOfWeekOfYear - mom . day ( ) ,
adjustedMoment ;
2013-05-06 03:38:29 -04:00
if ( daysToDayOfWeek > end ) {
daysToDayOfWeek -= 7 ;
}
if ( daysToDayOfWeek < end - 7 ) {
daysToDayOfWeek += 7 ;
}
2014-07-25 03:00:29 -04:00
adjustedMoment = moment ( mom ) . add ( 'd' , daysToDayOfWeek ) ;
return {
week : Math . ceil ( adjustedMoment . dayOfYear ( ) / 7 ) ,
year : adjustedMoment . year ( )
} ;
2013-05-06 03:38:29 -04:00
}
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Top Level Functions
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
function makeMoment ( config ) {
var input = config . _i ,
format = config . _f ;
if ( input === null || input === '' ) {
return null ;
}
if ( typeof input === 'string' ) {
config . _i = input = getLangDefinition ( ) . preparse ( input ) ;
}
if ( moment . isMoment ( input ) ) {
config = extend ( { } , input ) ;
config . _d = new Date ( + input . _d ) ;
} else if ( format ) {
if ( isArray ( format ) ) {
makeDateFromStringAndArray ( config ) ;
} else {
makeDateFromStringAndFormat ( config ) ;
}
} else {
makeDateFromInput ( config ) ;
}
return new Moment ( config ) ;
}
moment = function ( input , format , lang ) {
return makeMoment ( {
_i : input ,
_f : format ,
_l : lang ,
_isUTC : false
} ) ;
} ;
// creating with utc
moment . utc = function ( input , format , lang ) {
return makeMoment ( {
_useUTC : true ,
_isUTC : true ,
_l : lang ,
_i : input ,
_f : format
2014-07-25 03:00:29 -04:00
} ) . utc ( ) ;
2013-05-06 03:38:29 -04:00
} ;
// creating with unix timestamp (in seconds)
moment . unix = function ( input ) {
return moment ( input * 1000 ) ;
} ;
// duration
moment . duration = function ( input , key ) {
var isDuration = moment . isDuration ( input ) ,
isNumber = ( typeof input === 'number' ) ,
2014-07-25 03:00:29 -04:00
duration = ( isDuration ? input . _input : ( isNumber ? { } : input ) ) ,
matched = aspNetTimeSpanJsonRegex . exec ( input ) ,
sign ,
2013-05-06 03:38:29 -04:00
ret ;
if ( isNumber ) {
if ( key ) {
duration [ key ] = input ;
} else {
duration . milliseconds = input ;
}
2014-07-25 03:00:29 -04:00
} else if ( matched ) {
sign = ( matched [ 1 ] === "-" ) ? - 1 : 1 ;
duration = {
y : 0 ,
d : ~ ~ matched [ 2 ] * sign ,
h : ~ ~ matched [ 3 ] * sign ,
m : ~ ~ matched [ 4 ] * sign ,
s : ~ ~ matched [ 5 ] * sign ,
ms : ~ ~ matched [ 6 ] * sign
} ;
2013-05-06 03:38:29 -04:00
}
ret = new Duration ( duration ) ;
if ( isDuration && input . hasOwnProperty ( '_lang' ) ) {
ret . _lang = input . _lang ;
}
return ret ;
} ;
// version number
moment . version = VERSION ;
// default format
moment . defaultFormat = isoFormat ;
2014-07-25 03:00:29 -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 ( ) { } ;
2013-05-06 03:38:29 -04:00
// This function will load languages and then set the global language. If
// no arguments are passed in, it will simply return the current global
// language key.
moment . lang = function ( key , values ) {
if ( ! key ) {
return moment . fn . _lang . _abbr ;
}
2014-07-25 03:00:29 -04:00
key = key . toLowerCase ( ) ;
key = key . replace ( '_' , '-' ) ;
2013-05-06 03:38:29 -04:00
if ( values ) {
loadLang ( key , values ) ;
2014-07-25 03:00:29 -04:00
} else if ( values === null ) {
unloadLang ( key ) ;
key = 'en' ;
2013-05-06 03:38:29 -04:00
} else if ( ! languages [ key ] ) {
getLangDefinition ( key ) ;
}
moment . duration . fn . _lang = moment . fn . _lang = getLangDefinition ( key ) ;
} ;
// returns language data
moment . langData = function ( key ) {
if ( key && key . _lang && key . _lang . _abbr ) {
key = key . _lang . _abbr ;
}
return getLangDefinition ( key ) ;
} ;
// compare moment object
moment . isMoment = function ( obj ) {
return obj instanceof Moment ;
} ;
// for typechecking Duration objects
moment . isDuration = function ( obj ) {
return obj instanceof Duration ;
} ;
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Moment Prototype
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
2014-07-25 03:00:29 -04:00
extend ( moment . fn = Moment . prototype , {
2013-05-06 03:38:29 -04:00
clone : function ( ) {
return moment ( this ) ;
} ,
valueOf : function ( ) {
2014-07-25 03:00:29 -04:00
return + this . _d + ( ( this . _offset || 0 ) * 60000 ) ;
2013-05-06 03:38:29 -04:00
} ,
unix : function ( ) {
2014-07-25 03:00:29 -04:00
return Math . floor ( + this / 1 0 0 0 ) ;
2013-05-06 03:38:29 -04:00
} ,
toString : function ( ) {
return this . format ( "ddd MMM DD YYYY HH:mm:ss [GMT]ZZ" ) ;
} ,
toDate : function ( ) {
2014-07-25 03:00:29 -04:00
return this . _offset ? new Date ( + this ) : this . _d ;
2013-05-06 03:38:29 -04:00
} ,
2014-07-25 03:00:29 -04:00
toISOString : function ( ) {
return formatMoment ( moment ( this ) . utc ( ) , 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]' ) ;
2013-05-06 03:38:29 -04:00
} ,
toArray : function ( ) {
var m = this ;
return [
m . year ( ) ,
m . month ( ) ,
m . date ( ) ,
m . hours ( ) ,
m . minutes ( ) ,
m . seconds ( ) ,
m . milliseconds ( )
] ;
} ,
isValid : function ( ) {
if ( this . _isValid == null ) {
if ( this . _a ) {
this . _isValid = ! compareArrays ( this . _a , ( this . _isUTC ? moment . utc ( this . _a ) : moment ( this . _a ) ) . toArray ( ) ) ;
} else {
this . _isValid = ! isNaN ( this . _d . getTime ( ) ) ;
}
}
return ! ! this . _isValid ;
} ,
2014-07-25 03:00:29 -04:00
invalidAt : function ( ) {
var i , arr1 = this . _a , arr2 = ( this . _isUTC ? moment . utc ( this . _a ) : moment ( this . _a ) ) . toArray ( ) ;
for ( i = 6 ; i >= 0 && arr1 [ i ] === arr2 [ i ] ; -- i ) {
// empty loop body
}
return i ;
} ,
2013-05-06 03:38:29 -04:00
utc : function ( ) {
2014-07-25 03:00:29 -04:00
return this . zone ( 0 ) ;
2013-05-06 03:38:29 -04:00
} ,
local : function ( ) {
2014-07-25 03:00:29 -04:00
this . zone ( 0 ) ;
2013-05-06 03:38:29 -04:00
this . _isUTC = false ;
return this ;
} ,
format : function ( inputString ) {
var output = formatMoment ( this , inputString || moment . defaultFormat ) ;
return this . lang ( ) . postformat ( output ) ;
} ,
add : function ( input , val ) {
var dur ;
// switch args to support add('s', 1) and add(1, 's')
if ( typeof input === 'string' ) {
dur = moment . duration ( + val , input ) ;
} else {
dur = moment . duration ( input , val ) ;
}
addOrSubtractDurationFromMoment ( this , dur , 1 ) ;
return this ;
} ,
subtract : function ( input , val ) {
var dur ;
// switch args to support subtract('s', 1) and subtract(1, 's')
if ( typeof input === 'string' ) {
dur = moment . duration ( + val , input ) ;
} else {
dur = moment . duration ( input , val ) ;
}
addOrSubtractDurationFromMoment ( this , dur , - 1 ) ;
return this ;
} ,
diff : function ( input , units , asFloat ) {
2014-07-25 03:00:29 -04:00
var that = this . _isUTC ? moment ( input ) . zone ( this . _offset || 0 ) : moment ( input ) . local ( ) ,
2013-05-06 03:38:29 -04:00
zoneDiff = ( this . zone ( ) - that . zone ( ) ) * 6e4 ,
diff , output ;
2014-07-25 03:00:29 -04:00
units = normalizeUnits ( units ) ;
2013-05-06 03:38:29 -04:00
if ( units === 'year' || units === 'month' ) {
2014-07-25 03:00:29 -04:00
// average number of days in the months in the given dates
2013-05-06 03:38:29 -04:00
diff = ( this . daysInMonth ( ) + that . daysInMonth ( ) ) * 432e5 ; // 24 * 60 * 60 * 1000 / 2
2014-07-25 03:00:29 -04:00
// difference in months
2013-05-06 03:38:29 -04:00
output = ( ( this . year ( ) - that . year ( ) ) * 12 ) + ( this . month ( ) - that . month ( ) ) ;
2014-07-25 03:00:29 -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-05-06 03:38:29 -04:00
if ( units === 'year' ) {
output = output / 12 ;
}
} else {
2014-07-25 03:00:29 -04:00
diff = ( this - that ) ;
2013-05-06 03:38:29 -04:00
output = units === 'second' ? diff / 1e3 : // 1000
units === 'minute' ? diff / 6e4 : // 1000 * 60
units === 'hour' ? diff / 36e5 : // 1000 * 60 * 60
2014-07-25 03:00:29 -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-05-06 03:38:29 -04:00
diff ;
}
return asFloat ? output : absRound ( output ) ;
} ,
from : function ( time , withoutSuffix ) {
return moment . duration ( this . diff ( time ) ) . lang ( this . lang ( ) . _abbr ) . humanize ( ! withoutSuffix ) ;
} ,
fromNow : function ( withoutSuffix ) {
return this . from ( moment ( ) , withoutSuffix ) ;
} ,
calendar : function ( ) {
2014-07-25 03:00:29 -04:00
var diff = this . diff ( moment ( ) . zone ( this . zone ( ) ) . startOf ( 'day' ) , 'days' , true ) ,
2013-05-06 03:38:29 -04:00
format = diff < - 6 ? 'sameElse' :
diff < - 1 ? 'lastWeek' :
diff < 0 ? 'lastDay' :
diff < 1 ? 'sameDay' :
diff < 2 ? 'nextDay' :
diff < 7 ? 'nextWeek' : 'sameElse' ;
return this . format ( this . lang ( ) . calendar ( format , this ) ) ;
} ,
isLeapYear : function ( ) {
var year = this . year ( ) ;
return ( year % 4 === 0 && year % 100 !== 0 ) || year % 400 === 0 ;
} ,
isDST : function ( ) {
2014-07-25 03:00:29 -04:00
return ( this . zone ( ) < this . clone ( ) . month ( 0 ) . zone ( ) ||
this . zone ( ) < this . clone ( ) . month ( 5 ) . zone ( ) ) ;
2013-05-06 03:38:29 -04:00
} ,
day : function ( input ) {
var day = this . _isUTC ? this . _d . getUTCDay ( ) : this . _d . getDay ( ) ;
2014-07-25 03:00:29 -04:00
if ( input != null ) {
if ( typeof input === 'string' ) {
input = this . lang ( ) . weekdaysParse ( input ) ;
if ( typeof input !== 'number' ) {
return this ;
}
}
return this . add ( { d : input - day } ) ;
} else {
return day ;
}
} ,
month : function ( input ) {
var utc = this . _isUTC ? 'UTC' : '' ,
dayOfMonth ;
if ( input != null ) {
if ( typeof input === 'string' ) {
input = this . lang ( ) . monthsParse ( input ) ;
if ( typeof input !== 'number' ) {
return this ;
}
}
dayOfMonth = this . date ( ) ;
this . date ( 1 ) ;
this . _d [ 'set' + utc + 'Month' ] ( input ) ;
this . date ( Math . min ( dayOfMonth , this . daysInMonth ( ) ) ) ;
moment . updateOffset ( this ) ;
return this ;
} else {
return this . _d [ 'get' + utc + 'Month' ] ( ) ;
}
2013-05-06 03:38:29 -04:00
} ,
startOf : function ( units ) {
2014-07-25 03:00:29 -04:00
units = normalizeUnits ( units ) ;
2013-05-06 03:38:29 -04:00
// the following switch intentionally omits break keywords
// to utilize falling through the cases.
switch ( units ) {
case 'year' :
this . month ( 0 ) ;
/* falls through */
case 'month' :
this . date ( 1 ) ;
/* falls through */
case 'week' :
2014-07-25 03:00:29 -04:00
case 'isoweek' :
2013-05-06 03:38:29 -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' ) {
2014-07-25 03:00:29 -04:00
this . weekday ( 0 ) ;
} else if ( units === 'isoweek' ) {
this . isoWeekday ( 1 ) ;
2013-05-06 03:38:29 -04:00
}
return this ;
} ,
endOf : function ( units ) {
2014-07-25 03:00:29 -04:00
units = normalizeUnits ( units ) ;
return this . startOf ( units ) . add ( ( units === 'isoweek' ? 'week' : units ) , 1 ) . subtract ( 'ms' , 1 ) ;
2013-05-06 03:38:29 -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 ) {
units = typeof units !== 'undefined' ? units : 'millisecond' ;
return + this . clone ( ) . startOf ( units ) === + moment ( input ) . startOf ( units ) ;
} ,
2014-07-25 03:00:29 -04:00
min : function ( other ) {
other = moment . apply ( null , arguments ) ;
return other < this ? this : other ;
} ,
max : function ( other ) {
other = moment . apply ( null , arguments ) ;
return other > this ? this : other ;
} ,
zone : function ( input ) {
var offset = this . _offset || 0 ;
if ( input != null ) {
if ( typeof input === "string" ) {
input = timezoneMinutesFromString ( input ) ;
}
if ( Math . abs ( input ) < 16 ) {
input = input * 60 ;
}
this . _offset = input ;
this . _isUTC = true ;
if ( offset !== input ) {
addOrSubtractDurationFromMoment ( this , moment . duration ( offset - input , 'm' ) , 1 , true ) ;
}
} else {
return this . _isUTC ? offset : this . _d . getTimezoneOffset ( ) ;
}
return this ;
} ,
zoneAbbr : function ( ) {
return this . _isUTC ? "UTC" : "" ;
} ,
zoneName : function ( ) {
return this . _isUTC ? "Coordinated Universal Time" : "" ;
} ,
hasAlignedHourOffset : function ( input ) {
if ( ! input ) {
input = 0 ;
}
else {
input = moment ( input ) . zone ( ) ;
}
return ( this . zone ( ) - input ) % 60 === 0 ;
2013-05-06 03:38:29 -04:00
} ,
daysInMonth : function ( ) {
return moment . utc ( [ this . year ( ) , this . month ( ) + 1 , 0 ] ) . date ( ) ;
} ,
dayOfYear : function ( input ) {
var dayOfYear = round ( ( moment ( this ) . startOf ( 'day' ) - moment ( this ) . startOf ( 'year' ) ) / 864e5 ) + 1 ;
return input == null ? dayOfYear : this . add ( "d" , ( input - dayOfYear ) ) ;
} ,
2014-07-25 03:00:29 -04:00
weekYear : function ( input ) {
var year = weekOfYear ( this , this . lang ( ) . _week . dow , this . lang ( ) . _week . doy ) . year ;
return input == null ? year : this . add ( "y" , ( input - year ) ) ;
} ,
isoWeekYear : function ( input ) {
var year = weekOfYear ( this , 1 , 4 ) . year ;
return input == null ? year : this . add ( "y" , ( input - year ) ) ;
2013-05-06 03:38:29 -04:00
} ,
week : function ( input ) {
var week = this . lang ( ) . week ( this ) ;
return input == null ? week : this . add ( "d" , ( input - week ) * 7 ) ;
} ,
2014-07-25 03:00:29 -04:00
isoWeek : function ( input ) {
var week = weekOfYear ( this , 1 , 4 ) . week ;
return input == null ? week : this . add ( "d" , ( input - week ) * 7 ) ;
} ,
weekday : function ( input ) {
var weekday = ( this . _d . getDay ( ) + 7 - this . lang ( ) . _week . dow ) % 7 ;
return input == null ? weekday : this . add ( "d" , input - weekday ) ;
} ,
isoWeekday : function ( input ) {
// 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 ) ;
} ,
get : function ( units ) {
units = normalizeUnits ( units ) ;
return this [ units . toLowerCase ( ) ] ( ) ;
} ,
set : function ( units , value ) {
units = normalizeUnits ( units ) ;
this [ units . toLowerCase ( ) ] ( value ) ;
} ,
2013-05-06 03:38:29 -04:00
// If passed a language key, it will set the language for this
// instance. Otherwise, it will return the language configuration
// variables for this instance.
lang : function ( key ) {
if ( key === undefined ) {
return this . _lang ;
} else {
this . _lang = getLangDefinition ( key ) ;
return this ;
}
}
2014-07-25 03:00:29 -04:00
} ) ;
2013-05-06 03:38:29 -04:00
// helper for adding shortcuts
function makeGetterAndSetter ( name , key ) {
moment . fn [ name ] = moment . fn [ name + 's' ] = function ( input ) {
var utc = this . _isUTC ? 'UTC' : '' ;
if ( input != null ) {
this . _d [ 'set' + utc + key ] ( input ) ;
2014-07-25 03:00:29 -04:00
moment . updateOffset ( this ) ;
2013-05-06 03:38:29 -04:00
return this ;
} else {
return this . _d [ 'get' + utc + key ] ( ) ;
}
} ;
}
// loop through and add shortcuts (Month, Date, Hours, Minutes, Seconds, Milliseconds)
for ( i = 0 ; i < proxyGettersAndSetters . length ; i ++ ) {
makeGetterAndSetter ( proxyGettersAndSetters [ i ] . toLowerCase ( ) . replace ( /s$/ , '' ) , proxyGettersAndSetters [ i ] ) ;
}
// add shortcut for year (uses different syntax than the getter/setter 'year' == 'FullYear')
makeGetterAndSetter ( 'year' , 'FullYear' ) ;
// add plural methods
moment . fn . days = moment . fn . day ;
2014-07-25 03:00:29 -04:00
moment . fn . months = moment . fn . month ;
2013-05-06 03:38:29 -04:00
moment . fn . weeks = moment . fn . week ;
moment . fn . isoWeeks = moment . fn . isoWeek ;
2014-07-25 03:00:29 -04:00
// add aliased format methods
moment . fn . toJSON = moment . fn . toISOString ;
2013-05-06 03:38:29 -04:00
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Duration Prototype
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
2014-07-25 03:00:29 -04:00
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 ;
// 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 ) ;
data . days = days % 30 ;
months += absRound ( days / 30 ) ;
data . months = months % 12 ;
years = absRound ( months / 12 ) ;
data . years = years ;
} ,
2013-05-06 03:38:29 -04:00
weeks : function ( ) {
return absRound ( this . days ( ) / 7 ) ;
} ,
valueOf : function ( ) {
return this . _milliseconds +
this . _days * 864e5 +
2014-07-25 03:00:29 -04:00
( this . _months % 12 ) * 2592e6 +
~ ~ ( this . _months / 12 ) * 31536e6 ;
2013-05-06 03:38:29 -04:00
} ,
humanize : function ( withSuffix ) {
var difference = + this ,
output = relativeTime ( difference , ! withSuffix , this . lang ( ) ) ;
if ( withSuffix ) {
output = this . lang ( ) . pastFuture ( difference , output ) ;
}
return this . lang ( ) . postformat ( output ) ;
} ,
2014-07-25 03:00:29 -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 ;
this . _bubble ( ) ;
return this ;
} ,
subtract : function ( input , val ) {
var dur = moment . duration ( input , val ) ;
this . _milliseconds -= dur . _milliseconds ;
this . _days -= dur . _days ;
this . _months -= dur . _months ;
this . _bubble ( ) ;
return this ;
} ,
get : function ( units ) {
units = normalizeUnits ( units ) ;
return this [ units . toLowerCase ( ) + 's' ] ( ) ;
} ,
as : function ( units ) {
units = normalizeUnits ( units ) ;
return this [ 'as' + units . charAt ( 0 ) . toUpperCase ( ) + units . slice ( 1 ) + 's' ] ( ) ;
} ,
2013-05-06 03:38:29 -04:00
lang : moment . fn . lang
2014-07-25 03:00:29 -04:00
} ) ;
2013-05-06 03:38:29 -04:00
function makeDurationGetter ( name ) {
moment . duration . fn [ name ] = function ( ) {
return this . _data [ name ] ;
} ;
}
function makeDurationAsGetter ( name , factor ) {
moment . duration . fn [ 'as' + name ] = function ( ) {
return + this / f a c t o r ;
} ;
}
for ( i in unitMillisecondFactors ) {
if ( unitMillisecondFactors . hasOwnProperty ( i ) ) {
makeDurationAsGetter ( i , unitMillisecondFactors [ i ] ) ;
makeDurationGetter ( i . toLowerCase ( ) ) ;
}
}
makeDurationAsGetter ( 'Weeks' , 6048e5 ) ;
2014-07-25 03:00:29 -04:00
moment . duration . fn . asMonths = function ( ) {
return ( + this - this . years ( ) * 31536e6 ) / 2592e6 + this . years ( ) * 12 ;
} ;
2013-05-06 03:38:29 -04:00
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Default Lang
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
// Set default language, other languages will inherit from English.
moment . lang ( 'en' , {
ordinal : function ( number ) {
var b = number % 10 ,
output = ( ~ ~ ( number % 100 / 10 ) === 1 ) ? 'th' :
( b === 1 ) ? 'st' :
( b === 2 ) ? 'nd' :
( b === 3 ) ? 'rd' : 'th' ;
return number + output ;
}
} ) ;
2014-07-25 03:00:29 -04:00
/* EMBED_LANGUAGES */
2013-05-06 03:38:29 -04:00
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Exposing Moment
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
// CommonJS module is defined
if ( hasModule ) {
module . exports = moment ;
}
/*global ender:false */
if ( typeof ender === 'undefined' ) {
// here, `this` means `window` in the browser, or `global` on the server
// add `moment` as a global object via a string identifier,
// for Closure Compiler "advanced" mode
this [ 'moment' ] = moment ;
}
/*global define:false */
if ( typeof define === "function" && define . amd ) {
define ( "moment" , [ ] , function ( ) {
return moment ;
} ) ;
}
} ) . call ( this ) ;