forked from kewisch/ical.js
-
Notifications
You must be signed in to change notification settings - Fork 0
/
period.js
233 lines (206 loc) · 6.56 KB
/
period.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http:https://mozilla.org/MPL/2.0/.
* Portions Copyright (C) Philipp Kewisch, 2011-2015 */
"use strict";
(function() {
/**
* @classdesc
* This class represents the "period" value type, with various calculation
* and manipulation methods.
*
* @description
* The passed data object cannot contain both and end date and a duration.
*
* @class
* @param {Object} aData An object with members of the period
* @param {ICAL.Time=} aData.start The start of the period
* @param {ICAL.Time=} aData.end The end of the period
* @param {ICAL.Duration=} aData.duration The duration of the period
*/
ICAL.Period = function icalperiod(aData) {
this.wrappedJSObject = this;
if (aData && 'start' in aData) {
if (aData.start && !(aData.start instanceof ICAL.Time)) {
throw new TypeError('.start must be an instance of ICAL.Time');
}
this.start = aData.start;
}
if (aData && aData.end && aData.duration) {
throw new Error('cannot accept both end and duration');
}
if (aData && 'end' in aData) {
if (aData.end && !(aData.end instanceof ICAL.Time)) {
throw new TypeError('.end must be an instance of ICAL.Time');
}
this.end = aData.end;
}
if (aData && 'duration' in aData) {
if (aData.duration && !(aData.duration instanceof ICAL.Duration)) {
throw new TypeError('.duration must be an instance of ICAL.Duration');
}
this.duration = aData.duration;
}
};
ICAL.Period.prototype = {
/**
* The start of the period
* @type {ICAL.Time}
*/
start: null,
/**
* The end of the period
* @type {ICAL.Time}
*/
end: null,
/**
* The duration of the period
* @type {ICAL.Duration}
*/
duration: null,
/**
* The class identifier.
* @constant
* @type {String}
* @default "icalperiod"
*/
icalclass: "icalperiod",
/**
* The type name, to be used in the jCal object.
* @constant
* @type {String}
* @default "period"
*/
icaltype: "period",
/**
* Returns a clone of the duration object.
*
* @return {ICAL.Period} The cloned object
*/
clone: function() {
return ICAL.Period.fromData({
start: this.start ? this.start.clone() : null,
end: this.end ? this.end.clone() : null,
duration: this.duration ? this.duration.clone() : null
});
},
/**
* Calculates the duration of the period, either directly or by subtracting
* start from end date.
*
* @return {ICAL.Duration} The calculated duration
*/
getDuration: function duration() {
if (this.duration) {
return this.duration;
} else {
return this.end.subtractDate(this.start);
}
},
/**
* Calculates the end date of the period, either directly or by adding
* duration to start date.
*
* @return {ICAL.Time} The calculated end date
*/
getEnd: function() {
if (this.end) {
return this.end;
} else {
var end = this.start.clone();
end.addDuration(this.duration);
return end;
}
},
/**
* The string representation of this period.
* @return {String}
*/
toString: function toString() {
return this.start + "/" + (this.end || this.duration);
},
/**
* The jCal representation of this period type.
* @return {Object}
*/
toJSON: function() {
return [this.start.toString(), (this.end || this.duration).toString()];
},
/**
* The iCalendar string representation of this period.
* @return {String}
*/
toICALString: function() {
return this.start.toICALString() + "/" +
(this.end || this.duration).toICALString();
}
};
/**
* Creates a new {@link ICAL.Period} instance from the passed string.
*
* @param {String} str The string to parse
* @param {ICAL.Property} prop The property this period will be on
* @return {ICAL.Period} The created period instance
*/
ICAL.Period.fromString = function fromString(str, prop) {
var parts = str.split('/');
if (parts.length !== 2) {
throw new Error(
'Invalid string value: "' + str + '" must contain a "/" char.'
);
}
var options = {
start: ICAL.Time.fromDateTimeString(parts[0], prop)
};
var end = parts[1];
if (ICAL.Duration.isValueString(end)) {
options.duration = ICAL.Duration.fromString(end);
} else {
options.end = ICAL.Time.fromDateTimeString(end, prop);
}
return new ICAL.Period(options);
};
/**
* Creates a new {@link ICAL.Period} instance from the given data object.
* The passed data object cannot contain both and end date and a duration.
*
* @param {Object} aData An object with members of the period
* @param {ICAL.Time=} aData.start The start of the period
* @param {ICAL.Time=} aData.end The end of the period
* @param {ICAL.Duration=} aData.duration The duration of the period
* @return {ICAL.Period} The period instance
*/
ICAL.Period.fromData = function fromData(aData) {
return new ICAL.Period(aData);
};
/**
* Returns a new period instance from the given jCal data array. The first
* member is always the start date string, the second member is either a
* duration or end date string.
*
* @param {Array<String,String>} aData The jCal data array
* @param {ICAL.Property} aProp The property this jCal data is on
* @param {Boolean} aLenient If true, data value can be both date and date-time
* @return {ICAL.Period} The period instance
*/
ICAL.Period.fromJSON = function(aData, aProp, aLenient) {
function fromDateOrDateTimeString(aValue, aProp) {
if (aLenient) {
return ICAL.Time.fromString(aValue, aProp);
} else {
return ICAL.Time.fromDateTimeString(aValue, aProp);
}
}
if (ICAL.Duration.isValueString(aData[1])) {
return ICAL.Period.fromData({
start: fromDateOrDateTimeString(aData[0], aProp),
duration: ICAL.Duration.fromString(aData[1])
});
} else {
return ICAL.Period.fromData({
start: fromDateOrDateTimeString(aData[0], aProp),
end: fromDateOrDateTimeString(aData[1], aProp)
});
}
};
})();