ts-time-utils 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/README.md +226 -1
  2. package/dist/calculate.d.ts.map +1 -1
  3. package/dist/calculate.js +24 -10
  4. package/dist/countdown.d.ts +217 -0
  5. package/dist/countdown.d.ts.map +1 -0
  6. package/dist/countdown.js +298 -0
  7. package/dist/dateRange.d.ts +266 -0
  8. package/dist/dateRange.d.ts.map +1 -0
  9. package/dist/dateRange.js +433 -0
  10. package/dist/esm/calculate.d.ts.map +1 -1
  11. package/dist/esm/calculate.js +24 -10
  12. package/dist/esm/countdown.d.ts +217 -0
  13. package/dist/esm/countdown.d.ts.map +1 -0
  14. package/dist/esm/countdown.js +298 -0
  15. package/dist/esm/dateRange.d.ts +266 -0
  16. package/dist/esm/dateRange.d.ts.map +1 -0
  17. package/dist/esm/dateRange.js +433 -0
  18. package/dist/esm/index.d.ts +5 -1
  19. package/dist/esm/index.d.ts.map +1 -1
  20. package/dist/esm/index.js +8 -0
  21. package/dist/esm/naturalLanguage.d.ts +107 -0
  22. package/dist/esm/naturalLanguage.d.ts.map +1 -0
  23. package/dist/esm/naturalLanguage.js +344 -0
  24. package/dist/esm/recurrence.d.ts +149 -0
  25. package/dist/esm/recurrence.d.ts.map +1 -0
  26. package/dist/esm/recurrence.js +404 -0
  27. package/dist/esm/types.d.ts +21 -0
  28. package/dist/esm/types.d.ts.map +1 -1
  29. package/dist/index.d.ts +5 -1
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +8 -0
  32. package/dist/naturalLanguage.d.ts +107 -0
  33. package/dist/naturalLanguage.d.ts.map +1 -0
  34. package/dist/naturalLanguage.js +344 -0
  35. package/dist/recurrence.d.ts +149 -0
  36. package/dist/recurrence.d.ts.map +1 -0
  37. package/dist/recurrence.js +404 -0
  38. package/dist/types.d.ts +21 -0
  39. package/dist/types.d.ts.map +1 -1
  40. package/package.json +30 -2
