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