1131cdcbed6a8696a6654e197b7cd8aefedc890e
[platform/framework/web/crosswalk-tizen.git] /
1 var totalDaysInMonth = require('./totalDaysInMonth');
2 var totalDaysInYear = require('./totalDaysInYear');
3 var convert = require('../time/convert');
4
5     /**
6      * calculate the difference between dates (range)
7      */
8     function diff(start, end, unitName){
9         // sort the dates to make it easier to process (specially year/month)
10         if (start > end) {
11             var swap = start;
12             start = end;
13             end = swap;
14         }
15
16         var output;
17
18         if (unitName === 'month') {
19             output = getMonthsDiff(start, end);
20         } else if (unitName === 'year'){
21             output = getYearsDiff(start, end);
22         } else if (unitName != null) {
23             if (unitName === 'day') {
24                 // ignore timezone difference because of daylight savings time
25                 start = toUtc(start);
26                 end = toUtc(end);
27             }
28             output = convert(end - start, 'ms', unitName);
29         } else {
30             output = end - start;
31         }
32
33         return output;
34     }
35
36
37     function toUtc(d){
38         // we ignore timezone differences on purpose because of daylight
39         // savings time, otherwise it would return fractional days/weeks even
40         // if a full day elapsed. eg:
41         // Wed Feb 12 2014 00:00:00 GMT-0200 (BRST)
42         // Sun Feb 16 2014 00:00:00 GMT-0300 (BRT)
43         // diff should be 4 days and not 4.041666666666667
44         return Date.UTC(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate(),
45                         d.getHours(), d.getMinutes(), d.getSeconds(),
46                         d.getMilliseconds());
47     }
48
49
50     function getMonthsDiff(start, end){
51         return getElapsedMonths(start, end) +
52                getElapsedYears(start, end) * 12 +
53                getFractionalMonth(start, end);
54     }
55
56
57     function getYearsDiff(start, end){
58         var elapsedYears = getElapsedYears(start, end);
59         return elapsedYears + getFractionalYear(start, end, elapsedYears);
60     }
61
62
63     function getElapsedMonths(start, end){
64         var monthDiff = end.getMonth() - start.getMonth();
65         if (monthDiff < 0) {
66             monthDiff += 12;
67         }
68         // less than a full month
69         if (start.getDate() > end.getDate()) {
70             monthDiff -= 1;
71         }
72         return monthDiff;
73     }
74
75
76     function getElapsedYears(start, end){
77         var yearDiff = end.getFullYear() - start.getFullYear();
78         // less than a full year
79         if (start.getMonth() > end.getMonth()) {
80             yearDiff -= 1;
81         }
82         return yearDiff;
83     }
84
85
86     function getFractionalMonth(start, end){
87         var fractionalDiff = 0;
88         var startDay = start.getDate();
89         var endDay = end.getDate();
90
91         if (startDay !== endDay) {
92             var startTotalDays = totalDaysInMonth(start);
93             var endTotalDays = totalDaysInMonth(end);
94             var totalDays;
95             var daysElapsed;
96
97             if (startDay > endDay) {
98                 // eg: Jan 29 - Feb 27 (29 days elapsed but not a full month)
99                 var baseDay = startTotalDays - startDay;
100                 daysElapsed = endDay + baseDay;
101                 // total days should be relative to 1st day of next month if
102                 // startDay > endTotalDays
103                 totalDays = (startDay > endTotalDays)?
104                     endTotalDays + baseDay + 1 : startDay + baseDay;
105             } else {
106                 // fractional is only based on endMonth eg: Jan 12 - Feb 18
107                 // (6 fractional days, 28 days until next full month)
108                 daysElapsed = endDay - startDay;
109                 totalDays = endTotalDays;
110             }
111
112             fractionalDiff = daysElapsed / totalDays;
113         }
114
115         return fractionalDiff;
116     }
117
118
119     function getFractionalYear(start, end, elapsedYears){
120         var base = elapsedYears?
121             new Date(end.getFullYear(), start.getMonth(), start.getDate()) :
122             start;
123         var elapsedDays = diff(base, end, 'day');
124         return elapsedDays / totalDaysInYear(end);
125     }
126
127
128     module.exports = diff;
129
130