@@ -0,0 +1,433 @@
1
+ /**
2
+ * @fileoverview Extended date range operations and utilities
3
+ * Provides advanced operations for working with date ranges beyond basic intervals
4
+ */
5
+ import { addTime } from './calculate.js';
6
+ /**
7
+ * Checks if two date ranges overlap
8
+ * @param range1 - First date range
9
+ * @param range2 - Second date range
10
+ * @returns True if the ranges overlap
11
+ *
12
+ * @example
13
+ * ```ts
14
+ * const range1 = { start: new Date('2024-01-01'), end: new Date('2024-01-10') };
15
+ * const range2 = { start: new Date('2024-01-05'), end: new Date('2024-01-15') };
16
+ *
17
+ * dateRangeOverlap(range1, range2); // true
18
+ * ```
19
+ */
20
+ export function dateRangeOverlap(range1, range2) {
21
+ return range1.start <= range2.end && range2.start <= range1.end;
22
+ }
23
+ /**
24
+ * Checks if multiple date ranges have any overlaps
25
+ * @param ranges - Array of date ranges
26
+ * @returns True if any two ranges overlap
27
+ *
28
+ * @example
29
+ * ```ts
30
+ * const ranges = [
31
+ * { start: new Date('2024-01-01'), end: new Date('2024-01-10') },
32
+ * { start: new Date('2024-01-05'), end: new Date('2024-01-15') }
33
+ * ];
34
+ *
35
+ * hasOverlappingRanges(ranges); // true
36
+ * ```
37
+ */
38
+ export function hasOverlappingRanges(ranges) {
39
+ for (let i = 0; i < ranges.length; i++) {
40
+ for (let j = i + 1; j < ranges.length; j++) {
41
+ if (dateRangeOverlap(ranges[i], ranges[j])) {
42
+ return true;
43
+ }
44
+ }
45
+ }
46
+ return false;
47
+ }
48
+ /**
49
+ * Merges overlapping or adjacent date ranges
50
+ * @param ranges - Array of date ranges to merge
51
+ * @returns Array of merged, non-overlapping ranges
52
+ *
53
+ * @example
54
+ * ```ts
55
+ * const ranges = [
56
+ * { start: new Date('2024-01-01'), end: new Date('2024-01-10') },
57
+ * { start: new Date('2024-01-05'), end: new Date('2024-01-15') },
58
+ * { start: new Date('2024-01-20'), end: new Date('2024-01-25') }
59
+ * ];
60
+ *
61
+ * mergeDateRanges(ranges);
62
+ * // [
63
+ * // { start: Date('2024-01-01'), end: Date('2024-01-15') },
64
+ * // { start: Date('2024-01-20'), end: Date('2024-01-25') }
65
+ * // ]
66
+ * ```
67
+ */
68
+ export function mergeDateRanges(ranges) {
69
+ if (ranges.length === 0)
70
+ return [];
71
+ // Sort ranges by start date
72
+ const sorted = [...ranges].sort((a, b) => a.start.getTime() - b.start.getTime());
73
+ const merged = [{ ...sorted[0] }];
74
+ for (let i = 1; i < sorted.length; i++) {
75
+ const current = sorted[i];
76
+ const lastMerged = merged[merged.length - 1];
77
+ // Check if current range overlaps or is adjacent to last merged range
78
+ if (current.start <= lastMerged.end ||
79
+ current.start.getTime() === lastMerged.end.getTime() + 1) {
80
+ // Merge by extending the end date if needed
81
+ if (current.end > lastMerged.end) {
82
+ lastMerged.end = new Date(current.end);
83
+ }
84
+ }
85
+ else {
86
+ // No overlap, add as new range
87
+ merged.push({ ...current });
88
+ }
89
+ }
90
+ return merged;
91
+ }
92
+ /**
93
+ * Finds gaps between date ranges within specified bounds
94
+ * @param ranges - Array of date ranges
95
+ * @param bounds - Optional bounds to search within
96
+ * @returns Array of date ranges representing gaps
97
+ *
98
+ * @example
99
+ * ```ts
100
+ * const ranges = [
101
+ * { start: new Date('2024-01-01'), end: new Date('2024-01-05') },
102
+ * { start: new Date('2024-01-10'), end: new Date('2024-01-15') }
103
+ * ];
104
+ *
105
+ * findGaps(ranges, {
106
+ * start: new Date('2024-01-01'),
107
+ * end: new Date('2024-01-20')
108
+ * });
109
+ * // [
110
+ * // { start: Date('2024-01-06'), end: Date('2024-01-09') },
111
+ * // { start: Date('2024-01-16'), end: Date('2024-01-20') }
112
+ * // ]
113
+ * ```
114
+ */
115
+ export function findGaps(ranges, bounds) {
116
+ if (ranges.length === 0) {
117
+ return bounds ? [{ ...bounds }] : [];
118
+ }
119
+ // Merge overlapping ranges first
120
+ const merged = mergeDateRanges(ranges);
121
+ // Sort by start date
122
+ const sorted = merged.sort((a, b) => a.start.getTime() - b.start.getTime());
123
+ const gaps = [];
124
+ // Check gap before first range if bounds provided
125
+ if (bounds && sorted[0].start > bounds.start) {
126
+ gaps.push({
127
+ start: new Date(bounds.start),
128
+ end: addTime(sorted[0].start, -1, 'millisecond')
129
+ });
130
+ }
131
+ // Find gaps between ranges
132
+ for (let i = 0; i < sorted.length - 1; i++) {
133
+ const currentEnd = sorted[i].end;
134
+ const nextStart = sorted[i + 1].start;
135
+ if (nextStart > currentEnd) {
136
+ gaps.push({
137
+ start: addTime(currentEnd, 1, 'day'),
138
+ end: addTime(nextStart, -1, 'day')
139
+ });
140
+ }
141
+ }
142
+ // Check gap after last range if bounds provided
143
+ if (bounds && sorted[sorted.length - 1].end < bounds.end) {
144
+ gaps.push({
145
+ start: addTime(sorted[sorted.length - 1].end, 1, 'millisecond'),
146
+ end: new Date(bounds.end)
147
+ });
148
+ }
149
+ return gaps;
150
+ }
151
+ /**
152
+ * Splits a date range into smaller chunks
153
+ * @param range - The date range to split
154
+ * @param chunkSize - Size of each chunk
155
+ * @param unit - Unit for chunk size
156
+ * @returns Array of date ranges
157
+ *
158
+ * @example
159
+ * ```ts
160
+ * const range = {
161
+ * start: new Date('2024-01-01'),
162
+ * end: new Date('2024-01-10')
163
+ * };
164
+ *
165
+ * splitRange(range, 3, 'day');
166
+ * // Returns 4 ranges: 3 days, 3 days, 3 days, 1 day
167
+ * ```
168
+ */
169
+ export function splitRange(range, chunkSize, unit) {
170
+ const chunks = [];
171
+ let current = new Date(range.start);
172
+ const rangeEnd = new Date(range.end);
173
+ // Keep looping while current hasn't passed the end
174
+ while (current.getTime() <= rangeEnd.getTime()) {
175
+ const chunkEnd = addTime(current, chunkSize, unit);
176
+ // Don't go past the range end
177
+ const effectiveEnd = chunkEnd > rangeEnd ? new Date(rangeEnd) : new Date(chunkEnd);
178
+ chunks.push({
179
+ start: new Date(current),
180
+ end: effectiveEnd
181
+ });
182
+ // Move to the next chunk
183
+ current = chunkEnd;
184
+ // If the next chunk would start after the range end, we're done
185
+ if (current.getTime() > rangeEnd.getTime()) {
186
+ break;
187
+ }
188
+ }
189
+ return chunks;
190
+ }
191
+ /**
192
+ * Checks if a date falls within a date range
193
+ * @param range - The date range
194
+ * @param date - The date to check
195
+ * @param inclusive - Whether to include boundary dates (default: true)
196
+ * @returns True if date is within range
197
+ *
198
+ * @example
199
+ * ```ts
200
+ * const range = {
201
+ * start: new Date('2024-01-01'),
202
+ * end: new Date('2024-01-31')
203
+ * };
204
+ *
205
+ * containsDate(range, new Date('2024-01-15')); // true
206
+ * containsDate(range, new Date('2024-02-01')); // false
207
+ * ```
208
+ */
209
+ export function containsDate(range, date, inclusive = true) {
210
+ const checkDate = new Date(date);
211
+ if (inclusive) {
212
+ return checkDate >= range.start && checkDate <= range.end;
213
+ }
214
+ return checkDate > range.start && checkDate < range.end;
215
+ }
216
+ /**
217
+ * Gets the intersection of two date ranges
218
+ * @param range1 - First date range
219
+ * @param range2 - Second date range
220
+ * @returns The overlapping range, or null if no overlap
221
+ *
222
+ * @example
223
+ * ```ts
224
+ * const range1 = { start: new Date('2024-01-01'), end: new Date('2024-01-15') };
225
+ * const range2 = { start: new Date('2024-01-10'), end: new Date('2024-01-20') };
226
+ *
227
+ * getIntersection(range1, range2);
228
+ * // { start: Date('2024-01-10'), end: Date('2024-01-15') }
229
+ * ```
230
+ */
231
+ export function getIntersection(range1, range2) {
232
+ if (!dateRangeOverlap(range1, range2)) {
233
+ return null;
234
+ }
235
+ return {
236
+ start: new Date(Math.max(range1.start.getTime(), range2.start.getTime())),
237
+ end: new Date(Math.min(range1.end.getTime(), range2.end.getTime()))
238
+ };
239
+ }
240
+ /**
241
+ * Gets the union (combined coverage) of two date ranges
242
+ * @param range1 - First date range
243
+ * @param range2 - Second date range
244
+ * @returns The combined range covering both inputs
245
+ *
246
+ * @example
247
+ * ```ts
248
+ * const range1 = { start: new Date('2024-01-01'), end: new Date('2024-01-15') };
249
+ * const range2 = { start: new Date('2024-01-10'), end: new Date('2024-01-20') };
250
+ *
251
+ * getUnion(range1, range2);
252
+ * // { start: Date('2024-01-01'), end: Date('2024-01-20') }
253
+ * ```
254
+ */
255
+ export function getUnion(range1, range2) {
256
+ return {
257
+ start: new Date(Math.min(range1.start.getTime(), range2.start.getTime())),
258
+ end: new Date(Math.max(range1.end.getTime(), range2.end.getTime()))
259
+ };
260
+ }
261
+ /**
262
+ * Subtracts one date range from another
263
+ * @param range - The range to subtract from
264
+ * @param subtract - The range to subtract
265
+ * @returns Array of remaining date ranges (0-2 ranges)
266
+ *
267
+ * @example
268
+ * ```ts
269
+ * const range = { start: new Date('2024-01-01'), end: new Date('2024-01-31') };
270
+ * const subtract = { start: new Date('2024-01-10'), end: new Date('2024-01-20') };
271
+ *
272
+ * subtractRange(range, subtract);
273
+ * // [
274
+ * // { start: Date('2024-01-01'), end: Date('2024-01-09') },
275
+ * // { start: Date('2024-01-21'), end: Date('2024-01-31') }
276
+ * // ]
277
+ * ```
278
+ */
279
+ export function subtractRange(range, subtract) {
280
+ // No overlap, return original range
281
+ if (!dateRangeOverlap(range, subtract)) {
282
+ return [{ ...range }];
283
+ }
284
+ const result = [];
285
+ // Check if there's a range before the subtraction
286
+ if (range.start < subtract.start) {
287
+ result.push({
288
+ start: new Date(range.start),
289
+ end: addTime(subtract.start, -1, 'day')
290
+ });
291
+ }
292
+ // Check if there's a range after the subtraction
293
+ if (range.end > subtract.end) {
294
+ result.push({
295
+ start: addTime(subtract.end, 1, 'day'),
296
+ end: new Date(range.end)
297
+ });
298
+ }
299
+ return result;
300
+ }
301
+ /**
302
+ * Calculates the duration of a date range in milliseconds
303
+ * @param range - The date range
304
+ * @returns Duration in milliseconds
305
+ *
306
+ * @example
307
+ * ```ts
308
+ * const range = {
309
+ * start: new Date('2024-01-01'),
310
+ * end: new Date('2024-01-02')
311
+ * };
312
+ *
313
+ * getRangeDuration(range); // 86400000 (1 day in ms)
314
+ * ```
315
+ */
316
+ export function getRangeDuration(range) {
317
+ return range.end.getTime() - range.start.getTime();
318
+ }
319
+ /**
320
+ * Expands a date range by a specified amount
321
+ * @param range - The date range to expand
322
+ * @param amount - Amount to expand by
323
+ * @param unit - Unit for expansion
324
+ * @param options - Expansion options
325
+ * @returns Expanded date range
326
+ *
327
+ * @example
328
+ * ```ts
329
+ * const range = {
330
+ * start: new Date('2024-01-10'),
331
+ * end: new Date('2024-01-20')
332
+ * };
333
+ *
334
+ * expandRange(range, 5, 'day');
335
+ * // { start: Date('2024-01-05'), end: Date('2024-01-25') }
336
+ *
337
+ * expandRange(range, 5, 'day', { direction: 'before' });
338
+ * // { start: Date('2024-01-05'), end: Date('2024-01-20') }
339
+ * ```
340
+ */
341
+ export function expandRange(range, amount, unit, options = {}) {
342
+ const { direction = 'both' } = options;
343
+ let newStart = new Date(range.start);
344
+ let newEnd = new Date(range.end);
345
+ if (direction === 'both' || direction === 'before') {
346
+ newStart = addTime(newStart, -amount, unit);
347
+ }
348
+ if (direction === 'both' || direction === 'after') {
349
+ newEnd = addTime(newEnd, amount, unit);
350
+ }
351
+ return {
352
+ start: newStart,
353
+ end: newEnd
354
+ };
355
+ }
356
+ /**
357
+ * Shrinks a date range by a specified amount
358
+ * @param range - The date range to shrink
359
+ * @param amount - Amount to shrink by
360
+ * @param unit - Unit for shrinking
361
+ * @param options - Shrink options
362
+ * @returns Shrunk date range, or null if result would be invalid
363
+ *
364
+ * @example
365
+ * ```ts
366
+ * const range = {
367
+ * start: new Date('2024-01-01'),
368
+ * end: new Date('2024-01-31')
369
+ * };
370
+ *
371
+ * shrinkRange(range, 5, 'day');
372
+ * // { start: Date('2024-01-06'), end: Date('2024-01-26') }
373
+ * ```
374
+ */
375
+ export function shrinkRange(range, amount, unit, options = {}) {
376
+ const { direction = 'both' } = options;
377
+ let newStart = new Date(range.start);
378
+ let newEnd = new Date(range.end);
379
+ if (direction === 'both' || direction === 'start') {
380
+ newStart = addTime(newStart, amount, unit);
381
+ }
382
+ if (direction === 'both' || direction === 'end') {
383
+ newEnd = addTime(newEnd, -amount, unit);
384
+ }
385
+ // Check if result is valid
386
+ if (newStart >= newEnd) {
387
+ return null;
388
+ }
389
+ return {
390
+ start: newStart,
391
+ end: newEnd
392
+ };
393
+ }
394
+ /**
395
+ * Checks if one date range completely contains another
396
+ * @param outer - The potentially containing range
397
+ * @param inner - The potentially contained range
398
+ * @returns True if outer completely contains inner
399
+ *
400
+ * @example
401
+ * ```ts
402
+ * const outer = { start: new Date('2024-01-01'), end: new Date('2024-01-31') };
403
+ * const inner = { start: new Date('2024-01-10'), end: new Date('2024-01-20') };
404
+ *
405
+ * rangeContains(outer, inner); // true
406
+ * ```
407
+ */
408
+ export function rangeContains(outer, inner) {
409
+ return outer.start <= inner.start && outer.end >= inner.end;
410
+ }
411
+ /**
412
+ * Sorts an array of date ranges by start date
413
+ * @param ranges - Array of date ranges
414
+ * @param order - Sort order ('asc' or 'desc')
415
+ * @returns Sorted array of date ranges
416
+ *
417
+ * @example
418
+ * ```ts
419
+ * const ranges = [
420
+ * { start: new Date('2024-01-15'), end: new Date('2024-01-20') },
421
+ * { start: new Date('2024-01-01'), end: new Date('2024-01-10') }
422
+ * ];
423
+ *
424
+ * sortRanges(ranges); // Sorted by start date ascending
425
+ * ```
426
+ */
427
+ export function sortRanges(ranges, order = 'asc') {
428
+ const sorted = [...ranges].sort((a, b) => {
429
+ const diff = a.start.getTime() - b.start.getTime();
430
+ return order === 'asc' ? diff : -diff;
431
+ });
432
+ return sorted;
433
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"calculate.d.ts","sourceRoot":"","sources":["../../src/calculate.ts"],"names":[],"mappings":"AAAA,OAAO,EAQL,QAAQ,EACT,MAAM,gBAAgB,CAAC;AAExB;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,IAAI,EACX,KAAK,EAAE,IAAI,EACX,IAAI,GAAE,QAAyB,EAC/B,OAAO,GAAE,OAAc,GACtB,MAAM,CAkCR;AAED;;;;;GAKG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,GAAG,IAAI,CAmCxE;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,GAAG,IAAI,CAE7E;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,GAAG,IAAI,CA4BrG;AAED;;;;GAIG;AACH,wBAAgB,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,GAAG,IAAI,CA4BnG;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,GAAG,OAAO,CAGrE;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,GAAG,MAAM,CAa1E"}
1
+ {"version":3,"file":"calculate.d.ts","sourceRoot":"","sources":["../../src/calculate.ts"],"names":[],"mappings":"AAAA,OAAO,EAQL,QAAQ,EACT,MAAM,gBAAgB,CAAC;AAExB;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,IAAI,EACX,KAAK,EAAE,IAAI,EACX,IAAI,GAAE,QAAyB,EAC/B,OAAO,GAAE,OAAc,GACtB,MAAM,CAkCR;AAED;;;;;GAKG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,GAAG,IAAI,CAgDxE;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,GAAG,IAAI,CAE7E;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,GAAG,IAAI,CA4BrG;AAED;;;;GAIG;AACH,wBAAgB,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,GAAG,IAAI,CA4BnG;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,GAAG,OAAO,CAGrE;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,GAAG,MAAM,CAa1E"}
@@ -46,35 +46,49 @@ export function differenceInUnits(date1, date2, unit = 'milliseconds', precise =
46
46
  */
47
47
  export function addTime(date, amount, unit) {
48
48
  const result = new Date(date);
49
- let milliseconds;
50
49
  switch (unit) {
50
+ case 'year':
51
51
  case 'years':
52
- milliseconds = amount * MILLISECONDS_PER_YEAR;
52
+ case 'y':
53
+ result.setFullYear(result.getFullYear() + amount);
53
54
  break;
55
+ case 'month':
54
56
  case 'months':
55
- milliseconds = amount * MILLISECONDS_PER_MONTH;
57
+ case 'M':
58
+ result.setMonth(result.getMonth() + amount);
56
59
  break;
60
+ case 'week':
57
61
  case 'weeks':
58
- milliseconds = amount * MILLISECONDS_PER_WEEK;
62
+ case 'w':
63
+ result.setDate(result.getDate() + (amount * 7));
59
64
  break;
65
+ case 'day':
60
66
  case 'days':
61
- milliseconds = amount * MILLISECONDS_PER_DAY;
67
+ case 'd':
68
+ result.setDate(result.getDate() + amount);
62
69
  break;
70
+ case 'hour':
63
71
  case 'hours':
64
- milliseconds = amount * MILLISECONDS_PER_HOUR;
72
+ case 'h':
73
+ result.setHours(result.getHours() + amount);
65
74
  break;
75
+ case 'minute':
66
76
  case 'minutes':
67
- milliseconds = amount * MILLISECONDS_PER_MINUTE;
77
+ case 'm':
78
+ result.setMinutes(result.getMinutes() + amount);
68
79
  break;
80
+ case 'second':
69
81
  case 'seconds':
70
- milliseconds = amount * MILLISECONDS_PER_SECOND;
82
+ case 's':
83
+ result.setSeconds(result.getSeconds() + amount);
71
84
  break;
85
+ case 'millisecond':
72
86
  case 'milliseconds':
87
+ case 'ms':
73
88
  default:
74
- milliseconds = amount;
89
+ result.setMilliseconds(result.getMilliseconds() + amount);
75
90
  break;
76
91
  }
77
- result.setTime(result.getTime() + milliseconds);
78
92
  return result;
79
93
  }
80
94
  /**