/
Duration.js
165 lines (142 loc) · 3.86 KB
/
Duration.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
/** @type {number} */
const SECONDS_PER_MINUTE = 60;
/** @type {number} */
const SECONDS_PER_HOUR = SECONDS_PER_MINUTE * 60;
/** @type {number} */
const SECONDS_PER_DAY = SECONDS_PER_HOUR * 24;
/** @type {number} */
const SECONDS_PER_WEEK = SECONDS_PER_DAY * 7;
/** @type {number} */
const SECONDS_PER_YEAR = SECONDS_PER_DAY * 365;
/** @type {number} */
const SECONDS_PER_MONTH = SECONDS_PER_YEAR / 12;
/**
* Inspired by Rails' ActiveSupport::Duration.
* Provides accurate date and time measurements.
* @example
* // Retuns a Date with the timestamp for a month before the current date and time.
* (1).month.ago
*/
class Duration {
/** @returns {Number} the number of seconds in a minute. */
static get SECONDS_PER_MINUTE() {
return SECONDS_PER_MINUTE;
}
/** @returns {Number} the number of seconds in an hour. */
static get SECONDS_PER_HOUR() {
return SECONDS_PER_HOUR;
}
/** @returns {Number} the number of seconds in a day. */
static get SECONDS_PER_DAY() {
return SECONDS_PER_DAY;
}
/** @returns {Number} the number of seconds in a week. */
static get SECONDS_PER_WEEK() {
return SECONDS_PER_WEEK;
}
/**
* @returns {Number} the number of seconds in a month.
* Note: for this purpose, a month is presumed to be 1/12th of a year.
* */
static get SECONDS_PER_MONTH() {
return SECONDS_PER_MONTH;
}
/**
* @returns {Number} the number of seconds in a month.
* Note: for this purpose, a year is presumed to be 365 days.
* */
static get SECONDS_PER_YEAR() {
return SECONDS_PER_YEAR;
}
/**
* @param {Number} seconds The number of seconds the Duration represents.
* @returns {Duration} An object representing a span of time.
*/
constructor(seconds) {
/** @type {number} The number of seconds the Duration represents. */
this.seconds = seconds;
}
/** @returns {Number} the number of millisends in this duration. */
get asMilliseconds() {
return this.seconds * 1000;
}
/** @returns {Number} the number of minutes in this duration. */
get asMinutes() {
return this.seconds / SECONDS_PER_MINUTE;
}
/** @returns {Number} the number of hours in this duration. */
get asHours() {
return this.seconds / SECONDS_PER_HOUR;
}
/** @returns {Number} the number of days in this duration. */
get asDays() {
return this.seconds / SECONDS_PER_DAY;
}
/** @returns {Number} the number of weeks in this duration. */
get asWeeks() {
return this.seconds / SECONDS_PER_WEEK;
}
/** @returns {Number} the number of months in this duration. */
get asMonths() {
return this.seconds / SECONDS_PER_MONTH;
}
/** @returns {Number} the number of years in this duration. */
get asYears() {
return this.seconds / SECONDS_PER_YEAR;
}
/**
* A Date in the future of the given Date, or new Date() if not supplied
* @param {Date} [date=new Date()]
* @returns {Date}
*/
since(date = new Date()) {
return new Date(date + this.asMilliseconds);
}
/**
* Alias of since
* @param {Date} [date=new Date()]
* @returns {Date}
*/
fromNow(date) {
return this.since(date);
}
/**
* Alias of since
* @param {Date} [date=new Date()]
* @returns {Date}
*/
after(date) {
return this.since(date);
}
/**
* A Date in the past of the given Date, or new Date() if not supplied
* @param {Date} [date=new Date()]
* @returns {Date}
*/
ago(date = new Date()) {
return new Date(date - this.asMilliseconds);
}
/**
* Alias of ago
* @param {Date} [date=new Date()]
* @returns {Date}
*/
until(date) {
return this.ago(date);
}
/**
* Alias of ago
* @param {Date} [date=new Date()]
* @returns {Date}
*/
before(date) {
return this.ago(date);
}
/**
* @returns {Number} The number of seconds represented by this Duration.
*/
valueOf() {
return this.seconds;
}
}
module.exports = Duration;