| | import { Duration, isDuration } from './constructor'; |
| | import isNumber from '../utils/is-number'; |
| | import toInt from '../utils/to-int'; |
| | import absRound from '../utils/abs-round'; |
| | import hasOwnProp from '../utils/has-own-prop'; |
| | import { DATE, HOUR, MINUTE, SECOND, MILLISECOND } from '../units/constants'; |
| | import { cloneWithOffset } from '../units/offset'; |
| | import { createLocal } from '../create/local'; |
| | import { createInvalid as invalid } from './valid'; |
| |
|
| | |
| | var aspNetRegex = /^(\-|\+)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/; |
| |
|
| | |
| | |
| | |
| | var isoRegex = /^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/; |
| |
|
| | export function createDuration (input, key) { |
| | var duration = input, |
| | |
| | match = null, |
| | sign, |
| | ret, |
| | diffRes; |
| |
|
| | if (isDuration(input)) { |
| | duration = { |
| | ms : input._milliseconds, |
| | d : input._days, |
| | M : input._months |
| | }; |
| | } else if (isNumber(input)) { |
| | duration = {}; |
| | if (key) { |
| | duration[key] = input; |
| | } else { |
| | duration.milliseconds = input; |
| | } |
| | } else if (!!(match = aspNetRegex.exec(input))) { |
| | sign = (match[1] === '-') ? -1 : 1; |
| | duration = { |
| | y : 0, |
| | d : toInt(match[DATE]) * sign, |
| | h : toInt(match[HOUR]) * sign, |
| | m : toInt(match[MINUTE]) * sign, |
| | s : toInt(match[SECOND]) * sign, |
| | ms : toInt(absRound(match[MILLISECOND] * 1000)) * sign |
| | }; |
| | } else if (!!(match = isoRegex.exec(input))) { |
| | sign = (match[1] === '-') ? -1 : (match[1] === '+') ? 1 : 1; |
| | duration = { |
| | y : parseIso(match[2], sign), |
| | M : parseIso(match[3], sign), |
| | w : parseIso(match[4], sign), |
| | d : parseIso(match[5], sign), |
| | h : parseIso(match[6], sign), |
| | m : parseIso(match[7], sign), |
| | s : parseIso(match[8], sign) |
| | }; |
| | } else if (duration == null) { |
| | duration = {}; |
| | } else if (typeof duration === 'object' && ('from' in duration || 'to' in duration)) { |
| | diffRes = momentsDifference(createLocal(duration.from), createLocal(duration.to)); |
| |
|
| | duration = {}; |
| | duration.ms = diffRes.milliseconds; |
| | duration.M = diffRes.months; |
| | } |
| |
|
| | ret = new Duration(duration); |
| |
|
| | if (isDuration(input) && hasOwnProp(input, '_locale')) { |
| | ret._locale = input._locale; |
| | } |
| |
|
| | return ret; |
| | } |
| |
|
| | createDuration.fn = Duration.prototype; |
| | createDuration.invalid = invalid; |
| |
|
| | function parseIso (inp, sign) { |
| | |
| | |
| | |
| | var res = inp && parseFloat(inp.replace(',', '.')); |
| | |
| | return (isNaN(res) ? 0 : res) * sign; |
| | } |
| |
|
| | function positiveMomentsDifference(base, other) { |
| | var res = {milliseconds: 0, months: 0}; |
| |
|
| | res.months = other.month() - base.month() + |
| | (other.year() - base.year()) * 12; |
| | if (base.clone().add(res.months, 'M').isAfter(other)) { |
| | --res.months; |
| | } |
| |
|
| | res.milliseconds = +other - +(base.clone().add(res.months, 'M')); |
| |
|
| | return res; |
| | } |
| |
|
| | function momentsDifference(base, other) { |
| | var res; |
| | if (!(base.isValid() && other.isValid())) { |
| | return {milliseconds: 0, months: 0}; |
| | } |
| |
|
| | other = cloneWithOffset(other, base); |
| | if (base.isBefore(other)) { |
| | res = positiveMomentsDifference(base, other); |
| | } else { |
| | res = positiveMomentsDifference(other, base); |
| | res.milliseconds = -res.milliseconds; |
| | res.months = -res.months; |
| | } |
| |
|
| | return res; |
| | } |
| |
|