corrade-nucleus-nucleons – Blame information for rev 38

Subversion Repositories:
Rev:
Rev Author Line No. Line
38 office 1 import { Duration, isDuration } from './constructor';
2 import isNumber from '../utils/is-number';
3 import toInt from '../utils/to-int';
4 import absRound from '../utils/abs-round';
5 import hasOwnProp from '../utils/has-own-prop';
6 import { DATE, HOUR, MINUTE, SECOND, MILLISECOND } from '../units/constants';
7 import { cloneWithOffset } from '../units/offset';
8 import { createLocal } from '../create/local';
9 import { createInvalid as invalid } from './valid';
10  
11 // ASP.NET json date format regex
12 var aspNetRegex = /^(\-)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/;
13  
14 // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html
15 // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere
16 // and further modified to allow for strings containing both week and day
17 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)?)?$/;
18  
19 export function createDuration (input, key) {
20 var duration = input,
21 // matching against regexp is expensive, do it on demand
22 match = null,
23 sign,
24 ret,
25 diffRes;
26  
27 if (isDuration(input)) {
28 duration = {
29 ms : input._milliseconds,
30 d : input._days,
31 M : input._months
32 };
33 } else if (isNumber(input)) {
34 duration = {};
35 if (key) {
36 duration[key] = input;
37 } else {
38 duration.milliseconds = input;
39 }
40 } else if (!!(match = aspNetRegex.exec(input))) {
41 sign = (match[1] === '-') ? -1 : 1;
42 duration = {
43 y : 0,
44 d : toInt(match[DATE]) * sign,
45 h : toInt(match[HOUR]) * sign,
46 m : toInt(match[MINUTE]) * sign,
47 s : toInt(match[SECOND]) * sign,
48 ms : toInt(absRound(match[MILLISECOND] * 1000)) * sign // the millisecond decimal point is included in the match
49 };
50 } else if (!!(match = isoRegex.exec(input))) {
51 sign = (match[1] === '-') ? -1 : 1;
52 duration = {
53 y : parseIso(match[2], sign),
54 M : parseIso(match[3], sign),
55 w : parseIso(match[4], sign),
56 d : parseIso(match[5], sign),
57 h : parseIso(match[6], sign),
58 m : parseIso(match[7], sign),
59 s : parseIso(match[8], sign)
60 };
61 } else if (duration == null) {// checks for null or undefined
62 duration = {};
63 } else if (typeof duration === 'object' && ('from' in duration || 'to' in duration)) {
64 diffRes = momentsDifference(createLocal(duration.from), createLocal(duration.to));
65  
66 duration = {};
67 duration.ms = diffRes.milliseconds;
68 duration.M = diffRes.months;
69 }
70  
71 ret = new Duration(duration);
72  
73 if (isDuration(input) && hasOwnProp(input, '_locale')) {
74 ret._locale = input._locale;
75 }
76  
77 return ret;
78 }
79  
80 createDuration.fn = Duration.prototype;
81 createDuration.invalid = invalid;
82  
83 function parseIso (inp, sign) {
84 // We'd normally use ~~inp for this, but unfortunately it also
85 // converts floats to ints.
86 // inp may be undefined, so careful calling replace on it.
87 var res = inp && parseFloat(inp.replace(',', '.'));
88 // apply sign while we're at it
89 return (isNaN(res) ? 0 : res) * sign;
90 }
91  
92 function positiveMomentsDifference(base, other) {
93 var res = {milliseconds: 0, months: 0};
94  
95 res.months = other.month() - base.month() +
96 (other.year() - base.year()) * 12;
97 if (base.clone().add(res.months, 'M').isAfter(other)) {
98 --res.months;
99 }
100  
101 res.milliseconds = +other - +(base.clone().add(res.months, 'M'));
102  
103 return res;
104 }
105  
106 function momentsDifference(base, other) {
107 var res;
108 if (!(base.isValid() && other.isValid())) {
109 return {milliseconds: 0, months: 0};
110 }
111  
112 other = cloneWithOffset(other, base);
113 if (base.isBefore(other)) {
114 res = positiveMomentsDifference(base, other);
115 } else {
116 res = positiveMomentsDifference(other, base);
117 res.milliseconds = -res.milliseconds;
118 res.months = -res.months;
119 }
120  
121 return res;
122 }