moment.js 100 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044
  1. //! moment.js
  2. //! version : 2.9.0
  3. //! authors : Tim Wood, Iskren Chernev, Moment.js contributors
  4. //! license : MIT
  5. //! momentjs.com
  6. (function (undefined) {
  7. /************************************
  8. Constants
  9. ************************************/
  10. var moment,
  11. VERSION = '2.9.0',
  12. // the global-scope this is NOT the global object in Node.js
  13. globalScope = (typeof global !== 'undefined' && (typeof window === 'undefined' || window === global.window)) ? global : this,
  14. oldGlobalMoment,
  15. round = Math.round,
  16. hasOwnProperty = Object.prototype.hasOwnProperty,
  17. i,
  18. YEAR = 0,
  19. MONTH = 1,
  20. DATE = 2,
  21. HOUR = 3,
  22. MINUTE = 4,
  23. SECOND = 5,
  24. MILLISECOND = 6,
  25. // internal storage for locale config files
  26. locales = {},
  27. // extra moment internal properties (plugins register props here)
  28. momentProperties = [],
  29. // check for nodeJS
  30. hasModule = (typeof module !== 'undefined' && module && module.exports),
  31. // ASP.NET json date format regex
  32. aspNetJsonRegex = /^\/?Date\((\-?\d+)/i,
  33. aspNetTimeSpanJsonRegex = /(\-)?(?:(\d*)\.)?(\d+)\:(\d+)(?:\:(\d+)\.?(\d{3})?)?/,
  34. // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html
  35. // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere
  36. isoDurationRegex = /^(-)?P(?:(?:([0-9,.]*)Y)?(?:([0-9,.]*)M)?(?:([0-9,.]*)D)?(?:T(?:([0-9,.]*)H)?(?:([0-9,.]*)M)?(?:([0-9,.]*)S)?)?|([0-9,.]*)W)$/,
  37. // format tokens
  38. 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|X|zz?|ZZ?|.)/g,
  39. localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,
  40. // parsing token regexes
  41. parseTokenOneOrTwoDigits = /\d\d?/, // 0 - 99
  42. parseTokenOneToThreeDigits = /\d{1,3}/, // 0 - 999
  43. parseTokenOneToFourDigits = /\d{1,4}/, // 0 - 9999
  44. parseTokenOneToSixDigits = /[+\-]?\d{1,6}/, // -999,999 - 999,999
  45. parseTokenDigits = /\d+/, // nonzero number of digits
  46. 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.
  47. parseTokenTimezone = /Z|[\+\-]\d\d:?\d\d/gi, // +00:00 -00:00 +0000 -0000 or Z
  48. parseTokenT = /T/i, // T (ISO separator)
  49. parseTokenOffsetMs = /[\+\-]?\d+/, // 1234567890123
  50. parseTokenTimestampMs = /[\+\-]?\d+(\.\d{1,3})?/, // 123456789 123456789.123
  51. //strict parsing regexes
  52. parseTokenOneDigit = /\d/, // 0 - 9
  53. parseTokenTwoDigits = /\d\d/, // 00 - 99
  54. parseTokenThreeDigits = /\d{3}/, // 000 - 999
  55. parseTokenFourDigits = /\d{4}/, // 0000 - 9999
  56. parseTokenSixDigits = /[+-]?\d{6}/, // -999,999 - 999,999
  57. parseTokenSignedNumber = /[+-]?\d+/, // -inf - inf
  58. // iso 8601 regex
  59. // 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)
  60. 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)?)?$/,
  61. isoFormat = 'YYYY-MM-DDTHH:mm:ssZ',
  62. isoDates = [
  63. ['YYYYYY-MM-DD', /[+-]\d{6}-\d{2}-\d{2}/],
  64. ['YYYY-MM-DD', /\d{4}-\d{2}-\d{2}/],
  65. ['GGGG-[W]WW-E', /\d{4}-W\d{2}-\d/],
  66. ['GGGG-[W]WW', /\d{4}-W\d{2}/],
  67. ['YYYY-DDD', /\d{4}-\d{3}/]
  68. ],
  69. // iso time formats and regexes
  70. isoTimes = [
  71. ['HH:mm:ss.SSSS', /(T| )\d\d:\d\d:\d\d\.\d+/],
  72. ['HH:mm:ss', /(T| )\d\d:\d\d:\d\d/],
  73. ['HH:mm', /(T| )\d\d:\d\d/],
  74. ['HH', /(T| )\d\d/]
  75. ],
  76. // timezone chunker '+10:00' > ['10', '00'] or '-1530' > ['-', '15', '30']
  77. parseTimezoneChunker = /([\+\-]|\d\d)/gi,
  78. // getter and setter names
  79. proxyGettersAndSetters = 'Date|Hours|Minutes|Seconds|Milliseconds'.split('|'),
  80. unitMillisecondFactors = {
  81. 'Milliseconds' : 1,
  82. 'Seconds' : 1e3,
  83. 'Minutes' : 6e4,
  84. 'Hours' : 36e5,
  85. 'Days' : 864e5,
  86. 'Months' : 2592e6,
  87. 'Years' : 31536e6
  88. },
  89. unitAliases = {
  90. ms : 'millisecond',
  91. s : 'second',
  92. m : 'minute',
  93. h : 'hour',
  94. d : 'day',
  95. D : 'date',
  96. w : 'week',
  97. W : 'isoWeek',
  98. M : 'month',
  99. Q : 'quarter',
  100. y : 'year',
  101. DDD : 'dayOfYear',
  102. e : 'weekday',
  103. E : 'isoWeekday',
  104. gg: 'weekYear',
  105. GG: 'isoWeekYear'
  106. },
  107. camelFunctions = {
  108. dayofyear : 'dayOfYear',
  109. isoweekday : 'isoWeekday',
  110. isoweek : 'isoWeek',
  111. weekyear : 'weekYear',
  112. isoweekyear : 'isoWeekYear'
  113. },
  114. // format function strings
  115. formatFunctions = {},
  116. // default relative time thresholds
  117. relativeTimeThresholds = {
  118. s: 45, // seconds to minute
  119. m: 45, // minutes to hour
  120. h: 22, // hours to day
  121. d: 26, // days to month
  122. M: 11 // months to year
  123. },
  124. // tokens to ordinalize and pad
  125. ordinalizeTokens = 'DDD w W M D d'.split(' '),
  126. paddedTokens = 'M D H h m s w W'.split(' '),
  127. formatTokenFunctions = {
  128. M : function () {
  129. return this.month() + 1;
  130. },
  131. MMM : function (format) {
  132. return this.localeData().monthsShort(this, format);
  133. },
  134. MMMM : function (format) {
  135. return this.localeData().months(this, format);
  136. },
  137. D : function () {
  138. return this.date();
  139. },
  140. DDD : function () {
  141. return this.dayOfYear();
  142. },
  143. d : function () {
  144. return this.day();
  145. },
  146. dd : function (format) {
  147. return this.localeData().weekdaysMin(this, format);
  148. },
  149. ddd : function (format) {
  150. return this.localeData().weekdaysShort(this, format);
  151. },
  152. dddd : function (format) {
  153. return this.localeData().weekdays(this, format);
  154. },
  155. w : function () {
  156. return this.week();
  157. },
  158. W : function () {
  159. return this.isoWeek();
  160. },
  161. YY : function () {
  162. return leftZeroFill(this.year() % 100, 2);
  163. },
  164. YYYY : function () {
  165. return leftZeroFill(this.year(), 4);
  166. },
  167. YYYYY : function () {
  168. return leftZeroFill(this.year(), 5);
  169. },
  170. YYYYYY : function () {
  171. var y = this.year(), sign = y >= 0 ? '+' : '-';
  172. return sign + leftZeroFill(Math.abs(y), 6);
  173. },
  174. gg : function () {
  175. return leftZeroFill(this.weekYear() % 100, 2);
  176. },
  177. gggg : function () {
  178. return leftZeroFill(this.weekYear(), 4);
  179. },
  180. ggggg : function () {
  181. return leftZeroFill(this.weekYear(), 5);
  182. },
  183. GG : function () {
  184. return leftZeroFill(this.isoWeekYear() % 100, 2);
  185. },
  186. GGGG : function () {
  187. return leftZeroFill(this.isoWeekYear(), 4);
  188. },
  189. GGGGG : function () {
  190. return leftZeroFill(this.isoWeekYear(), 5);
  191. },
  192. e : function () {
  193. return this.weekday();
  194. },
  195. E : function () {
  196. return this.isoWeekday();
  197. },
  198. a : function () {
  199. return this.localeData().meridiem(this.hours(), this.minutes(), true);
  200. },
  201. A : function () {
  202. return this.localeData().meridiem(this.hours(), this.minutes(), false);
  203. },
  204. H : function () {
  205. return this.hours();
  206. },
  207. h : function () {
  208. return this.hours() % 12 || 12;
  209. },
  210. m : function () {
  211. return this.minutes();
  212. },
  213. s : function () {
  214. return this.seconds();
  215. },
  216. S : function () {
  217. return toInt(this.milliseconds() / 100);
  218. },
  219. SS : function () {
  220. return leftZeroFill(toInt(this.milliseconds() / 10), 2);
  221. },
  222. SSS : function () {
  223. return leftZeroFill(this.milliseconds(), 3);
  224. },
  225. SSSS : function () {
  226. return leftZeroFill(this.milliseconds(), 3);
  227. },
  228. Z : function () {
  229. var a = this.utcOffset(),
  230. b = '+';
  231. if (a < 0) {
  232. a = -a;
  233. b = '-';
  234. }
  235. return b + leftZeroFill(toInt(a / 60), 2) + ':' + leftZeroFill(toInt(a) % 60, 2);
  236. },
  237. ZZ : function () {
  238. var a = this.utcOffset(),
  239. b = '+';
  240. if (a < 0) {
  241. a = -a;
  242. b = '-';
  243. }
  244. return b + leftZeroFill(toInt(a / 60), 2) + leftZeroFill(toInt(a) % 60, 2);
  245. },
  246. z : function () {
  247. return this.zoneAbbr();
  248. },
  249. zz : function () {
  250. return this.zoneName();
  251. },
  252. x : function () {
  253. return this.valueOf();
  254. },
  255. X : function () {
  256. return this.unix();
  257. },
  258. Q : function () {
  259. return this.quarter();
  260. }
  261. },
  262. deprecations = {},
  263. lists = ['months', 'monthsShort', 'weekdays', 'weekdaysShort', 'weekdaysMin'],
  264. updateInProgress = false;
  265. // Pick the first defined of two or three arguments. dfl comes from
  266. // default.
  267. function dfl(a, b, c) {
  268. switch (arguments.length) {
  269. case 2: return a != null ? a : b;
  270. case 3: return a != null ? a : b != null ? b : c;
  271. default: throw new Error('Implement me');
  272. }
  273. }
  274. function hasOwnProp(a, b) {
  275. return hasOwnProperty.call(a, b);
  276. }
  277. function defaultParsingFlags() {
  278. // We need to deep clone this object, and es5 standard is not very
  279. // helpful.
  280. return {
  281. empty : false,
  282. unusedTokens : [],
  283. unusedInput : [],
  284. overflow : -2,
  285. charsLeftOver : 0,
  286. nullInput : false,
  287. invalidMonth : null,
  288. invalidFormat : false,
  289. userInvalidated : false,
  290. iso: false
  291. };
  292. }
  293. function printMsg(msg) {
  294. if (moment.suppressDeprecationWarnings === false &&
  295. typeof console !== 'undefined' && console.warn) {
  296. console.warn('Deprecation warning: ' + msg);
  297. }
  298. }
  299. function deprecate(msg, fn) {
  300. var firstTime = true;
  301. return extend(function () {
  302. if (firstTime) {
  303. printMsg(msg);
  304. firstTime = false;
  305. }
  306. return fn.apply(this, arguments);
  307. }, fn);
  308. }
  309. function deprecateSimple(name, msg) {
  310. if (!deprecations[name]) {
  311. printMsg(msg);
  312. deprecations[name] = true;
  313. }
  314. }
  315. function padToken(func, count) {
  316. return function (a) {
  317. return leftZeroFill(func.call(this, a), count);
  318. };
  319. }
  320. function ordinalizeToken(func, period) {
  321. return function (a) {
  322. return this.localeData().ordinal(func.call(this, a), period);
  323. };
  324. }
  325. function monthDiff(a, b) {
  326. // difference in months
  327. var wholeMonthDiff = ((b.year() - a.year()) * 12) + (b.month() - a.month()),
  328. // b is in (anchor - 1 month, anchor + 1 month)
  329. anchor = a.clone().add(wholeMonthDiff, 'months'),
  330. anchor2, adjust;
  331. if (b - anchor < 0) {
  332. anchor2 = a.clone().add(wholeMonthDiff - 1, 'months');
  333. // linear across the month
  334. adjust = (b - anchor) / (anchor - anchor2);
  335. } else {
  336. anchor2 = a.clone().add(wholeMonthDiff + 1, 'months');
  337. // linear across the month
  338. adjust = (b - anchor) / (anchor2 - anchor);
  339. }
  340. return -(wholeMonthDiff + adjust);
  341. }
  342. while (ordinalizeTokens.length) {
  343. i = ordinalizeTokens.pop();
  344. formatTokenFunctions[i + 'o'] = ordinalizeToken(formatTokenFunctions[i], i);
  345. }
  346. while (paddedTokens.length) {
  347. i = paddedTokens.pop();
  348. formatTokenFunctions[i + i] = padToken(formatTokenFunctions[i], 2);
  349. }
  350. formatTokenFunctions.DDDD = padToken(formatTokenFunctions.DDD, 3);
  351. function meridiemFixWrap(locale, hour, meridiem) {
  352. var isPm;
  353. if (meridiem == null) {
  354. // nothing to do
  355. return hour;
  356. }
  357. if (locale.meridiemHour != null) {
  358. return locale.meridiemHour(hour, meridiem);
  359. } else if (locale.isPM != null) {
  360. // Fallback
  361. isPm = locale.isPM(meridiem);
  362. if (isPm && hour < 12) {
  363. hour += 12;
  364. }
  365. if (!isPm && hour === 12) {
  366. hour = 0;
  367. }
  368. return hour;
  369. } else {
  370. // thie is not supposed to happen
  371. return hour;
  372. }
  373. }
  374. /************************************
  375. Constructors
  376. ************************************/
  377. function Locale() {
  378. }
  379. // Moment prototype object
  380. function Moment(config, skipOverflow) {
  381. if (skipOverflow !== false) {
  382. checkOverflow(config);
  383. }
  384. copyConfig(this, config);
  385. this._d = new Date(+config._d);
  386. // Prevent infinite loop in case updateOffset creates new moment
  387. // objects.
  388. if (updateInProgress === false) {
  389. updateInProgress = true;
  390. moment.updateOffset(this);
  391. updateInProgress = false;
  392. }
  393. }
  394. // Duration Constructor
  395. function Duration(duration) {
  396. var normalizedInput = normalizeObjectUnits(duration),
  397. years = normalizedInput.year || 0,
  398. quarters = normalizedInput.quarter || 0,
  399. months = normalizedInput.month || 0,
  400. weeks = normalizedInput.week || 0,
  401. days = normalizedInput.day || 0,
  402. hours = normalizedInput.hour || 0,
  403. minutes = normalizedInput.minute || 0,
  404. seconds = normalizedInput.second || 0,
  405. milliseconds = normalizedInput.millisecond || 0;
  406. // representation for dateAddRemove
  407. this._milliseconds = +milliseconds +
  408. seconds * 1e3 + // 1000
  409. minutes * 6e4 + // 1000 * 60
  410. hours * 36e5; // 1000 * 60 * 60
  411. // Because of dateAddRemove treats 24 hours as different from a
  412. // day when working around DST, we need to store them separately
  413. this._days = +days +
  414. weeks * 7;
  415. // It is impossible translate months into days without knowing
  416. // which months you are are talking about, so we have to store
  417. // it separately.
  418. this._months = +months +
  419. quarters * 3 +
  420. years * 12;
  421. this._data = {};
  422. this._locale = moment.localeData();
  423. this._bubble();
  424. }
  425. /************************************
  426. Helpers
  427. ************************************/
  428. function extend(a, b) {
  429. for (var i in b) {
  430. if (hasOwnProp(b, i)) {
  431. a[i] = b[i];
  432. }
  433. }
  434. if (hasOwnProp(b, 'toString')) {
  435. a.toString = b.toString;
  436. }
  437. if (hasOwnProp(b, 'valueOf')) {
  438. a.valueOf = b.valueOf;
  439. }
  440. return a;
  441. }
  442. function copyConfig(to, from) {
  443. var i, prop, val;
  444. if (typeof from._isAMomentObject !== 'undefined') {
  445. to._isAMomentObject = from._isAMomentObject;
  446. }
  447. if (typeof from._i !== 'undefined') {
  448. to._i = from._i;
  449. }
  450. if (typeof from._f !== 'undefined') {
  451. to._f = from._f;
  452. }
  453. if (typeof from._l !== 'undefined') {
  454. to._l = from._l;
  455. }
  456. if (typeof from._strict !== 'undefined') {
  457. to._strict = from._strict;
  458. }
  459. if (typeof from._tzm !== 'undefined') {
  460. to._tzm = from._tzm;
  461. }
  462. if (typeof from._isUTC !== 'undefined') {
  463. to._isUTC = from._isUTC;
  464. }
  465. if (typeof from._offset !== 'undefined') {
  466. to._offset = from._offset;
  467. }
  468. if (typeof from._pf !== 'undefined') {
  469. to._pf = from._pf;
  470. }
  471. if (typeof from._locale !== 'undefined') {
  472. to._locale = from._locale;
  473. }
  474. if (momentProperties.length > 0) {
  475. for (i in momentProperties) {
  476. prop = momentProperties[i];
  477. val = from[prop];
  478. if (typeof val !== 'undefined') {
  479. to[prop] = val;
  480. }
  481. }
  482. }
  483. return to;
  484. }
  485. function absRound(number) {
  486. if (number < 0) {
  487. return Math.ceil(number);
  488. } else {
  489. return Math.floor(number);
  490. }
  491. }
  492. // left zero fill a number
  493. // see http://jsperf.com/left-zero-filling for performance comparison
  494. function leftZeroFill(number, targetLength, forceSign) {
  495. var output = '' + Math.abs(number),
  496. sign = number >= 0;
  497. while (output.length < targetLength) {
  498. output = '0' + output;
  499. }
  500. return (sign ? (forceSign ? '+' : '') : '-') + output;
  501. }
  502. function positiveMomentsDifference(base, other) {
  503. var res = {milliseconds: 0, months: 0};
  504. res.months = other.month() - base.month() +
  505. (other.year() - base.year()) * 12;
  506. if (base.clone().add(res.months, 'M').isAfter(other)) {
  507. --res.months;
  508. }
  509. res.milliseconds = +other - +(base.clone().add(res.months, 'M'));
  510. return res;
  511. }
  512. function momentsDifference(base, other) {
  513. var res;
  514. other = makeAs(other, base);
  515. if (base.isBefore(other)) {
  516. res = positiveMomentsDifference(base, other);
  517. } else {
  518. res = positiveMomentsDifference(other, base);
  519. res.milliseconds = -res.milliseconds;
  520. res.months = -res.months;
  521. }
  522. return res;
  523. }
  524. // TODO: remove 'name' arg after deprecation is removed
  525. function createAdder(direction, name) {
  526. return function (val, period) {
  527. var dur, tmp;
  528. //invert the arguments, but complain about it
  529. if (period !== null && !isNaN(+period)) {
  530. deprecateSimple(name, 'moment().' + name + '(period, number) is deprecated. Please use moment().' + name + '(number, period).');
  531. tmp = val; val = period; period = tmp;
  532. }
  533. val = typeof val === 'string' ? +val : val;
  534. dur = moment.duration(val, period);
  535. addOrSubtractDurationFromMoment(this, dur, direction);
  536. return this;
  537. };
  538. }
  539. function addOrSubtractDurationFromMoment(mom, duration, isAdding, updateOffset) {
  540. var milliseconds = duration._milliseconds,
  541. days = duration._days,
  542. months = duration._months;
  543. updateOffset = updateOffset == null ? true : updateOffset;
  544. if (milliseconds) {
  545. mom._d.setTime(+mom._d + milliseconds * isAdding);
  546. }
  547. if (days) {
  548. rawSetter(mom, 'Date', rawGetter(mom, 'Date') + days * isAdding);
  549. }
  550. if (months) {
  551. rawMonthSetter(mom, rawGetter(mom, 'Month') + months * isAdding);
  552. }
  553. if (updateOffset) {
  554. moment.updateOffset(mom, days || months);
  555. }
  556. }
  557. // check if is an array
  558. function isArray(input) {
  559. return Object.prototype.toString.call(input) === '[object Array]';
  560. }
  561. function isDate(input) {
  562. return Object.prototype.toString.call(input) === '[object Date]' ||
  563. input instanceof Date;
  564. }
  565. // compare two arrays, return the number of differences
  566. function compareArrays(array1, array2, dontConvert) {
  567. var len = Math.min(array1.length, array2.length),
  568. lengthDiff = Math.abs(array1.length - array2.length),
  569. diffs = 0,
  570. i;
  571. for (i = 0; i < len; i++) {
  572. if ((dontConvert && array1[i] !== array2[i]) ||
  573. (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) {
  574. diffs++;
  575. }
  576. }
  577. return diffs + lengthDiff;
  578. }
  579. function normalizeUnits(units) {
  580. if (units) {
  581. var lowered = units.toLowerCase().replace(/(.)s$/, '$1');
  582. units = unitAliases[units] || camelFunctions[lowered] || lowered;
  583. }
  584. return units;
  585. }
  586. function normalizeObjectUnits(inputObject) {
  587. var normalizedInput = {},
  588. normalizedProp,
  589. prop;
  590. for (prop in inputObject) {
  591. if (hasOwnProp(inputObject, prop)) {
  592. normalizedProp = normalizeUnits(prop);
  593. if (normalizedProp) {
  594. normalizedInput[normalizedProp] = inputObject[prop];
  595. }
  596. }
  597. }
  598. return normalizedInput;
  599. }
  600. function makeList(field) {
  601. var count, setter;
  602. if (field.indexOf('week') === 0) {
  603. count = 7;
  604. setter = 'day';
  605. }
  606. else if (field.indexOf('month') === 0) {
  607. count = 12;
  608. setter = 'month';
  609. }
  610. else {
  611. return;
  612. }
  613. moment[field] = function (format, index) {
  614. var i, getter,
  615. method = moment._locale[field],
  616. results = [];
  617. if (typeof format === 'number') {
  618. index = format;
  619. format = undefined;
  620. }
  621. getter = function (i) {
  622. var m = moment().utc().set(setter, i);
  623. return method.call(moment._locale, m, format || '');
  624. };
  625. if (index != null) {
  626. return getter(index);
  627. }
  628. else {
  629. for (i = 0; i < count; i++) {
  630. results.push(getter(i));
  631. }
  632. return results;
  633. }
  634. };
  635. }
  636. function toInt(argumentForCoercion) {
  637. var coercedNumber = +argumentForCoercion,
  638. value = 0;
  639. if (coercedNumber !== 0 && isFinite(coercedNumber)) {
  640. if (coercedNumber >= 0) {
  641. value = Math.floor(coercedNumber);
  642. } else {
  643. value = Math.ceil(coercedNumber);
  644. }
  645. }
  646. return value;
  647. }
  648. function daysInMonth(year, month) {
  649. return new Date(Date.UTC(year, month + 1, 0)).getUTCDate();
  650. }
  651. function weeksInYear(year, dow, doy) {
  652. return weekOfYear(moment([year, 11, 31 + dow - doy]), dow, doy).week;
  653. }
  654. function daysInYear(year) {
  655. return isLeapYear(year) ? 366 : 365;
  656. }
  657. function isLeapYear(year) {
  658. return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
  659. }
  660. function checkOverflow(m) {
  661. var overflow;
  662. if (m._a && m._pf.overflow === -2) {
  663. overflow =
  664. m._a[MONTH] < 0 || m._a[MONTH] > 11 ? MONTH :
  665. m._a[DATE] < 1 || m._a[DATE] > daysInMonth(m._a[YEAR], m._a[MONTH]) ? DATE :
  666. m._a[HOUR] < 0 || m._a[HOUR] > 24 ||
  667. (m._a[HOUR] === 24 && (m._a[MINUTE] !== 0 ||
  668. m._a[SECOND] !== 0 ||
  669. m._a[MILLISECOND] !== 0)) ? HOUR :
  670. m._a[MINUTE] < 0 || m._a[MINUTE] > 59 ? MINUTE :
  671. m._a[SECOND] < 0 || m._a[SECOND] > 59 ? SECOND :
  672. m._a[MILLISECOND] < 0 || m._a[MILLISECOND] > 999 ? MILLISECOND :
  673. -1;
  674. if (m._pf._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) {
  675. overflow = DATE;
  676. }
  677. m._pf.overflow = overflow;
  678. }
  679. }
  680. function isValid(m) {
  681. if (m._isValid == null) {
  682. m._isValid = !isNaN(m._d.getTime()) &&
  683. m._pf.overflow < 0 &&
  684. !m._pf.empty &&
  685. !m._pf.invalidMonth &&
  686. !m._pf.nullInput &&
  687. !m._pf.invalidFormat &&
  688. !m._pf.userInvalidated;
  689. if (m._strict) {
  690. m._isValid = m._isValid &&
  691. m._pf.charsLeftOver === 0 &&
  692. m._pf.unusedTokens.length === 0 &&
  693. m._pf.bigHour === undefined;
  694. }
  695. }
  696. return m._isValid;
  697. }
  698. function normalizeLocale(key) {
  699. return key ? key.toLowerCase().replace('_', '-') : key;
  700. }
  701. // pick the locale from the array
  702. // try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each
  703. // substring from most specific to least, but move to the next array item if it's a more specific variant than the current root
  704. function chooseLocale(names) {
  705. var i = 0, j, next, locale, split;
  706. while (i < names.length) {
  707. split = normalizeLocale(names[i]).split('-');
  708. j = split.length;
  709. next = normalizeLocale(names[i + 1]);
  710. next = next ? next.split('-') : null;
  711. while (j > 0) {
  712. locale = loadLocale(split.slice(0, j).join('-'));
  713. if (locale) {
  714. return locale;
  715. }
  716. if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {
  717. //the next array item is better than a shallower substring of this one
  718. break;
  719. }
  720. j--;
  721. }
  722. i++;
  723. }
  724. return null;
  725. }
  726. function loadLocale(name) {
  727. var oldLocale = null;
  728. if (!locales[name] && hasModule) {
  729. try {
  730. oldLocale = moment.locale();
  731. require('./locale/' + name);
  732. // because defineLocale currently also sets the global locale, we want to undo that for lazy loaded locales
  733. moment.locale(oldLocale);
  734. } catch (e) { }
  735. }
  736. return locales[name];
  737. }
  738. // Return a moment from input, that is local/utc/utcOffset equivalent to
  739. // model.
  740. function makeAs(input, model) {
  741. var res, diff;
  742. if (model._isUTC) {
  743. res = model.clone();
  744. diff = (moment.isMoment(input) || isDate(input) ?
  745. +input : +moment(input)) - (+res);
  746. // Use low-level api, because this fn is low-level api.
  747. res._d.setTime(+res._d + diff);
  748. moment.updateOffset(res, false);
  749. return res;
  750. } else {
  751. return moment(input).local();
  752. }
  753. }
  754. /************************************
  755. Locale
  756. ************************************/
  757. extend(Locale.prototype, {
  758. set : function (config) {
  759. var prop, i;
  760. for (i in config) {
  761. prop = config[i];
  762. if (typeof prop === 'function') {
  763. this[i] = prop;
  764. } else {
  765. this['_' + i] = prop;
  766. }
  767. }
  768. // Lenient ordinal parsing accepts just a number in addition to
  769. // number + (possibly) stuff coming from _ordinalParseLenient.
  770. this._ordinalParseLenient = new RegExp(this._ordinalParse.source + '|' + /\d{1,2}/.source);
  771. },
  772. _months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),
  773. months : function (m) {
  774. return this._months[m.month()];
  775. },
  776. _monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),
  777. monthsShort : function (m) {
  778. return this._monthsShort[m.month()];
  779. },
  780. monthsParse : function (monthName, format, strict) {
  781. var i, mom, regex;
  782. if (!this._monthsParse) {
  783. this._monthsParse = [];
  784. this._longMonthsParse = [];
  785. this._shortMonthsParse = [];
  786. }
  787. for (i = 0; i < 12; i++) {
  788. // make the regex if we don't have it already
  789. mom = moment.utc([2000, i]);
  790. if (strict && !this._longMonthsParse[i]) {
  791. this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i');
  792. this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i');
  793. }
  794. if (!strict && !this._monthsParse[i]) {
  795. regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');
  796. this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');
  797. }
  798. // test the regex
  799. if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) {
  800. return i;
  801. } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) {
  802. return i;
  803. } else if (!strict && this._monthsParse[i].test(monthName)) {
  804. return i;
  805. }
  806. }
  807. },
  808. _weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),
  809. weekdays : function (m) {
  810. return this._weekdays[m.day()];
  811. },
  812. _weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
  813. weekdaysShort : function (m) {
  814. return this._weekdaysShort[m.day()];
  815. },
  816. _weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
  817. weekdaysMin : function (m) {
  818. return this._weekdaysMin[m.day()];
  819. },
  820. weekdaysParse : function (weekdayName) {
  821. var i, mom, regex;
  822. if (!this._weekdaysParse) {
  823. this._weekdaysParse = [];
  824. }
  825. for (i = 0; i < 7; i++) {
  826. // make the regex if we don't have it already
  827. if (!this._weekdaysParse[i]) {
  828. mom = moment([2000, 1]).day(i);
  829. regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, '');
  830. this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');
  831. }
  832. // test the regex
  833. if (this._weekdaysParse[i].test(weekdayName)) {
  834. return i;
  835. }
  836. }
  837. },
  838. _longDateFormat : {
  839. LTS : 'h:mm:ss A',
  840. LT : 'h:mm A',
  841. L : 'MM/DD/YYYY',
  842. LL : 'MMMM D, YYYY',
  843. LLL : 'MMMM D, YYYY LT',
  844. LLLL : 'dddd, MMMM D, YYYY LT'
  845. },
  846. longDateFormat : function (key) {
  847. var output = this._longDateFormat[key];
  848. if (!output && this._longDateFormat[key.toUpperCase()]) {
  849. output = this._longDateFormat[key.toUpperCase()].replace(/MMMM|MM|DD|dddd/g, function (val) {
  850. return val.slice(1);
  851. });
  852. this._longDateFormat[key] = output;
  853. }
  854. return output;
  855. },
  856. isPM : function (input) {
  857. // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays
  858. // Using charAt should be more compatible.
  859. return ((input + '').toLowerCase().charAt(0) === 'p');
  860. },
  861. _meridiemParse : /[ap]\.?m?\.?/i,
  862. meridiem : function (hours, minutes, isLower) {
  863. if (hours > 11) {
  864. return isLower ? 'pm' : 'PM';
  865. } else {
  866. return isLower ? 'am' : 'AM';
  867. }
  868. },
  869. _calendar : {
  870. sameDay : '[Today at] LT',
  871. nextDay : '[Tomorrow at] LT',
  872. nextWeek : 'dddd [at] LT',
  873. lastDay : '[Yesterday at] LT',
  874. lastWeek : '[Last] dddd [at] LT',
  875. sameElse : 'L'
  876. },
  877. calendar : function (key, mom, now) {
  878. var output = this._calendar[key];
  879. return typeof output === 'function' ? output.apply(mom, [now]) : output;
  880. },
  881. _relativeTime : {
  882. future : 'in %s',
  883. past : '%s ago',
  884. s : 'a few seconds',
  885. m : 'a minute',
  886. mm : '%d minutes',
  887. h : 'an hour',
  888. hh : '%d hours',
  889. d : 'a day',
  890. dd : '%d days',
  891. M : 'a month',
  892. MM : '%d months',
  893. y : 'a year',
  894. yy : '%d years'
  895. },
  896. relativeTime : function (number, withoutSuffix, string, isFuture) {
  897. var output = this._relativeTime[string];
  898. return (typeof output === 'function') ?
  899. output(number, withoutSuffix, string, isFuture) :
  900. output.replace(/%d/i, number);
  901. },
  902. pastFuture : function (diff, output) {
  903. var format = this._relativeTime[diff > 0 ? 'future' : 'past'];
  904. return typeof format === 'function' ? format(output) : format.replace(/%s/i, output);
  905. },
  906. ordinal : function (number) {
  907. return this._ordinal.replace('%d', number);
  908. },
  909. _ordinal : '%d',
  910. _ordinalParse : /\d{1,2}/,
  911. preparse : function (string) {
  912. return string;
  913. },
  914. postformat : function (string) {
  915. return string;
  916. },
  917. week : function (mom) {
  918. return weekOfYear(mom, this._week.dow, this._week.doy).week;
  919. },
  920. _week : {
  921. dow : 0, // Sunday is the first day of the week.
  922. doy : 6 // The week that contains Jan 1st is the first week of the year.
  923. },
  924. firstDayOfWeek : function () {
  925. return this._week.dow;
  926. },
  927. firstDayOfYear : function () {
  928. return this._week.doy;
  929. },
  930. _invalidDate: 'Invalid date',
  931. invalidDate: function () {
  932. return this._invalidDate;
  933. }
  934. });
  935. /************************************
  936. Formatting
  937. ************************************/
  938. function removeFormattingTokens(input) {
  939. if (input.match(/\[[\s\S]/)) {
  940. return input.replace(/^\[|\]$/g, '');
  941. }
  942. return input.replace(/\\/g, '');
  943. }
  944. function makeFormatFunction(format) {
  945. var array = format.match(formattingTokens), i, length;
  946. for (i = 0, length = array.length; i < length; i++) {
  947. if (formatTokenFunctions[array[i]]) {
  948. array[i] = formatTokenFunctions[array[i]];
  949. } else {
  950. array[i] = removeFormattingTokens(array[i]);
  951. }
  952. }
  953. return function (mom) {
  954. var output = '';
  955. for (i = 0; i < length; i++) {
  956. output += array[i] instanceof Function ? array[i].call(mom, format) : array[i];
  957. }
  958. return output;
  959. };
  960. }
  961. // format date using native date object
  962. function formatMoment(m, format) {
  963. if (!m.isValid()) {
  964. return m.localeData().invalidDate();
  965. }
  966. format = expandFormat(format, m.localeData());
  967. if (!formatFunctions[format]) {
  968. formatFunctions[format] = makeFormatFunction(format);
  969. }
  970. return formatFunctions[format](m);
  971. }
  972. function expandFormat(format, locale) {
  973. var i = 5;
  974. function replaceLongDateFormatTokens(input) {
  975. return locale.longDateFormat(input) || input;
  976. }
  977. localFormattingTokens.lastIndex = 0;
  978. while (i >= 0 && localFormattingTokens.test(format)) {
  979. format = format.replace(localFormattingTokens, replaceLongDateFormatTokens);
  980. localFormattingTokens.lastIndex = 0;
  981. i -= 1;
  982. }
  983. return format;
  984. }
  985. /************************************
  986. Parsing
  987. ************************************/
  988. // get the regex to find the next token
  989. function getParseRegexForToken(token, config) {
  990. var a, strict = config._strict;
  991. switch (token) {
  992. case 'Q':
  993. return parseTokenOneDigit;
  994. case 'DDDD':
  995. return parseTokenThreeDigits;
  996. case 'YYYY':
  997. case 'GGGG':
  998. case 'gggg':
  999. return strict ? parseTokenFourDigits : parseTokenOneToFourDigits;
  1000. case 'Y':
  1001. case 'G':
  1002. case 'g':
  1003. return parseTokenSignedNumber;
  1004. case 'YYYYYY':
  1005. case 'YYYYY':
  1006. case 'GGGGG':
  1007. case 'ggggg':
  1008. return strict ? parseTokenSixDigits : parseTokenOneToSixDigits;
  1009. case 'S':
  1010. if (strict) {
  1011. return parseTokenOneDigit;
  1012. }
  1013. /* falls through */
  1014. case 'SS':
  1015. if (strict) {
  1016. return parseTokenTwoDigits;
  1017. }
  1018. /* falls through */
  1019. case 'SSS':
  1020. if (strict) {
  1021. return parseTokenThreeDigits;
  1022. }
  1023. /* falls through */
  1024. case 'DDD':
  1025. return parseTokenOneToThreeDigits;
  1026. case 'MMM':
  1027. case 'MMMM':
  1028. case 'dd':
  1029. case 'ddd':
  1030. case 'dddd':
  1031. return parseTokenWord;
  1032. case 'a':
  1033. case 'A':
  1034. return config._locale._meridiemParse;
  1035. case 'x':
  1036. return parseTokenOffsetMs;
  1037. case 'X':
  1038. return parseTokenTimestampMs;
  1039. case 'Z':
  1040. case 'ZZ':
  1041. return parseTokenTimezone;
  1042. case 'T':
  1043. return parseTokenT;
  1044. case 'SSSS':
  1045. return parseTokenDigits;
  1046. case 'MM':
  1047. case 'DD':
  1048. case 'YY':
  1049. case 'GG':
  1050. case 'gg':
  1051. case 'HH':
  1052. case 'hh':
  1053. case 'mm':
  1054. case 'ss':
  1055. case 'ww':
  1056. case 'WW':
  1057. return strict ? parseTokenTwoDigits : parseTokenOneOrTwoDigits;
  1058. case 'M':
  1059. case 'D':
  1060. case 'd':
  1061. case 'H':
  1062. case 'h':
  1063. case 'm':
  1064. case 's':
  1065. case 'w':
  1066. case 'W':
  1067. case 'e':
  1068. case 'E':
  1069. return parseTokenOneOrTwoDigits;
  1070. case 'Do':
  1071. return strict ? config._locale._ordinalParse : config._locale._ordinalParseLenient;
  1072. default :
  1073. a = new RegExp(regexpEscape(unescapeFormat(token.replace('\\', '')), 'i'));
  1074. return a;
  1075. }
  1076. }
  1077. function utcOffsetFromString(string) {
  1078. string = string || '';
  1079. var possibleTzMatches = (string.match(parseTokenTimezone) || []),
  1080. tzChunk = possibleTzMatches[possibleTzMatches.length - 1] || [],
  1081. parts = (tzChunk + '').match(parseTimezoneChunker) || ['-', 0, 0],
  1082. minutes = +(parts[1] * 60) + toInt(parts[2]);
  1083. return parts[0] === '+' ? minutes : -minutes;
  1084. }
  1085. // function to convert string input to date
  1086. function addTimeToArrayFromToken(token, input, config) {
  1087. var a, datePartArray = config._a;
  1088. switch (token) {
  1089. // QUARTER
  1090. case 'Q':
  1091. if (input != null) {
  1092. datePartArray[MONTH] = (toInt(input) - 1) * 3;
  1093. }
  1094. break;
  1095. // MONTH
  1096. case 'M' : // fall through to MM
  1097. case 'MM' :
  1098. if (input != null) {
  1099. datePartArray[MONTH] = toInt(input) - 1;
  1100. }
  1101. break;
  1102. case 'MMM' : // fall through to MMMM
  1103. case 'MMMM' :
  1104. a = config._locale.monthsParse(input, token, config._strict);
  1105. // if we didn't find a month name, mark the date as invalid.
  1106. if (a != null) {
  1107. datePartArray[MONTH] = a;
  1108. } else {
  1109. config._pf.invalidMonth = input;
  1110. }
  1111. break;
  1112. // DAY OF MONTH
  1113. case 'D' : // fall through to DD
  1114. case 'DD' :
  1115. if (input != null) {
  1116. datePartArray[DATE] = toInt(input);
  1117. }
  1118. break;
  1119. case 'Do' :
  1120. if (input != null) {
  1121. datePartArray[DATE] = toInt(parseInt(
  1122. input.match(/\d{1,2}/)[0], 10));
  1123. }
  1124. break;
  1125. // DAY OF YEAR
  1126. case 'DDD' : // fall through to DDDD
  1127. case 'DDDD' :
  1128. if (input != null) {
  1129. config._dayOfYear = toInt(input);
  1130. }
  1131. break;
  1132. // YEAR
  1133. case 'YY' :
  1134. datePartArray[YEAR] = moment.parseTwoDigitYear(input);
  1135. break;
  1136. case 'YYYY' :
  1137. case 'YYYYY' :
  1138. case 'YYYYYY' :
  1139. datePartArray[YEAR] = toInt(input);
  1140. break;
  1141. // AM / PM
  1142. case 'a' : // fall through to A
  1143. case 'A' :
  1144. config._meridiem = input;
  1145. // config._isPm = config._locale.isPM(input);
  1146. break;
  1147. // HOUR
  1148. case 'h' : // fall through to hh
  1149. case 'hh' :
  1150. config._pf.bigHour = true;
  1151. /* falls through */
  1152. case 'H' : // fall through to HH
  1153. case 'HH' :
  1154. datePartArray[HOUR] = toInt(input);
  1155. break;
  1156. // MINUTE
  1157. case 'm' : // fall through to mm
  1158. case 'mm' :
  1159. datePartArray[MINUTE] = toInt(input);
  1160. break;
  1161. // SECOND
  1162. case 's' : // fall through to ss
  1163. case 'ss' :
  1164. datePartArray[SECOND] = toInt(input);
  1165. break;
  1166. // MILLISECOND
  1167. case 'S' :
  1168. case 'SS' :
  1169. case 'SSS' :
  1170. case 'SSSS' :
  1171. datePartArray[MILLISECOND] = toInt(('0.' + input) * 1000);
  1172. break;
  1173. // UNIX OFFSET (MILLISECONDS)
  1174. case 'x':
  1175. config._d = new Date(toInt(input));
  1176. break;
  1177. // UNIX TIMESTAMP WITH MS
  1178. case 'X':
  1179. config._d = new Date(parseFloat(input) * 1000);
  1180. break;
  1181. // TIMEZONE
  1182. case 'Z' : // fall through to ZZ
  1183. case 'ZZ' :
  1184. config._useUTC = true;
  1185. config._tzm = utcOffsetFromString(input);
  1186. break;
  1187. // WEEKDAY - human
  1188. case 'dd':
  1189. case 'ddd':
  1190. case 'dddd':
  1191. a = config._locale.weekdaysParse(input);
  1192. // if we didn't get a weekday name, mark the date as invalid
  1193. if (a != null) {
  1194. config._w = config._w || {};
  1195. config._w['d'] = a;
  1196. } else {
  1197. config._pf.invalidWeekday = input;
  1198. }
  1199. break;
  1200. // WEEK, WEEK DAY - numeric
  1201. case 'w':
  1202. case 'ww':
  1203. case 'W':
  1204. case 'WW':
  1205. case 'd':
  1206. case 'e':
  1207. case 'E':
  1208. token = token.substr(0, 1);
  1209. /* falls through */
  1210. case 'gggg':
  1211. case 'GGGG':
  1212. case 'GGGGG':
  1213. token = token.substr(0, 2);
  1214. if (input) {
  1215. config._w = config._w || {};
  1216. config._w[token] = toInt(input);
  1217. }
  1218. break;
  1219. case 'gg':
  1220. case 'GG':
  1221. config._w = config._w || {};
  1222. config._w[token] = moment.parseTwoDigitYear(input);
  1223. }
  1224. }
  1225. function dayOfYearFromWeekInfo(config) {
  1226. var w, weekYear, week, weekday, dow, doy, temp;
  1227. w = config._w;
  1228. if (w.GG != null || w.W != null || w.E != null) {
  1229. dow = 1;
  1230. doy = 4;
  1231. // TODO: We need to take the current isoWeekYear, but that depends on
  1232. // how we interpret now (local, utc, fixed offset). So create
  1233. // a now version of current config (take local/utc/offset flags, and
  1234. // create now).
  1235. weekYear = dfl(w.GG, config._a[YEAR], weekOfYear(moment(), 1, 4).year);
  1236. week = dfl(w.W, 1);
  1237. weekday = dfl(w.E, 1);
  1238. } else {
  1239. dow = config._locale._week.dow;
  1240. doy = config._locale._week.doy;
  1241. weekYear = dfl(w.gg, config._a[YEAR], weekOfYear(moment(), dow, doy).year);
  1242. week = dfl(w.w, 1);
  1243. if (w.d != null) {
  1244. // weekday -- low day numbers are considered next week
  1245. weekday = w.d;
  1246. if (weekday < dow) {
  1247. ++week;
  1248. }
  1249. } else if (w.e != null) {
  1250. // local weekday -- counting starts from begining of week
  1251. weekday = w.e + dow;
  1252. } else {
  1253. // default to begining of week
  1254. weekday = dow;
  1255. }
  1256. }
  1257. temp = dayOfYearFromWeeks(weekYear, week, weekday, doy, dow);
  1258. config._a[YEAR] = temp.year;
  1259. config._dayOfYear = temp.dayOfYear;
  1260. }
  1261. // convert an array to a date.
  1262. // the array should mirror the parameters below
  1263. // note: all values past the year are optional and will default to the lowest possible value.
  1264. // [year, month, day , hour, minute, second, millisecond]
  1265. function dateFromConfig(config) {
  1266. var i, date, input = [], currentDate, yearToUse;
  1267. if (config._d) {
  1268. return;
  1269. }
  1270. currentDate = currentDateArray(config);
  1271. //compute day of the year from weeks and weekdays
  1272. if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {
  1273. dayOfYearFromWeekInfo(config);
  1274. }
  1275. //if the day of the year is set, figure out what it is
  1276. if (config._dayOfYear) {
  1277. yearToUse = dfl(config._a[YEAR], currentDate[YEAR]);
  1278. if (config._dayOfYear > daysInYear(yearToUse)) {
  1279. config._pf._overflowDayOfYear = true;
  1280. }
  1281. date = makeUTCDate(yearToUse, 0, config._dayOfYear);
  1282. config._a[MONTH] = date.getUTCMonth();
  1283. config._a[DATE] = date.getUTCDate();
  1284. }
  1285. // Default to current date.
  1286. // * if no year, month, day of month are given, default to today
  1287. // * if day of month is given, default month and year
  1288. // * if month is given, default only year
  1289. // * if year is given, don't default anything
  1290. for (i = 0; i < 3 && config._a[i] == null; ++i) {
  1291. config._a[i] = input[i] = currentDate[i];
  1292. }
  1293. // Zero out whatever was not defaulted, including time
  1294. for (; i < 7; i++) {
  1295. config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i];
  1296. }
  1297. // Check for 24:00:00.000
  1298. if (config._a[HOUR] === 24 &&
  1299. config._a[MINUTE] === 0 &&
  1300. config._a[SECOND] === 0 &&
  1301. config._a[MILLISECOND] === 0) {
  1302. config._nextDay = true;
  1303. config._a[HOUR] = 0;
  1304. }
  1305. config._d = (config._useUTC ? makeUTCDate : makeDate).apply(null, input);
  1306. // Apply timezone offset from input. The actual utcOffset can be changed
  1307. // with parseZone.
  1308. if (config._tzm != null) {
  1309. config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);
  1310. }
  1311. if (config._nextDay) {
  1312. config._a[HOUR] = 24;
  1313. }
  1314. }
  1315. function dateFromObject(config) {
  1316. var normalizedInput;
  1317. if (config._d) {
  1318. return;
  1319. }
  1320. normalizedInput = normalizeObjectUnits(config._i);
  1321. config._a = [
  1322. normalizedInput.year,
  1323. normalizedInput.month,
  1324. normalizedInput.day || normalizedInput.date,
  1325. normalizedInput.hour,
  1326. normalizedInput.minute,
  1327. normalizedInput.second,
  1328. normalizedInput.millisecond
  1329. ];
  1330. dateFromConfig(config);
  1331. }
  1332. function currentDateArray(config) {
  1333. var now = new Date();
  1334. if (config._useUTC) {
  1335. return [
  1336. now.getUTCFullYear(),
  1337. now.getUTCMonth(),
  1338. now.getUTCDate()
  1339. ];
  1340. } else {
  1341. return [now.getFullYear(), now.getMonth(), now.getDate()];
  1342. }
  1343. }
  1344. // date from string and format string
  1345. function makeDateFromStringAndFormat(config) {
  1346. if (config._f === moment.ISO_8601) {
  1347. parseISO(config);
  1348. return;
  1349. }
  1350. config._a = [];
  1351. config._pf.empty = true;
  1352. // This array is used to make a Date, either with `new Date` or `Date.UTC`
  1353. var string = '' + config._i,
  1354. i, parsedInput, tokens, token, skipped,
  1355. stringLength = string.length,
  1356. totalParsedInputLength = 0;
  1357. tokens = expandFormat(config._f, config._locale).match(formattingTokens) || [];
  1358. for (i = 0; i < tokens.length; i++) {
  1359. token = tokens[i];
  1360. parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0];
  1361. if (parsedInput) {
  1362. skipped = string.substr(0, string.indexOf(parsedInput));
  1363. if (skipped.length > 0) {
  1364. config._pf.unusedInput.push(skipped);
  1365. }
  1366. string = string.slice(string.indexOf(parsedInput) + parsedInput.length);
  1367. totalParsedInputLength += parsedInput.length;
  1368. }
  1369. // don't parse if it's not a known token
  1370. if (formatTokenFunctions[token]) {
  1371. if (parsedInput) {
  1372. config._pf.empty = false;
  1373. }
  1374. else {
  1375. config._pf.unusedTokens.push(token);
  1376. }
  1377. addTimeToArrayFromToken(token, parsedInput, config);
  1378. }
  1379. else if (config._strict && !parsedInput) {
  1380. config._pf.unusedTokens.push(token);
  1381. }
  1382. }
  1383. // add remaining unparsed input length to the string
  1384. config._pf.charsLeftOver = stringLength - totalParsedInputLength;
  1385. if (string.length > 0) {
  1386. config._pf.unusedInput.push(string);
  1387. }
  1388. // clear _12h flag if hour is <= 12
  1389. if (config._pf.bigHour === true && config._a[HOUR] <= 12) {
  1390. config._pf.bigHour = undefined;
  1391. }
  1392. // handle meridiem
  1393. config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR],
  1394. config._meridiem);
  1395. dateFromConfig(config);
  1396. checkOverflow(config);
  1397. }
  1398. function unescapeFormat(s) {
  1399. return s.replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (matched, p1, p2, p3, p4) {
  1400. return p1 || p2 || p3 || p4;
  1401. });
  1402. }
  1403. // Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript
  1404. function regexpEscape(s) {
  1405. return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
  1406. }
  1407. // date from string and array of format strings
  1408. function makeDateFromStringAndArray(config) {
  1409. var tempConfig,
  1410. bestMoment,
  1411. scoreToBeat,
  1412. i,
  1413. currentScore;
  1414. if (config._f.length === 0) {
  1415. config._pf.invalidFormat = true;
  1416. config._d = new Date(NaN);
  1417. return;
  1418. }
  1419. for (i = 0; i < config._f.length; i++) {
  1420. currentScore = 0;
  1421. tempConfig = copyConfig({}, config);
  1422. if (config._useUTC != null) {
  1423. tempConfig._useUTC = config._useUTC;
  1424. }
  1425. tempConfig._pf = defaultParsingFlags();
  1426. tempConfig._f = config._f[i];
  1427. makeDateFromStringAndFormat(tempConfig);
  1428. if (!isValid(tempConfig)) {
  1429. continue;
  1430. }
  1431. // if there is any input that was not parsed add a penalty for that format
  1432. currentScore += tempConfig._pf.charsLeftOver;
  1433. //or tokens
  1434. currentScore += tempConfig._pf.unusedTokens.length * 10;
  1435. tempConfig._pf.score = currentScore;
  1436. if (scoreToBeat == null || currentScore < scoreToBeat) {
  1437. scoreToBeat = currentScore;
  1438. bestMoment = tempConfig;
  1439. }
  1440. }
  1441. extend(config, bestMoment || tempConfig);
  1442. }
  1443. // date from iso format
  1444. function parseISO(config) {
  1445. var i, l,
  1446. string = config._i,
  1447. match = isoRegex.exec(string);
  1448. if (match) {
  1449. config._pf.iso = true;
  1450. for (i = 0, l = isoDates.length; i < l; i++) {
  1451. if (isoDates[i][1].exec(string)) {
  1452. // match[5] should be 'T' or undefined
  1453. config._f = isoDates[i][0] + (match[6] || ' ');
  1454. break;
  1455. }
  1456. }
  1457. for (i = 0, l = isoTimes.length; i < l; i++) {
  1458. if (isoTimes[i][1].exec(string)) {
  1459. config._f += isoTimes[i][0];
  1460. break;
  1461. }
  1462. }
  1463. if (string.match(parseTokenTimezone)) {
  1464. config._f += 'Z';
  1465. }
  1466. makeDateFromStringAndFormat(config);
  1467. } else {
  1468. config._isValid = false;
  1469. }
  1470. }
  1471. // date from iso format or fallback
  1472. function makeDateFromString(config) {
  1473. parseISO(config);
  1474. if (config._isValid === false) {
  1475. delete config._isValid;
  1476. moment.createFromInputFallback(config);
  1477. }
  1478. }
  1479. function map(arr, fn) {
  1480. var res = [], i;
  1481. for (i = 0; i < arr.length; ++i) {
  1482. res.push(fn(arr[i], i));
  1483. }
  1484. return res;
  1485. }
  1486. function makeDateFromInput(config) {
  1487. var input = config._i, matched;
  1488. if (input === undefined) {
  1489. config._d = new Date();
  1490. } else if (isDate(input)) {
  1491. config._d = new Date(+input);
  1492. } else if ((matched = aspNetJsonRegex.exec(input)) !== null) {
  1493. config._d = new Date(+matched[1]);
  1494. } else if (typeof input === 'string') {
  1495. makeDateFromString(config);
  1496. } else if (isArray(input)) {
  1497. config._a = map(input.slice(0), function (obj) {
  1498. return parseInt(obj, 10);
  1499. });
  1500. dateFromConfig(config);
  1501. } else if (typeof(input) === 'object') {
  1502. dateFromObject(config);
  1503. } else if (typeof(input) === 'number') {
  1504. // from milliseconds
  1505. config._d = new Date(input);
  1506. } else {
  1507. moment.createFromInputFallback(config);
  1508. }
  1509. }
  1510. function makeDate(y, m, d, h, M, s, ms) {
  1511. //can't just apply() to create a date:
  1512. //http://stackoverflow.com/questions/181348/instantiating-a-javascript-object-by-calling-prototype-constructor-apply
  1513. var date = new Date(y, m, d, h, M, s, ms);
  1514. //the date constructor doesn't accept years < 1970
  1515. if (y < 1970) {
  1516. date.setFullYear(y);
  1517. }
  1518. return date;
  1519. }
  1520. function makeUTCDate(y) {
  1521. var date = new Date(Date.UTC.apply(null, arguments));
  1522. if (y < 1970) {
  1523. date.setUTCFullYear(y);
  1524. }
  1525. return date;
  1526. }
  1527. function parseWeekday(input, locale) {
  1528. if (typeof input === 'string') {
  1529. if (!isNaN(input)) {
  1530. input = parseInt(input, 10);
  1531. }
  1532. else {
  1533. input = locale.weekdaysParse(input);
  1534. if (typeof input !== 'number') {
  1535. return null;
  1536. }
  1537. }
  1538. }
  1539. return input;
  1540. }
  1541. /************************************
  1542. Relative Time
  1543. ************************************/
  1544. // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize
  1545. function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) {
  1546. return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture);
  1547. }
  1548. function relativeTime(posNegDuration, withoutSuffix, locale) {
  1549. var duration = moment.duration(posNegDuration).abs(),
  1550. seconds = round(duration.as('s')),
  1551. minutes = round(duration.as('m')),
  1552. hours = round(duration.as('h')),
  1553. days = round(duration.as('d')),
  1554. months = round(duration.as('M')),
  1555. years = round(duration.as('y')),
  1556. args = seconds < relativeTimeThresholds.s && ['s', seconds] ||
  1557. minutes === 1 && ['m'] ||
  1558. minutes < relativeTimeThresholds.m && ['mm', minutes] ||
  1559. hours === 1 && ['h'] ||
  1560. hours < relativeTimeThresholds.h && ['hh', hours] ||
  1561. days === 1 && ['d'] ||
  1562. days < relativeTimeThresholds.d && ['dd', days] ||
  1563. months === 1 && ['M'] ||
  1564. months < relativeTimeThresholds.M && ['MM', months] ||
  1565. years === 1 && ['y'] || ['yy', years];
  1566. args[2] = withoutSuffix;
  1567. args[3] = +posNegDuration > 0;
  1568. args[4] = locale;
  1569. return substituteTimeAgo.apply({}, args);
  1570. }
  1571. /************************************
  1572. Week of Year
  1573. ************************************/
  1574. // firstDayOfWeek 0 = sun, 6 = sat
  1575. // the day of the week that starts the week
  1576. // (usually sunday or monday)
  1577. // firstDayOfWeekOfYear 0 = sun, 6 = sat
  1578. // the first week is the week that contains the first
  1579. // of this day of the week
  1580. // (eg. ISO weeks use thursday (4))
  1581. function weekOfYear(mom, firstDayOfWeek, firstDayOfWeekOfYear) {
  1582. var end = firstDayOfWeekOfYear - firstDayOfWeek,
  1583. daysToDayOfWeek = firstDayOfWeekOfYear - mom.day(),
  1584. adjustedMoment;
  1585. if (daysToDayOfWeek > end) {
  1586. daysToDayOfWeek -= 7;
  1587. }
  1588. if (daysToDayOfWeek < end - 7) {
  1589. daysToDayOfWeek += 7;
  1590. }
  1591. adjustedMoment = moment(mom).add(daysToDayOfWeek, 'd');
  1592. return {
  1593. week: Math.ceil(adjustedMoment.dayOfYear() / 7),
  1594. year: adjustedMoment.year()
  1595. };
  1596. }
  1597. //http://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday
  1598. function dayOfYearFromWeeks(year, week, weekday, firstDayOfWeekOfYear, firstDayOfWeek) {
  1599. var d = makeUTCDate(year, 0, 1).getUTCDay(), daysToAdd, dayOfYear;
  1600. d = d === 0 ? 7 : d;
  1601. weekday = weekday != null ? weekday : firstDayOfWeek;
  1602. daysToAdd = firstDayOfWeek - d + (d > firstDayOfWeekOfYear ? 7 : 0) - (d < firstDayOfWeek ? 7 : 0);
  1603. dayOfYear = 7 * (week - 1) + (weekday - firstDayOfWeek) + daysToAdd + 1;
  1604. return {
  1605. year: dayOfYear > 0 ? year : year - 1,
  1606. dayOfYear: dayOfYear > 0 ? dayOfYear : daysInYear(year - 1) + dayOfYear
  1607. };
  1608. }
  1609. /************************************
  1610. Top Level Functions
  1611. ************************************/
  1612. function makeMoment(config) {
  1613. var input = config._i,
  1614. format = config._f,
  1615. res;
  1616. config._locale = config._locale || moment.localeData(config._l);
  1617. if (input === null || (format === undefined && input === '')) {
  1618. return moment.invalid({nullInput: true});
  1619. }
  1620. if (typeof input === 'string') {
  1621. config._i = input = config._locale.preparse(input);
  1622. }
  1623. if (moment.isMoment(input)) {
  1624. return new Moment(input, true);
  1625. } else if (format) {
  1626. if (isArray(format)) {
  1627. makeDateFromStringAndArray(config);
  1628. } else {
  1629. makeDateFromStringAndFormat(config);
  1630. }
  1631. } else {
  1632. makeDateFromInput(config);
  1633. }
  1634. res = new Moment(config);
  1635. if (res._nextDay) {
  1636. // Adding is smart enough around DST
  1637. res.add(1, 'd');
  1638. res._nextDay = undefined;
  1639. }
  1640. return res;
  1641. }
  1642. moment = function (input, format, locale, strict) {
  1643. var c;
  1644. if (typeof(locale) === 'boolean') {
  1645. strict = locale;
  1646. locale = undefined;
  1647. }
  1648. // object construction must be done this way.
  1649. // https://github.com/moment/moment/issues/1423
  1650. c = {};
  1651. c._isAMomentObject = true;
  1652. c._i = input;
  1653. c._f = format;
  1654. c._l = locale;
  1655. c._strict = strict;
  1656. c._isUTC = false;
  1657. c._pf = defaultParsingFlags();
  1658. return makeMoment(c);
  1659. };
  1660. moment.suppressDeprecationWarnings = false;
  1661. moment.createFromInputFallback = deprecate(
  1662. 'moment construction falls back to js Date. This is ' +
  1663. 'discouraged and will be removed in upcoming major ' +
  1664. 'release. Please refer to ' +
  1665. 'https://github.com/moment/moment/issues/1407 for more info.',
  1666. function (config) {
  1667. config._d = new Date(config._i + (config._useUTC ? ' UTC' : ''));
  1668. }
  1669. );
  1670. // Pick a moment m from moments so that m[fn](other) is true for all
  1671. // other. This relies on the function fn to be transitive.
  1672. //
  1673. // moments should either be an array of moment objects or an array, whose
  1674. // first element is an array of moment objects.
  1675. function pickBy(fn, moments) {
  1676. var res, i;
  1677. if (moments.length === 1 && isArray(moments[0])) {
  1678. moments = moments[0];
  1679. }
  1680. if (!moments.length) {
  1681. return moment();
  1682. }
  1683. res = moments[0];
  1684. for (i = 1; i < moments.length; ++i) {
  1685. if (moments[i][fn](res)) {
  1686. res = moments[i];
  1687. }
  1688. }
  1689. return res;
  1690. }
  1691. moment.min = function () {
  1692. var args = [].slice.call(arguments, 0);
  1693. return pickBy('isBefore', args);
  1694. };
  1695. moment.max = function () {
  1696. var args = [].slice.call(arguments, 0);
  1697. return pickBy('isAfter', args);
  1698. };
  1699. // creating with utc
  1700. moment.utc = function (input, format, locale, strict) {
  1701. var c;
  1702. if (typeof(locale) === 'boolean') {
  1703. strict = locale;
  1704. locale = undefined;
  1705. }
  1706. // object construction must be done this way.
  1707. // https://github.com/moment/moment/issues/1423
  1708. c = {};
  1709. c._isAMomentObject = true;
  1710. c._useUTC = true;
  1711. c._isUTC = true;
  1712. c._l = locale;
  1713. c._i = input;
  1714. c._f = format;
  1715. c._strict = strict;
  1716. c._pf = defaultParsingFlags();
  1717. return makeMoment(c).utc();
  1718. };
  1719. // creating with unix timestamp (in seconds)
  1720. moment.unix = function (input) {
  1721. return moment(input * 1000);
  1722. };
  1723. // duration
  1724. moment.duration = function (input, key) {
  1725. var duration = input,
  1726. // matching against regexp is expensive, do it on demand
  1727. match = null,
  1728. sign,
  1729. ret,
  1730. parseIso,
  1731. diffRes;
  1732. if (moment.isDuration(input)) {
  1733. duration = {
  1734. ms: input._milliseconds,
  1735. d: input._days,
  1736. M: input._months
  1737. };
  1738. } else if (typeof input === 'number') {
  1739. duration = {};
  1740. if (key) {
  1741. duration[key] = input;
  1742. } else {
  1743. duration.milliseconds = input;
  1744. }
  1745. } else if (!!(match = aspNetTimeSpanJsonRegex.exec(input))) {
  1746. sign = (match[1] === '-') ? -1 : 1;
  1747. duration = {
  1748. y: 0,
  1749. d: toInt(match[DATE]) * sign,
  1750. h: toInt(match[HOUR]) * sign,
  1751. m: toInt(match[MINUTE]) * sign,
  1752. s: toInt(match[SECOND]) * sign,
  1753. ms: toInt(match[MILLISECOND]) * sign
  1754. };
  1755. } else if (!!(match = isoDurationRegex.exec(input))) {
  1756. sign = (match[1] === '-') ? -1 : 1;
  1757. parseIso = function (inp) {
  1758. // We'd normally use ~~inp for this, but unfortunately it also
  1759. // converts floats to ints.
  1760. // inp may be undefined, so careful calling replace on it.
  1761. var res = inp && parseFloat(inp.replace(',', '.'));
  1762. // apply sign while we're at it
  1763. return (isNaN(res) ? 0 : res) * sign;
  1764. };
  1765. duration = {
  1766. y: parseIso(match[2]),
  1767. M: parseIso(match[3]),
  1768. d: parseIso(match[4]),
  1769. h: parseIso(match[5]),
  1770. m: parseIso(match[6]),
  1771. s: parseIso(match[7]),
  1772. w: parseIso(match[8])
  1773. };
  1774. } else if (duration == null) {// checks for null or undefined
  1775. duration = {};
  1776. } else if (typeof duration === 'object' &&
  1777. ('from' in duration || 'to' in duration)) {
  1778. diffRes = momentsDifference(moment(duration.from), moment(duration.to));
  1779. duration = {};
  1780. duration.ms = diffRes.milliseconds;
  1781. duration.M = diffRes.months;
  1782. }
  1783. ret = new Duration(duration);
  1784. if (moment.isDuration(input) && hasOwnProp(input, '_locale')) {
  1785. ret._locale = input._locale;
  1786. }
  1787. return ret;
  1788. };
  1789. // version number
  1790. moment.version = VERSION;
  1791. // default format
  1792. moment.defaultFormat = isoFormat;
  1793. // constant that refers to the ISO standard
  1794. moment.ISO_8601 = function () {};
  1795. // Plugins that add properties should also add the key here (null value),
  1796. // so we can properly clone ourselves.
  1797. moment.momentProperties = momentProperties;
  1798. // This function will be called whenever a moment is mutated.
  1799. // It is intended to keep the offset in sync with the timezone.
  1800. moment.updateOffset = function () {};
  1801. // This function allows you to set a threshold for relative time strings
  1802. moment.relativeTimeThreshold = function (threshold, limit) {
  1803. if (relativeTimeThresholds[threshold] === undefined) {
  1804. return false;
  1805. }
  1806. if (limit === undefined) {
  1807. return relativeTimeThresholds[threshold];
  1808. }
  1809. relativeTimeThresholds[threshold] = limit;
  1810. return true;
  1811. };
  1812. moment.lang = deprecate(
  1813. 'moment.lang is deprecated. Use moment.locale instead.',
  1814. function (key, value) {
  1815. return moment.locale(key, value);
  1816. }
  1817. );
  1818. // This function will load locale and then set the global locale. If
  1819. // no arguments are passed in, it will simply return the current global
  1820. // locale key.
  1821. moment.locale = function (key, values) {
  1822. var data;
  1823. if (key) {
  1824. if (typeof(values) !== 'undefined') {
  1825. data = moment.defineLocale(key, values);
  1826. }
  1827. else {
  1828. data = moment.localeData(key);
  1829. }
  1830. if (data) {
  1831. moment.duration._locale = moment._locale = data;
  1832. }
  1833. }
  1834. return moment._locale._abbr;
  1835. };
  1836. moment.defineLocale = function (name, values) {
  1837. if (values !== null) {
  1838. values.abbr = name;
  1839. if (!locales[name]) {
  1840. locales[name] = new Locale();
  1841. }
  1842. locales[name].set(values);
  1843. // backwards compat for now: also set the locale
  1844. moment.locale(name);
  1845. return locales[name];
  1846. } else {
  1847. // useful for testing
  1848. delete locales[name];
  1849. return null;
  1850. }
  1851. };
  1852. moment.langData = deprecate(
  1853. 'moment.langData is deprecated. Use moment.localeData instead.',
  1854. function (key) {
  1855. return moment.localeData(key);
  1856. }
  1857. );
  1858. // returns locale data
  1859. moment.localeData = function (key) {
  1860. var locale;
  1861. if (key && key._locale && key._locale._abbr) {
  1862. key = key._locale._abbr;
  1863. }
  1864. if (!key) {
  1865. return moment._locale;
  1866. }
  1867. if (!isArray(key)) {
  1868. //short-circuit everything else
  1869. locale = loadLocale(key);
  1870. if (locale) {
  1871. return locale;
  1872. }
  1873. key = [key];
  1874. }
  1875. return chooseLocale(key);
  1876. };
  1877. // compare moment object
  1878. moment.isMoment = function (obj) {
  1879. return obj instanceof Moment ||
  1880. (obj != null && hasOwnProp(obj, '_isAMomentObject'));
  1881. };
  1882. // for typechecking Duration objects
  1883. moment.isDuration = function (obj) {
  1884. return obj instanceof Duration;
  1885. };
  1886. for (i = lists.length - 1; i >= 0; --i) {
  1887. makeList(lists[i]);
  1888. }
  1889. moment.normalizeUnits = function (units) {
  1890. return normalizeUnits(units);
  1891. };
  1892. moment.invalid = function (flags) {
  1893. var m = moment.utc(NaN);
  1894. if (flags != null) {
  1895. extend(m._pf, flags);
  1896. }
  1897. else {
  1898. m._pf.userInvalidated = true;
  1899. }
  1900. return m;
  1901. };
  1902. moment.parseZone = function () {
  1903. return moment.apply(null, arguments).parseZone();
  1904. };
  1905. moment.parseTwoDigitYear = function (input) {
  1906. return toInt(input) + (toInt(input) > 68 ? 1900 : 2000);
  1907. };
  1908. moment.isDate = isDate;
  1909. /************************************
  1910. Moment Prototype
  1911. ************************************/
  1912. extend(moment.fn = Moment.prototype, {
  1913. clone : function () {
  1914. return moment(this);
  1915. },
  1916. valueOf : function () {
  1917. return +this._d - ((this._offset || 0) * 60000);
  1918. },
  1919. unix : function () {
  1920. return Math.floor(+this / 1000);
  1921. },
  1922. toString : function () {
  1923. return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');
  1924. },
  1925. toDate : function () {
  1926. return this._offset ? new Date(+this) : this._d;
  1927. },
  1928. toISOString : function () {
  1929. var m = moment(this).utc();
  1930. if (0 < m.year() && m.year() <= 9999) {
  1931. if ('function' === typeof Date.prototype.toISOString) {
  1932. // native implementation is ~50x faster, use it when we can
  1933. return this.toDate().toISOString();
  1934. } else {
  1935. return formatMoment(m, 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]');
  1936. }
  1937. } else {
  1938. return formatMoment(m, 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]');
  1939. }
  1940. },
  1941. toArray : function () {
  1942. var m = this;
  1943. return [
  1944. m.year(),
  1945. m.month(),
  1946. m.date(),
  1947. m.hours(),
  1948. m.minutes(),
  1949. m.seconds(),
  1950. m.milliseconds()
  1951. ];
  1952. },
  1953. isValid : function () {
  1954. return isValid(this);
  1955. },
  1956. isDSTShifted : function () {
  1957. if (this._a) {
  1958. return this.isValid() && compareArrays(this._a, (this._isUTC ? moment.utc(this._a) : moment(this._a)).toArray()) > 0;
  1959. }
  1960. return false;
  1961. },
  1962. parsingFlags : function () {
  1963. return extend({}, this._pf);
  1964. },
  1965. invalidAt: function () {
  1966. return this._pf.overflow;
  1967. },
  1968. utc : function (keepLocalTime) {
  1969. return this.utcOffset(0, keepLocalTime);
  1970. },
  1971. local : function (keepLocalTime) {
  1972. if (this._isUTC) {
  1973. this.utcOffset(0, keepLocalTime);
  1974. this._isUTC = false;
  1975. if (keepLocalTime) {
  1976. this.subtract(this._dateUtcOffset(), 'm');
  1977. }
  1978. }
  1979. return this;
  1980. },
  1981. format : function (inputString) {
  1982. var output = formatMoment(this, inputString || moment.defaultFormat);
  1983. return this.localeData().postformat(output);
  1984. },
  1985. add : createAdder(1, 'add'),
  1986. subtract : createAdder(-1, 'subtract'),
  1987. diff : function (input, units, asFloat) {
  1988. var that = makeAs(input, this),
  1989. zoneDiff = (that.utcOffset() - this.utcOffset()) * 6e4,
  1990. anchor, diff, output, daysAdjust;
  1991. units = normalizeUnits(units);
  1992. if (units === 'year' || units === 'month' || units === 'quarter') {
  1993. output = monthDiff(this, that);
  1994. if (units === 'quarter') {
  1995. output = output / 3;
  1996. } else if (units === 'year') {
  1997. output = output / 12;
  1998. }
  1999. } else {
  2000. diff = this - that;
  2001. output = units === 'second' ? diff / 1e3 : // 1000
  2002. units === 'minute' ? diff / 6e4 : // 1000 * 60
  2003. units === 'hour' ? diff / 36e5 : // 1000 * 60 * 60
  2004. units === 'day' ? (diff - zoneDiff) / 864e5 : // 1000 * 60 * 60 * 24, negate dst
  2005. units === 'week' ? (diff - zoneDiff) / 6048e5 : // 1000 * 60 * 60 * 24 * 7, negate dst
  2006. diff;
  2007. }
  2008. return asFloat ? output : absRound(output);
  2009. },
  2010. from : function (time, withoutSuffix) {
  2011. return moment.duration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix);
  2012. },
  2013. fromNow : function (withoutSuffix) {
  2014. return this.from(moment(), withoutSuffix);
  2015. },
  2016. calendar : function (time) {
  2017. // We want to compare the start of today, vs this.
  2018. // Getting start-of-today depends on whether we're locat/utc/offset
  2019. // or not.
  2020. var now = time || moment(),
  2021. sod = makeAs(now, this).startOf('day'),
  2022. diff = this.diff(sod, 'days', true),
  2023. format = diff < -6 ? 'sameElse' :
  2024. diff < -1 ? 'lastWeek' :
  2025. diff < 0 ? 'lastDay' :
  2026. diff < 1 ? 'sameDay' :
  2027. diff < 2 ? 'nextDay' :
  2028. diff < 7 ? 'nextWeek' : 'sameElse';
  2029. return this.format(this.localeData().calendar(format, this, moment(now)));
  2030. },
  2031. isLeapYear : function () {
  2032. return isLeapYear(this.year());
  2033. },
  2034. isDST : function () {
  2035. return (this.utcOffset() > this.clone().month(0).utcOffset() ||
  2036. this.utcOffset() > this.clone().month(5).utcOffset());
  2037. },
  2038. day : function (input) {
  2039. var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();
  2040. if (input != null) {
  2041. input = parseWeekday(input, this.localeData());
  2042. return this.add(input - day, 'd');
  2043. } else {
  2044. return day;
  2045. }
  2046. },
  2047. month : makeAccessor('Month', true),
  2048. startOf : function (units) {
  2049. units = normalizeUnits(units);
  2050. // the following switch intentionally omits break keywords
  2051. // to utilize falling through the cases.
  2052. switch (units) {
  2053. case 'year':
  2054. this.month(0);
  2055. /* falls through */
  2056. case 'quarter':
  2057. case 'month':
  2058. this.date(1);
  2059. /* falls through */
  2060. case 'week':
  2061. case 'isoWeek':
  2062. case 'day':
  2063. this.hours(0);
  2064. /* falls through */
  2065. case 'hour':
  2066. this.minutes(0);
  2067. /* falls through */
  2068. case 'minute':
  2069. this.seconds(0);
  2070. /* falls through */
  2071. case 'second':
  2072. this.milliseconds(0);
  2073. /* falls through */
  2074. }
  2075. // weeks are a special case
  2076. if (units === 'week') {
  2077. this.weekday(0);
  2078. } else if (units === 'isoWeek') {
  2079. this.isoWeekday(1);
  2080. }
  2081. // quarters are also special
  2082. if (units === 'quarter') {
  2083. this.month(Math.floor(this.month() / 3) * 3);
  2084. }
  2085. return this;
  2086. },
  2087. endOf: function (units) {
  2088. units = normalizeUnits(units);
  2089. if (units === undefined || units === 'millisecond') {
  2090. return this;
  2091. }
  2092. return this.startOf(units).add(1, (units === 'isoWeek' ? 'week' : units)).subtract(1, 'ms');
  2093. },
  2094. isAfter: function (input, units) {
  2095. var inputMs;
  2096. units = normalizeUnits(typeof units !== 'undefined' ? units : 'millisecond');
  2097. if (units === 'millisecond') {
  2098. input = moment.isMoment(input) ? input : moment(input);
  2099. return +this > +input;
  2100. } else {
  2101. inputMs = moment.isMoment(input) ? +input : +moment(input);
  2102. return inputMs < +this.clone().startOf(units);
  2103. }
  2104. },
  2105. isBefore: function (input, units) {
  2106. var inputMs;
  2107. units = normalizeUnits(typeof units !== 'undefined' ? units : 'millisecond');
  2108. if (units === 'millisecond') {
  2109. input = moment.isMoment(input) ? input : moment(input);
  2110. return +this < +input;
  2111. } else {
  2112. inputMs = moment.isMoment(input) ? +input : +moment(input);
  2113. return +this.clone().endOf(units) < inputMs;
  2114. }
  2115. },
  2116. isBetween: function (from, to, units) {
  2117. return this.isAfter(from, units) && this.isBefore(to, units);
  2118. },
  2119. isSame: function (input, units) {
  2120. var inputMs;
  2121. units = normalizeUnits(units || 'millisecond');
  2122. if (units === 'millisecond') {
  2123. input = moment.isMoment(input) ? input : moment(input);
  2124. return +this === +input;
  2125. } else {
  2126. inputMs = +moment(input);
  2127. return +(this.clone().startOf(units)) <= inputMs && inputMs <= +(this.clone().endOf(units));
  2128. }
  2129. },
  2130. min: deprecate(
  2131. 'moment().min is deprecated, use moment.min instead. https://github.com/moment/moment/issues/1548',
  2132. function (other) {
  2133. other = moment.apply(null, arguments);
  2134. return other < this ? this : other;
  2135. }
  2136. ),
  2137. max: deprecate(
  2138. 'moment().max is deprecated, use moment.max instead. https://github.com/moment/moment/issues/1548',
  2139. function (other) {
  2140. other = moment.apply(null, arguments);
  2141. return other > this ? this : other;
  2142. }
  2143. ),
  2144. zone : deprecate(
  2145. 'moment().zone is deprecated, use moment().utcOffset instead. ' +
  2146. 'https://github.com/moment/moment/issues/1779',
  2147. function (input, keepLocalTime) {
  2148. if (input != null) {
  2149. if (typeof input !== 'string') {
  2150. input = -input;
  2151. }
  2152. this.utcOffset(input, keepLocalTime);
  2153. return this;
  2154. } else {
  2155. return -this.utcOffset();
  2156. }
  2157. }
  2158. ),
  2159. // keepLocalTime = true means only change the timezone, without
  2160. // affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]-->
  2161. // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset
  2162. // +0200, so we adjust the time as needed, to be valid.
  2163. //
  2164. // Keeping the time actually adds/subtracts (one hour)
  2165. // from the actual represented time. That is why we call updateOffset
  2166. // a second time. In case it wants us to change the offset again
  2167. // _changeInProgress == true case, then we have to adjust, because
  2168. // there is no such time in the given timezone.
  2169. utcOffset : function (input, keepLocalTime) {
  2170. var offset = this._offset || 0,
  2171. localAdjust;
  2172. if (input != null) {
  2173. if (typeof input === 'string') {
  2174. input = utcOffsetFromString(input);
  2175. }
  2176. if (Math.abs(input) < 16) {
  2177. input = input * 60;
  2178. }
  2179. if (!this._isUTC && keepLocalTime) {
  2180. localAdjust = this._dateUtcOffset();
  2181. }
  2182. this._offset = input;
  2183. this._isUTC = true;
  2184. if (localAdjust != null) {
  2185. this.add(localAdjust, 'm');
  2186. }
  2187. if (offset !== input) {
  2188. if (!keepLocalTime || this._changeInProgress) {
  2189. addOrSubtractDurationFromMoment(this,
  2190. moment.duration(input - offset, 'm'), 1, false);
  2191. } else if (!this._changeInProgress) {
  2192. this._changeInProgress = true;
  2193. moment.updateOffset(this, true);
  2194. this._changeInProgress = null;
  2195. }
  2196. }
  2197. return this;
  2198. } else {
  2199. return this._isUTC ? offset : this._dateUtcOffset();
  2200. }
  2201. },
  2202. isLocal : function () {
  2203. return !this._isUTC;
  2204. },
  2205. isUtcOffset : function () {
  2206. return this._isUTC;
  2207. },
  2208. isUtc : function () {
  2209. return this._isUTC && this._offset === 0;
  2210. },
  2211. zoneAbbr : function () {
  2212. return this._isUTC ? 'UTC' : '';
  2213. },
  2214. zoneName : function () {
  2215. return this._isUTC ? 'Coordinated Universal Time' : '';
  2216. },
  2217. parseZone : function () {
  2218. if (this._tzm) {
  2219. this.utcOffset(this._tzm);
  2220. } else if (typeof this._i === 'string') {
  2221. this.utcOffset(utcOffsetFromString(this._i));
  2222. }
  2223. return this;
  2224. },
  2225. hasAlignedHourOffset : function (input) {
  2226. if (!input) {
  2227. input = 0;
  2228. }
  2229. else {
  2230. input = moment(input).utcOffset();
  2231. }
  2232. return (this.utcOffset() - input) % 60 === 0;
  2233. },
  2234. daysInMonth : function () {
  2235. return daysInMonth(this.year(), this.month());
  2236. },
  2237. dayOfYear : function (input) {
  2238. var dayOfYear = round((moment(this).startOf('day') - moment(this).startOf('year')) / 864e5) + 1;
  2239. return input == null ? dayOfYear : this.add((input - dayOfYear), 'd');
  2240. },
  2241. quarter : function (input) {
  2242. return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3);
  2243. },
  2244. weekYear : function (input) {
  2245. var year = weekOfYear(this, this.localeData()._week.dow, this.localeData()._week.doy).year;
  2246. return input == null ? year : this.add((input - year), 'y');
  2247. },
  2248. isoWeekYear : function (input) {
  2249. var year = weekOfYear(this, 1, 4).year;
  2250. return input == null ? year : this.add((input - year), 'y');
  2251. },
  2252. week : function (input) {
  2253. var week = this.localeData().week(this);
  2254. return input == null ? week : this.add((input - week) * 7, 'd');
  2255. },
  2256. isoWeek : function (input) {
  2257. var week = weekOfYear(this, 1, 4).week;
  2258. return input == null ? week : this.add((input - week) * 7, 'd');
  2259. },
  2260. weekday : function (input) {
  2261. var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;
  2262. return input == null ? weekday : this.add(input - weekday, 'd');
  2263. },
  2264. isoWeekday : function (input) {
  2265. // behaves the same as moment#day except
  2266. // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)
  2267. // as a setter, sunday should belong to the previous week.
  2268. return input == null ? this.day() || 7 : this.day(this.day() % 7 ? input : input - 7);
  2269. },
  2270. isoWeeksInYear : function () {
  2271. return weeksInYear(this.year(), 1, 4);
  2272. },
  2273. weeksInYear : function () {
  2274. var weekInfo = this.localeData()._week;
  2275. return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);
  2276. },
  2277. get : function (units) {
  2278. units = normalizeUnits(units);
  2279. return this[units]();
  2280. },
  2281. set : function (units, value) {
  2282. var unit;
  2283. if (typeof units === 'object') {
  2284. for (unit in units) {
  2285. this.set(unit, units[unit]);
  2286. }
  2287. }
  2288. else {
  2289. units = normalizeUnits(units);
  2290. if (typeof this[units] === 'function') {
  2291. this[units](value);
  2292. }
  2293. }
  2294. return this;
  2295. },
  2296. // If passed a locale key, it will set the locale for this
  2297. // instance. Otherwise, it will return the locale configuration
  2298. // variables for this instance.
  2299. locale : function (key) {
  2300. var newLocaleData;
  2301. if (key === undefined) {
  2302. return this._locale._abbr;
  2303. } else {
  2304. newLocaleData = moment.localeData(key);
  2305. if (newLocaleData != null) {
  2306. this._locale = newLocaleData;
  2307. }
  2308. return this;
  2309. }
  2310. },
  2311. lang : deprecate(
  2312. 'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.',
  2313. function (key) {
  2314. if (key === undefined) {
  2315. return this.localeData();
  2316. } else {
  2317. return this.locale(key);
  2318. }
  2319. }
  2320. ),
  2321. localeData : function () {
  2322. return this._locale;
  2323. },
  2324. _dateUtcOffset : function () {
  2325. // On Firefox.24 Date#getTimezoneOffset returns a floating point.
  2326. // https://github.com/moment/moment/pull/1871
  2327. return -Math.round(this._d.getTimezoneOffset() / 15) * 15;
  2328. }
  2329. });
  2330. function rawMonthSetter(mom, value) {
  2331. var dayOfMonth;
  2332. // TODO: Move this out of here!
  2333. if (typeof value === 'string') {
  2334. value = mom.localeData().monthsParse(value);
  2335. // TODO: Another silent failure?
  2336. if (typeof value !== 'number') {
  2337. return mom;
  2338. }
  2339. }
  2340. dayOfMonth = Math.min(mom.date(),
  2341. daysInMonth(mom.year(), value));
  2342. mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth);
  2343. return mom;
  2344. }
  2345. function rawGetter(mom, unit) {
  2346. return mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]();
  2347. }
  2348. function rawSetter(mom, unit, value) {
  2349. if (unit === 'Month') {
  2350. return rawMonthSetter(mom, value);
  2351. } else {
  2352. return mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);
  2353. }
  2354. }
  2355. function makeAccessor(unit, keepTime) {
  2356. return function (value) {
  2357. if (value != null) {
  2358. rawSetter(this, unit, value);
  2359. moment.updateOffset(this, keepTime);
  2360. return this;
  2361. } else {
  2362. return rawGetter(this, unit);
  2363. }
  2364. };
  2365. }
  2366. moment.fn.millisecond = moment.fn.milliseconds = makeAccessor('Milliseconds', false);
  2367. moment.fn.second = moment.fn.seconds = makeAccessor('Seconds', false);
  2368. moment.fn.minute = moment.fn.minutes = makeAccessor('Minutes', false);
  2369. // Setting the hour should keep the time, because the user explicitly
  2370. // specified which hour he wants. So trying to maintain the same hour (in
  2371. // a new timezone) makes sense. Adding/subtracting hours does not follow
  2372. // this rule.
  2373. moment.fn.hour = moment.fn.hours = makeAccessor('Hours', true);
  2374. // moment.fn.month is defined separately
  2375. moment.fn.date = makeAccessor('Date', true);
  2376. moment.fn.dates = deprecate('dates accessor is deprecated. Use date instead.', makeAccessor('Date', true));
  2377. moment.fn.year = makeAccessor('FullYear', true);
  2378. moment.fn.years = deprecate('years accessor is deprecated. Use year instead.', makeAccessor('FullYear', true));
  2379. // add plural methods
  2380. moment.fn.days = moment.fn.day;
  2381. moment.fn.months = moment.fn.month;
  2382. moment.fn.weeks = moment.fn.week;
  2383. moment.fn.isoWeeks = moment.fn.isoWeek;
  2384. moment.fn.quarters = moment.fn.quarter;
  2385. // add aliased format methods
  2386. moment.fn.toJSON = moment.fn.toISOString;
  2387. // alias isUtc for dev-friendliness
  2388. moment.fn.isUTC = moment.fn.isUtc;
  2389. /************************************
  2390. Duration Prototype
  2391. ************************************/
  2392. function daysToYears (days) {
  2393. // 400 years have 146097 days (taking into account leap year rules)
  2394. return days * 400 / 146097;
  2395. }
  2396. function yearsToDays (years) {
  2397. // years * 365 + absRound(years / 4) -
  2398. // absRound(years / 100) + absRound(years / 400);
  2399. return years * 146097 / 400;
  2400. }
  2401. extend(moment.duration.fn = Duration.prototype, {
  2402. _bubble : function () {
  2403. var milliseconds = this._milliseconds,
  2404. days = this._days,
  2405. months = this._months,
  2406. data = this._data,
  2407. seconds, minutes, hours, years = 0;
  2408. // The following code bubbles up values, see the tests for
  2409. // examples of what that means.
  2410. data.milliseconds = milliseconds % 1000;
  2411. seconds = absRound(milliseconds / 1000);
  2412. data.seconds = seconds % 60;
  2413. minutes = absRound(seconds / 60);
  2414. data.minutes = minutes % 60;
  2415. hours = absRound(minutes / 60);
  2416. data.hours = hours % 24;
  2417. days += absRound(hours / 24);
  2418. // Accurately convert days to years, assume start from year 0.
  2419. years = absRound(daysToYears(days));
  2420. days -= absRound(yearsToDays(years));
  2421. // 30 days to a month
  2422. // TODO (iskren): Use anchor date (like 1st Jan) to compute this.
  2423. months += absRound(days / 30);
  2424. days %= 30;
  2425. // 12 months -> 1 year
  2426. years += absRound(months / 12);
  2427. months %= 12;
  2428. data.days = days;
  2429. data.months = months;
  2430. data.years = years;
  2431. },
  2432. abs : function () {
  2433. this._milliseconds = Math.abs(this._milliseconds);
  2434. this._days = Math.abs(this._days);
  2435. this._months = Math.abs(this._months);
  2436. this._data.milliseconds = Math.abs(this._data.milliseconds);
  2437. this._data.seconds = Math.abs(this._data.seconds);
  2438. this._data.minutes = Math.abs(this._data.minutes);
  2439. this._data.hours = Math.abs(this._data.hours);
  2440. this._data.months = Math.abs(this._data.months);
  2441. this._data.years = Math.abs(this._data.years);
  2442. return this;
  2443. },
  2444. weeks : function () {
  2445. return absRound(this.days() / 7);
  2446. },
  2447. valueOf : function () {
  2448. return this._milliseconds +
  2449. this._days * 864e5 +
  2450. (this._months % 12) * 2592e6 +
  2451. toInt(this._months / 12) * 31536e6;
  2452. },
  2453. humanize : function (withSuffix) {
  2454. var output = relativeTime(this, !withSuffix, this.localeData());
  2455. if (withSuffix) {
  2456. output = this.localeData().pastFuture(+this, output);
  2457. }
  2458. return this.localeData().postformat(output);
  2459. },
  2460. add : function (input, val) {
  2461. // supports only 2.0-style add(1, 's') or add(moment)
  2462. var dur = moment.duration(input, val);
  2463. this._milliseconds += dur._milliseconds;
  2464. this._days += dur._days;
  2465. this._months += dur._months;
  2466. this._bubble();
  2467. return this;
  2468. },
  2469. subtract : function (input, val) {
  2470. var dur = moment.duration(input, val);
  2471. this._milliseconds -= dur._milliseconds;
  2472. this._days -= dur._days;
  2473. this._months -= dur._months;
  2474. this._bubble();
  2475. return this;
  2476. },
  2477. get : function (units) {
  2478. units = normalizeUnits(units);
  2479. return this[units.toLowerCase() + 's']();
  2480. },
  2481. as : function (units) {
  2482. var days, months;
  2483. units = normalizeUnits(units);
  2484. if (units === 'month' || units === 'year') {
  2485. days = this._days + this._milliseconds / 864e5;
  2486. months = this._months + daysToYears(days) * 12;
  2487. return units === 'month' ? months : months / 12;
  2488. } else {
  2489. // handle milliseconds separately because of floating point math errors (issue #1867)
  2490. days = this._days + Math.round(yearsToDays(this._months / 12));
  2491. switch (units) {
  2492. case 'week': return days / 7 + this._milliseconds / 6048e5;
  2493. case 'day': return days + this._milliseconds / 864e5;
  2494. case 'hour': return days * 24 + this._milliseconds / 36e5;
  2495. case 'minute': return days * 24 * 60 + this._milliseconds / 6e4;
  2496. case 'second': return days * 24 * 60 * 60 + this._milliseconds / 1000;
  2497. // Math.floor prevents floating point math errors here
  2498. case 'millisecond': return Math.floor(days * 24 * 60 * 60 * 1000) + this._milliseconds;
  2499. default: throw new Error('Unknown unit ' + units);
  2500. }
  2501. }
  2502. },
  2503. lang : moment.fn.lang,
  2504. locale : moment.fn.locale,
  2505. toIsoString : deprecate(
  2506. 'toIsoString() is deprecated. Please use toISOString() instead ' +
  2507. '(notice the capitals)',
  2508. function () {
  2509. return this.toISOString();
  2510. }
  2511. ),
  2512. toISOString : function () {
  2513. // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js
  2514. var years = Math.abs(this.years()),
  2515. months = Math.abs(this.months()),
  2516. days = Math.abs(this.days()),
  2517. hours = Math.abs(this.hours()),
  2518. minutes = Math.abs(this.minutes()),
  2519. seconds = Math.abs(this.seconds() + this.milliseconds() / 1000);
  2520. if (!this.asSeconds()) {
  2521. // this is the same as C#'s (Noda) and python (isodate)...
  2522. // but not other JS (goog.date)
  2523. return 'P0D';
  2524. }
  2525. return (this.asSeconds() < 0 ? '-' : '') +
  2526. 'P' +
  2527. (years ? years + 'Y' : '') +
  2528. (months ? months + 'M' : '') +
  2529. (days ? days + 'D' : '') +
  2530. ((hours || minutes || seconds) ? 'T' : '') +
  2531. (hours ? hours + 'H' : '') +
  2532. (minutes ? minutes + 'M' : '') +
  2533. (seconds ? seconds + 'S' : '');
  2534. },
  2535. localeData : function () {
  2536. return this._locale;
  2537. },
  2538. toJSON : function () {
  2539. return this.toISOString();
  2540. }
  2541. });
  2542. moment.duration.fn.toString = moment.duration.fn.toISOString;
  2543. function makeDurationGetter(name) {
  2544. moment.duration.fn[name] = function () {
  2545. return this._data[name];
  2546. };
  2547. }
  2548. for (i in unitMillisecondFactors) {
  2549. if (hasOwnProp(unitMillisecondFactors, i)) {
  2550. makeDurationGetter(i.toLowerCase());
  2551. }
  2552. }
  2553. moment.duration.fn.asMilliseconds = function () {
  2554. return this.as('ms');
  2555. };
  2556. moment.duration.fn.asSeconds = function () {
  2557. return this.as('s');
  2558. };
  2559. moment.duration.fn.asMinutes = function () {
  2560. return this.as('m');
  2561. };
  2562. moment.duration.fn.asHours = function () {
  2563. return this.as('h');
  2564. };
  2565. moment.duration.fn.asDays = function () {
  2566. return this.as('d');
  2567. };
  2568. moment.duration.fn.asWeeks = function () {
  2569. return this.as('weeks');
  2570. };
  2571. moment.duration.fn.asMonths = function () {
  2572. return this.as('M');
  2573. };
  2574. moment.duration.fn.asYears = function () {
  2575. return this.as('y');
  2576. };
  2577. /************************************
  2578. Default Locale
  2579. ************************************/
  2580. // Set default locale, other locale will inherit from English.
  2581. moment.locale('en', {
  2582. ordinalParse: /\d{1,2}(th|st|nd|rd)/,
  2583. ordinal : function (number) {
  2584. var b = number % 10,
  2585. output = (toInt(number % 100 / 10) === 1) ? 'th' :
  2586. (b === 1) ? 'st' :
  2587. (b === 2) ? 'nd' :
  2588. (b === 3) ? 'rd' : 'th';
  2589. return number + output;
  2590. }
  2591. });
  2592. /* EMBED_LOCALES */
  2593. /************************************
  2594. Exposing Moment
  2595. ************************************/
  2596. function makeGlobal(shouldDeprecate) {
  2597. /*global ender:false */
  2598. if (typeof ender !== 'undefined') {
  2599. return;
  2600. }
  2601. oldGlobalMoment = globalScope.moment;
  2602. if (shouldDeprecate) {
  2603. globalScope.moment = deprecate(
  2604. 'Accessing Moment through the global scope is ' +
  2605. 'deprecated, and will be removed in an upcoming ' +
  2606. 'release.',
  2607. moment);
  2608. } else {
  2609. globalScope.moment = moment;
  2610. }
  2611. }
  2612. // CommonJS module is defined
  2613. if (hasModule) {
  2614. module.exports = moment;
  2615. } else if (typeof define === 'function' && define.amd) {
  2616. define(function (require, exports, module) {
  2617. if (module.config && module.config() && module.config().noGlobal === true) {
  2618. // release the global variable
  2619. globalScope.moment = oldGlobalMoment;
  2620. }
  2621. return moment;
  2622. });
  2623. makeGlobal(true);
  2624. } else {
  2625. makeGlobal();
  2626. }
  2627. }).call(this);