moment.js 91KB

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