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_ZonedDateTime_h
8 #define builtin_temporal_ZonedDateTime_h
10 #include "mozilla/Assertions.h"
11 #include "mozilla/Attributes.h"
15 #include "builtin/temporal/Calendar.h"
16 #include "builtin/temporal/Instant.h"
17 #include "builtin/temporal/TemporalTypes.h"
18 #include "builtin/temporal/TimeZone.h"
19 #include "js/RootingAPI.h"
20 #include "js/TypeDecls.h"
22 #include "vm/NativeObject.h"
24 class JS_PUBLIC_API JSTracer
;
30 namespace js::temporal
{
32 class ZonedDateTimeObject
: public NativeObject
{
34 static const JSClass class_
;
35 static const JSClass
& protoClass_
;
37 static constexpr uint32_t SECONDS_SLOT
= 0;
38 static constexpr uint32_t NANOSECONDS_SLOT
= 1;
39 static constexpr uint32_t TIMEZONE_SLOT
= 2;
40 static constexpr uint32_t CALENDAR_SLOT
= 3;
41 static constexpr uint32_t SLOT_COUNT
= 4;
43 int64_t seconds() const {
44 double seconds
= getFixedSlot(SECONDS_SLOT
).toNumber();
45 MOZ_ASSERT(-8'640'000'000'000 <= seconds
&& seconds
<= 8'640'000'000'000);
46 return int64_t(seconds
);
49 int32_t nanoseconds() const {
50 int32_t nanoseconds
= getFixedSlot(NANOSECONDS_SLOT
).toInt32();
51 MOZ_ASSERT(0 <= nanoseconds
&& nanoseconds
<= 999'999'999);
55 TimeZoneValue
timeZone() const {
56 return TimeZoneValue(getFixedSlot(TIMEZONE_SLOT
));
59 CalendarValue
calendar() const {
60 return CalendarValue(getFixedSlot(CALENDAR_SLOT
));
64 static const ClassSpec classSpec_
;
67 * Extract the instant fields from the ZonedDateTime object.
69 inline Instant
ToInstant(const ZonedDateTimeObject
* zonedDateTime
) {
70 return {zonedDateTime
->seconds(), zonedDateTime
->nanoseconds()};
73 class MOZ_STACK_CLASS ZonedDateTime final
{
75 TimeZoneValue timeZone_
;
76 CalendarValue calendar_
;
79 ZonedDateTime() = default;
81 ZonedDateTime(const Instant
& instant
, const TimeZoneValue
& timeZone
,
82 const CalendarValue
& calendar
)
83 : instant_(instant
), timeZone_(timeZone
), calendar_(calendar
) {
84 MOZ_ASSERT(IsValidEpochInstant(instant
));
89 explicit ZonedDateTime(const ZonedDateTimeObject
* obj
)
90 : ZonedDateTime(ToInstant(obj
), obj
->timeZone(), obj
->calendar()) {}
92 const auto& instant() const { return instant_
; }
94 const auto& timeZone() const { return timeZone_
; }
96 const auto& calendar() const { return calendar_
; }
98 explicit operator bool() const { return !!timeZone_
&& !!calendar_
; }
100 void trace(JSTracer
* trc
) {
101 timeZone_
.trace(trc
);
102 calendar_
.trace(trc
);
105 const auto* timeZoneDoNotUse() const { return &timeZone_
; }
106 const auto* calendarDoNotUse() const { return &calendar_
; }
109 enum class TemporalDisambiguation
;
110 enum class TemporalOffset
;
111 enum class TemporalOverflow
;
112 enum class TemporalUnit
;
115 * CreateTemporalZonedDateTime ( epochNanoseconds, timeZone, calendar [ ,
118 ZonedDateTimeObject
* CreateTemporalZonedDateTime(
119 JSContext
* cx
, const Instant
& instant
, JS::Handle
<TimeZoneValue
> timeZone
,
120 JS::Handle
<CalendarValue
> calendar
);
123 * AddDaysToZonedDateTime ( instant, dateTime, timeZoneRec, calendar, days [ ,
126 bool AddDaysToZonedDateTime(JSContext
* cx
, const Instant
& instant
,
127 const PlainDateTime
& dateTime
,
128 JS::Handle
<TimeZoneRecord
> timeZone
,
129 JS::Handle
<CalendarValue
> calendar
, int64_t days
,
130 TemporalOverflow overflow
, Instant
* result
);
133 * AddDaysToZonedDateTime ( instant, dateTime, timeZoneRec, calendar, days [ ,
136 bool AddDaysToZonedDateTime(JSContext
* cx
, const Instant
& instant
,
137 const PlainDateTime
& dateTime
,
138 JS::Handle
<TimeZoneRecord
> timeZone
,
139 JS::Handle
<CalendarValue
> calendar
, int64_t days
,
143 * AddZonedDateTime ( epochNanoseconds, timeZoneRec, calendarRec, years, months,
144 * weeks, days, norm [ , precalculatedPlainDateTime [ , options ] ] )
146 bool AddZonedDateTime(JSContext
* cx
, const Instant
& epochNanoseconds
,
147 JS::Handle
<TimeZoneRecord
> timeZone
,
148 JS::Handle
<CalendarRecord
> calendar
,
149 const NormalizedDuration
& duration
, Instant
* result
);
152 * AddZonedDateTime ( epochNanoseconds, timeZoneRec, calendarRec, years, months,
153 * weeks, days, norm [ , precalculatedPlainDateTime [ , options ] ] )
155 bool AddZonedDateTime(JSContext
* cx
, const Instant
& epochNanoseconds
,
156 JS::Handle
<TimeZoneRecord
> timeZone
,
157 JS::Handle
<CalendarRecord
> calendar
,
158 const NormalizedDuration
& duration
,
159 const PlainDateTime
& dateTime
, Instant
* result
);
162 * AddZonedDateTime ( epochNanoseconds, timeZoneRec, calendarRec, years, months,
163 * weeks, days, norm [ , precalculatedPlainDateTime [ , options ] ] )
165 bool AddZonedDateTime(JSContext
* cx
, const Instant
& epochNanoseconds
,
166 JS::Handle
<TimeZoneRecord
> timeZone
,
167 JS::Handle
<CalendarRecord
> calendar
,
168 const DateDuration
& duration
, Instant
* result
);
171 * AddZonedDateTime ( epochNanoseconds, timeZoneRec, calendarRec, years, months,
172 * weeks, days, norm [ , precalculatedPlainDateTime [ , options ] ] )
174 bool AddZonedDateTime(JSContext
* cx
, const Instant
& epochNanoseconds
,
175 JS::Handle
<TimeZoneRecord
> timeZone
,
176 JS::Handle
<CalendarRecord
> calendar
,
177 const DateDuration
& duration
,
178 const PlainDateTime
& dateTime
, Instant
* result
);
181 * DifferenceZonedDateTime ( ns1, ns2, timeZoneRec, calendarRec, largestUnit,
182 * options, precalculatedPlainDateTime )
184 bool DifferenceZonedDateTime(JSContext
* cx
, const Instant
& ns1
,
186 JS::Handle
<TimeZoneRecord
> timeZone
,
187 JS::Handle
<CalendarRecord
> calendar
,
188 TemporalUnit largestUnit
,
189 const PlainDateTime
& precalculatedPlainDateTime
,
190 NormalizedDuration
* result
);
192 struct NormalizedTimeAndDays final
{
195 int64_t dayLength
= 0;
199 * NormalizedTimeDurationToDays ( norm, zonedRelativeTo, timeZoneRec [ ,
200 * precalculatedPlainDateTime ] )
202 bool NormalizedTimeDurationToDays(JSContext
* cx
,
203 const NormalizedTimeDuration
& duration
,
204 JS::Handle
<ZonedDateTime
> zonedRelativeTo
,
205 JS::Handle
<TimeZoneRecord
> timeZone
,
206 NormalizedTimeAndDays
* result
);
209 * NormalizedTimeDurationToDays ( norm, zonedRelativeTo, timeZoneRec [ ,
210 * precalculatedPlainDateTime ] )
212 bool NormalizedTimeDurationToDays(
213 JSContext
* cx
, const NormalizedTimeDuration
& duration
,
214 JS::Handle
<ZonedDateTime
> zonedRelativeTo
,
215 JS::Handle
<TimeZoneRecord
> timeZone
,
216 const PlainDateTime
& precalculatedPlainDateTime
,
217 NormalizedTimeAndDays
* result
);
219 enum class OffsetBehaviour
{ Option
, Exact
, Wall
};
221 enum class MatchBehaviour
{ MatchExactly
, MatchMinutes
};
224 * InterpretISODateTimeOffset ( year, month, day, hour, minute, second,
225 * millisecond, microsecond, nanosecond, offsetBehaviour, offsetNanoseconds,
226 * timeZoneRec, disambiguation, offsetOption, matchBehaviour )
228 bool InterpretISODateTimeOffset(JSContext
* cx
, const PlainDateTime
& dateTime
,
229 OffsetBehaviour offsetBehaviour
,
230 int64_t offsetNanoseconds
,
231 JS::Handle
<TimeZoneRecord
> timeZone
,
232 TemporalDisambiguation disambiguation
,
233 TemporalOffset offsetOption
,
234 MatchBehaviour matchBehaviour
, Instant
* result
);
236 } /* namespace js::temporal */
240 template <typename Wrapper
>
241 class WrappedPtrOperations
<temporal::ZonedDateTime
, Wrapper
> {
242 const auto& container() const {
243 return static_cast<const Wrapper
*>(this)->get();
247 explicit operator bool() const { return bool(container()); }
249 const auto& instant() const { return container().instant(); }
251 JS::Handle
<temporal::TimeZoneValue
> timeZone() const {
252 return JS::Handle
<temporal::TimeZoneValue
>::fromMarkedLocation(
253 container().timeZoneDoNotUse());
256 JS::Handle
<temporal::CalendarValue
> calendar() const {
257 return JS::Handle
<temporal::CalendarValue
>::fromMarkedLocation(
258 container().calendarDoNotUse());
264 #endif /* builtin_temporal_ZonedDateTime_h */