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 DateDuration
& duration
);
105 * IsValidDuration ( years, months, weeks, days, hours, minutes, seconds,
106 * milliseconds, microseconds, nanoseconds )
108 bool IsValidDuration(const NormalizedDuration
& duration
);
112 * IsValidDuration ( years, months, weeks, days, hours, minutes, seconds,
113 * milliseconds, microseconds, nanoseconds )
115 bool ThrowIfInvalidDuration(JSContext
* cx
, const Duration
& duration
);
118 * IsValidDuration ( years, months, weeks, days, hours, minutes, seconds,
119 * milliseconds, microseconds, nanoseconds )
121 bool ThrowIfInvalidDuration(JSContext
* cx
, const DateDuration
& duration
);
124 * IsValidDuration ( years, months, weeks, days, hours, minutes, seconds,
125 * milliseconds, microseconds, nanoseconds )
127 inline bool IsValidNormalizedTimeDuration(
128 const NormalizedTimeDuration
& duration
) {
129 MOZ_ASSERT(0 <= duration
.nanoseconds
&& duration
.nanoseconds
<= 999'999'999);
133 // The absolute value of the seconds part of normalized time duration must be
134 // less-or-equal to `2**53 - 1` and the nanoseconds part must be less or equal
136 return NormalizedTimeDuration::min() <= duration
&&
137 duration
<= NormalizedTimeDuration::max();
141 * NormalizeTimeDuration ( hours, minutes, seconds, milliseconds, microseconds,
144 NormalizedTimeDuration
NormalizeTimeDuration(int32_t hours
, int32_t minutes
,
146 int32_t milliseconds
,
147 int32_t microseconds
,
148 int32_t nanoseconds
);
151 * NormalizeTimeDuration ( hours, minutes, seconds, milliseconds, microseconds,
154 NormalizedTimeDuration
NormalizeTimeDuration(const Duration
& duration
);
157 * CompareNormalizedTimeDuration ( one, two )
159 inline int32_t CompareNormalizedTimeDuration(
160 const NormalizedTimeDuration
& one
, const NormalizedTimeDuration
& two
) {
161 MOZ_ASSERT(IsValidNormalizedTimeDuration(one
));
162 MOZ_ASSERT(IsValidNormalizedTimeDuration(two
));
179 * NormalizedTimeDurationSign ( d )
181 inline int32_t NormalizedTimeDurationSign(const NormalizedTimeDuration
& d
) {
182 MOZ_ASSERT(IsValidNormalizedTimeDuration(d
));
185 return CompareNormalizedTimeDuration(d
, NormalizedTimeDuration
{});
189 * Add24HourDaysToNormalizedTimeDuration ( d, days )
191 bool Add24HourDaysToNormalizedTimeDuration(JSContext
* cx
,
192 const NormalizedTimeDuration
& d
,
194 NormalizedTimeDuration
* result
);
197 * CreateNormalizedDurationRecord ( years, months, weeks, days, norm )
199 inline NormalizedDuration
CreateNormalizedDurationRecord(
200 const DateDuration
& date
, const NormalizedTimeDuration
& time
) {
201 MOZ_ASSERT(IsValidDuration(date
));
202 MOZ_ASSERT(IsValidNormalizedTimeDuration(time
));
204 int64_t dateValues
= date
.years
| date
.months
| date
.weeks
| date
.days
;
205 int32_t dateSign
= dateValues
? dateValues
< 0 ? -1 : 1 : 0;
206 int32_t timeSign
= NormalizedTimeDurationSign(time
);
207 MOZ_ASSERT((dateSign
* timeSign
) >= 0);
214 * CreateNormalizedDurationRecord ( years, months, weeks, days, norm )
216 inline NormalizedDuration
CreateNormalizedDurationRecord(
217 const Duration
& duration
) {
218 return CreateNormalizedDurationRecord(duration
.toDateDuration(),
219 NormalizeTimeDuration(duration
));
223 * CombineDateAndNormalizedTimeDuration ( dateDurationRecord, norm )
225 bool CombineDateAndNormalizedTimeDuration(JSContext
* cx
,
226 const DateDuration
& date
,
227 const NormalizedTimeDuration
& time
,
228 NormalizedDuration
* result
);
231 * CreateNormalizedDurationRecord ( years, months, weeks, days, norm )
233 inline bool CreateNormalizedDurationRecord(JSContext
* cx
,
234 const DateDuration
& date
,
235 const NormalizedTimeDuration
& time
,
236 NormalizedDuration
* result
) {
237 return CombineDateAndNormalizedTimeDuration(cx
, date
, time
, result
);
241 * NormalizedTimeDurationFromEpochNanosecondsDifference ( one, two )
243 NormalizedTimeDuration
NormalizedTimeDurationFromEpochNanosecondsDifference(
244 const Instant
& one
, const Instant
& two
);
247 * CreateTemporalDuration ( years, months, weeks, days, hours, minutes, seconds,
248 * milliseconds, microseconds, nanoseconds [ , newTarget ] )
250 DurationObject
* CreateTemporalDuration(JSContext
* cx
, const Duration
& duration
);
253 * ToTemporalDuration ( item )
255 Wrapped
<DurationObject
*> ToTemporalDuration(JSContext
* cx
,
256 JS::Handle
<JS::Value
> item
);
259 * ToTemporalDuration ( item )
261 bool ToTemporalDuration(JSContext
* cx
, JS::Handle
<JS::Value
> item
,
265 * ToTemporalDurationRecord ( temporalDurationLike )
267 bool ToTemporalDurationRecord(JSContext
* cx
,
268 JS::Handle
<JS::Value
> temporalDurationLike
,
272 * BalanceTimeDuration ( norm, largestUnit )
274 TimeDuration
BalanceTimeDuration(const NormalizedTimeDuration
& duration
,
275 TemporalUnit largestUnit
);
278 * BalanceTimeDuration ( norm, largestUnit )
280 bool BalanceTimeDuration(JSContext
* cx
, const NormalizedTimeDuration
& duration
,
281 TemporalUnit largestUnit
, TimeDuration
* result
);
284 * BalanceDateDurationRelative ( years, months, weeks, days, largestUnit,
285 * smallestUnit, plainRelativeTo, calendarRec )
287 bool BalanceDateDurationRelative(
288 JSContext
* cx
, const DateDuration
& duration
, TemporalUnit largestUnit
,
289 TemporalUnit smallestUnit
,
290 JS::Handle
<Wrapped
<PlainDateObject
*>> plainRelativeTo
,
291 JS::Handle
<CalendarRecord
> calendar
, DateDuration
* result
);
294 * AdjustRoundedDurationDays ( years, months, weeks, days, norm, increment,
295 * unit, roundingMode, zonedRelativeTo, calendarRec, timeZoneRec,
296 * precalculatedPlainDateTime )
298 bool AdjustRoundedDurationDays(JSContext
* cx
,
299 const NormalizedDuration
& duration
,
300 Increment increment
, TemporalUnit unit
,
301 TemporalRoundingMode roundingMode
,
302 JS::Handle
<ZonedDateTime
> relativeTo
,
303 JS::Handle
<CalendarRecord
> calendar
,
304 JS::Handle
<TimeZoneRecord
> timeZone
,
305 const PlainDateTime
& precalculatedPlainDateTime
,
306 NormalizedDuration
* result
);
309 * RoundDuration ( years, months, weeks, days, norm, increment, unit,
310 * roundingMode [ , plainRelativeTo [ , calendarRec [ , zonedRelativeTo [ ,
311 * timeZoneRec [ , precalculatedPlainDateTime ] ] ] ] ] )
313 NormalizedTimeDuration
RoundDuration(const NormalizedTimeDuration
& duration
,
314 Increment increment
, TemporalUnit unit
,
315 TemporalRoundingMode roundingMode
);
318 * RoundDuration ( years, months, weeks, days, norm, increment, unit,
319 * roundingMode [ , plainRelativeTo [ , calendarRec [ , zonedRelativeTo [ ,
320 * timeZoneRec [ , precalculatedPlainDateTime ] ] ] ] ] )
322 bool RoundDuration(JSContext
* cx
, const NormalizedTimeDuration
& duration
,
323 Increment increment
, TemporalUnit unit
,
324 TemporalRoundingMode roundingMode
,
325 NormalizedTimeDuration
* result
);
328 * RoundDuration ( years, months, weeks, days, norm, increment, unit,
329 * roundingMode [ , plainRelativeTo [ , calendarRec [ , zonedRelativeTo [ ,
330 * timeZoneRec [ , precalculatedPlainDateTime ] ] ] ] ] )
332 bool RoundDuration(JSContext
* cx
, const NormalizedDuration
& duration
,
333 Increment increment
, TemporalUnit unit
,
334 TemporalRoundingMode roundingMode
,
335 JS::Handle
<Wrapped
<PlainDateObject
*>> plainRelativeTo
,
336 JS::Handle
<CalendarRecord
> calendar
,
337 NormalizedDuration
* result
);
340 * RoundDuration ( years, months, weeks, days, norm, increment, unit,
341 * roundingMode [ , plainRelativeTo [ , calendarRec [ , zonedRelativeTo [ ,
342 * timeZoneRec [ , precalculatedPlainDateTime ] ] ] ] ] )
344 bool RoundDuration(JSContext
* cx
, const NormalizedDuration
& duration
,
345 Increment increment
, TemporalUnit unit
,
346 TemporalRoundingMode roundingMode
,
347 JS::Handle
<PlainDateObject
*> plainRelativeTo
,
348 JS::Handle
<CalendarRecord
> calendar
,
349 JS::Handle
<ZonedDateTime
> zonedRelativeTo
,
350 JS::Handle
<TimeZoneRecord
> timeZone
,
351 const PlainDateTime
& precalculatedPlainDateTime
,
352 NormalizedDuration
* result
);
355 * DaysUntil ( earlier, later )
357 int32_t DaysUntil(const PlainDate
& earlier
, const PlainDate
& later
);
359 } /* namespace js::temporal */
361 #endif /* builtin_temporal_Duration_h */