1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * vim: set ts=8 sts=2 et sw=2 tw=80:
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef builtin_temporal_Duration_h
8 #define builtin_temporal_Duration_h
12 #include "builtin/temporal/TemporalTypes.h"
13 #include "builtin/temporal/Wrapped.h"
14 #include "js/RootingAPI.h"
15 #include "js/TypeDecls.h"
17 #include "vm/NativeObject.h"
23 namespace js::temporal
{
25 class DurationObject
: public NativeObject
{
27 static const JSClass class_
;
28 static const JSClass
& protoClass_
;
30 static constexpr uint32_t YEARS_SLOT
= 0;
31 static constexpr uint32_t MONTHS_SLOT
= 1;
32 static constexpr uint32_t WEEKS_SLOT
= 2;
33 static constexpr uint32_t DAYS_SLOT
= 3;
34 static constexpr uint32_t HOURS_SLOT
= 4;
35 static constexpr uint32_t MINUTES_SLOT
= 5;
36 static constexpr uint32_t SECONDS_SLOT
= 6;
37 static constexpr uint32_t MILLISECONDS_SLOT
= 7;
38 static constexpr uint32_t MICROSECONDS_SLOT
= 8;
39 static constexpr uint32_t NANOSECONDS_SLOT
= 9;
40 static constexpr uint32_t SLOT_COUNT
= 10;
42 double years() const { return getFixedSlot(YEARS_SLOT
).toNumber(); }
43 double months() const { return getFixedSlot(MONTHS_SLOT
).toNumber(); }
44 double weeks() const { return getFixedSlot(WEEKS_SLOT
).toNumber(); }
45 double days() const { return getFixedSlot(DAYS_SLOT
).toNumber(); }
46 double hours() const { return getFixedSlot(HOURS_SLOT
).toNumber(); }
47 double minutes() const { return getFixedSlot(MINUTES_SLOT
).toNumber(); }
48 double seconds() const { return getFixedSlot(SECONDS_SLOT
).toNumber(); }
49 double milliseconds() const {
50 return getFixedSlot(MILLISECONDS_SLOT
).toNumber();
52 double microseconds() const {
53 return getFixedSlot(MICROSECONDS_SLOT
).toNumber();
55 double nanoseconds() const {
56 return getFixedSlot(NANOSECONDS_SLOT
).toNumber();
60 static const ClassSpec classSpec_
;
64 * Extract the duration fields from the Duration object.
66 inline Duration
ToDuration(const DurationObject
* duration
) {
68 duration
->years(), duration
->months(),
69 duration
->weeks(), duration
->days(),
70 duration
->hours(), duration
->minutes(),
71 duration
->seconds(), duration
->milliseconds(),
72 duration
->microseconds(), duration
->nanoseconds(),
78 class PlainDateObject
;
81 class ZonedDateTimeObject
;
82 enum class TemporalRoundingMode
;
83 enum class TemporalUnit
;
86 * DurationSign ( years, months, weeks, days, hours, minutes, seconds,
87 * milliseconds, microseconds, nanoseconds )
89 int32_t DurationSign(const Duration
& duration
);
92 * IsValidDuration ( years, months, weeks, days, hours, minutes, seconds,
93 * milliseconds, microseconds, nanoseconds )
95 bool IsValidDuration(const Duration
& duration
);
99 * IsValidDuration ( years, months, weeks, days, hours, minutes, seconds,
100 * milliseconds, microseconds, nanoseconds )
102 bool IsValidDuration(const NormalizedDuration
& duration
);
106 * IsValidDuration ( years, months, weeks, days, hours, minutes, seconds,
107 * milliseconds, microseconds, nanoseconds )
109 bool ThrowIfInvalidDuration(JSContext
* cx
, const Duration
& duration
);
112 * IsValidDuration ( years, months, weeks, days, hours, minutes, seconds,
113 * milliseconds, microseconds, nanoseconds )
115 inline bool IsValidNormalizedTimeDuration(
116 const NormalizedTimeDuration
& duration
) {
117 MOZ_ASSERT(0 <= duration
.nanoseconds
&& duration
.nanoseconds
<= 999'999'999);
121 // The absolute value of the seconds part of normalized time duration must be
122 // less-or-equal to `2**53 - 1` and the nanoseconds part must be less or equal
124 return NormalizedTimeDuration::min() <= duration
&&
125 duration
<= NormalizedTimeDuration::max();
129 * NormalizeTimeDuration ( hours, minutes, seconds, milliseconds, microseconds,
132 NormalizedTimeDuration
NormalizeTimeDuration(int32_t hours
, int32_t minutes
,
134 int32_t milliseconds
,
135 int32_t microseconds
,
136 int32_t nanoseconds
);
139 * NormalizeTimeDuration ( hours, minutes, seconds, milliseconds, microseconds,
142 NormalizedTimeDuration
NormalizeTimeDuration(const Duration
& duration
);
145 * CompareNormalizedTimeDuration ( one, two )
147 inline int32_t CompareNormalizedTimeDuration(
148 const NormalizedTimeDuration
& one
, const NormalizedTimeDuration
& two
) {
149 MOZ_ASSERT(IsValidNormalizedTimeDuration(one
));
150 MOZ_ASSERT(IsValidNormalizedTimeDuration(two
));
167 * NormalizedTimeDurationSign ( d )
169 inline int32_t NormalizedTimeDurationSign(const NormalizedTimeDuration
& d
) {
170 MOZ_ASSERT(IsValidNormalizedTimeDuration(d
));
173 return CompareNormalizedTimeDuration(d
, NormalizedTimeDuration
{});
177 * Add24HourDaysToNormalizedTimeDuration ( d, days )
179 bool Add24HourDaysToNormalizedTimeDuration(JSContext
* cx
,
180 const NormalizedTimeDuration
& d
,
182 NormalizedTimeDuration
* result
);
185 * CreateNormalizedDurationRecord ( years, months, weeks, days, norm )
187 inline NormalizedDuration
CreateNormalizedDurationRecord(
188 const DateDuration
& date
, const NormalizedTimeDuration
& time
) {
189 MOZ_ASSERT(IsValidDuration(date
.toDuration()));
190 MOZ_ASSERT(IsValidNormalizedTimeDuration(time
));
192 int64_t dateValues
= date
.years
| date
.months
| date
.weeks
| date
.days
;
193 int32_t dateSign
= dateValues
? dateValues
< 0 ? -1 : 1 : 0;
194 int32_t timeSign
= NormalizedTimeDurationSign(time
);
195 MOZ_ASSERT((dateSign
* timeSign
) >= 0);
202 * CreateNormalizedDurationRecord ( years, months, weeks, days, norm )
204 inline NormalizedDuration
CreateNormalizedDurationRecord(
205 const Duration
& duration
) {
206 return CreateNormalizedDurationRecord(duration
.toDateDuration(),
207 NormalizeTimeDuration(duration
));
211 * CombineDateAndNormalizedTimeDuration ( dateDurationRecord, norm )
213 bool CombineDateAndNormalizedTimeDuration(JSContext
* cx
,
214 const DateDuration
& date
,
215 const NormalizedTimeDuration
& time
,
216 NormalizedDuration
* result
);
219 * CreateNormalizedDurationRecord ( years, months, weeks, days, norm )
221 inline bool CreateNormalizedDurationRecord(JSContext
* cx
,
222 const DateDuration
& date
,
223 const NormalizedTimeDuration
& time
,
224 NormalizedDuration
* result
) {
225 return CombineDateAndNormalizedTimeDuration(cx
, date
, time
, result
);
229 * NormalizedTimeDurationFromEpochNanosecondsDifference ( one, two )
231 NormalizedTimeDuration
NormalizedTimeDurationFromEpochNanosecondsDifference(
232 const Instant
& one
, const Instant
& two
);
235 * CreateTemporalDuration ( years, months, weeks, days, hours, minutes, seconds,
236 * milliseconds, microseconds, nanoseconds [ , newTarget ] )
238 DurationObject
* CreateTemporalDuration(JSContext
* cx
, const Duration
& duration
);
241 * ToTemporalDuration ( item )
243 Wrapped
<DurationObject
*> ToTemporalDuration(JSContext
* cx
,
244 JS::Handle
<JS::Value
> item
);
247 * ToTemporalDuration ( item )
249 bool ToTemporalDuration(JSContext
* cx
, JS::Handle
<JS::Value
> item
,
253 * ToTemporalDurationRecord ( temporalDurationLike )
255 bool ToTemporalDurationRecord(JSContext
* cx
,
256 JS::Handle
<JS::Value
> temporalDurationLike
,
260 * BalanceTimeDuration ( norm, largestUnit )
262 TimeDuration
BalanceTimeDuration(const NormalizedTimeDuration
& duration
,
263 TemporalUnit largestUnit
);
266 * BalanceDateDurationRelative ( years, months, weeks, days, largestUnit,
267 * smallestUnit, plainRelativeTo, calendarRec )
269 bool BalanceDateDurationRelative(
270 JSContext
* cx
, const DateDuration
& duration
, TemporalUnit largestUnit
,
271 TemporalUnit smallestUnit
,
272 JS::Handle
<Wrapped
<PlainDateObject
*>> plainRelativeTo
,
273 JS::Handle
<CalendarRecord
> calendar
, DateDuration
* result
);
276 * AdjustRoundedDurationDays ( years, months, weeks, days, norm, increment,
277 * unit, roundingMode, zonedRelativeTo, calendarRec, timeZoneRec,
278 * precalculatedPlainDateTime )
280 bool AdjustRoundedDurationDays(JSContext
* cx
,
281 const NormalizedDuration
& duration
,
282 Increment increment
, TemporalUnit unit
,
283 TemporalRoundingMode roundingMode
,
284 JS::Handle
<ZonedDateTime
> relativeTo
,
285 JS::Handle
<CalendarRecord
> calendar
,
286 JS::Handle
<TimeZoneRecord
> timeZone
,
287 const PlainDateTime
& precalculatedPlainDateTime
,
288 NormalizedDuration
* result
);
291 * RoundDuration ( years, months, weeks, days, norm, increment, unit,
292 * roundingMode [ , plainRelativeTo [ , calendarRec [ , zonedRelativeTo [ ,
293 * timeZoneRec [ , precalculatedPlainDateTime ] ] ] ] ] )
295 NormalizedTimeDuration
RoundDuration(const NormalizedTimeDuration
& duration
,
296 Increment increment
, TemporalUnit unit
,
297 TemporalRoundingMode roundingMode
);
300 * RoundDuration ( years, months, weeks, days, norm, increment, unit,
301 * roundingMode [ , plainRelativeTo [ , calendarRec [ , zonedRelativeTo [ ,
302 * timeZoneRec [ , precalculatedPlainDateTime ] ] ] ] ] )
304 bool RoundDuration(JSContext
* cx
, const NormalizedDuration
& duration
,
305 Increment increment
, TemporalUnit unit
,
306 TemporalRoundingMode roundingMode
,
307 JS::Handle
<Wrapped
<PlainDateObject
*>> plainRelativeTo
,
308 JS::Handle
<CalendarRecord
> calendar
,
309 NormalizedDuration
* result
);
312 * RoundDuration ( years, months, weeks, days, norm, increment, unit,
313 * roundingMode [ , plainRelativeTo [ , calendarRec [ , zonedRelativeTo [ ,
314 * timeZoneRec [ , precalculatedPlainDateTime ] ] ] ] ] )
316 bool RoundDuration(JSContext
* cx
, const NormalizedDuration
& duration
,
317 Increment increment
, TemporalUnit unit
,
318 TemporalRoundingMode roundingMode
,
319 JS::Handle
<PlainDateObject
*> plainRelativeTo
,
320 JS::Handle
<CalendarRecord
> calendar
,
321 JS::Handle
<ZonedDateTime
> zonedRelativeTo
,
322 JS::Handle
<TimeZoneRecord
> timeZone
,
323 const PlainDateTime
& precalculatedPlainDateTime
,
324 NormalizedDuration
* result
);
327 * DaysUntil ( earlier, later )
329 int32_t DaysUntil(const PlainDate
& earlier
, const PlainDate
& later
);
331 } /* namespace js::temporal */
333 #endif /* builtin_temporal_Duration_h */