Bug 1874684 - Part 20: Tag stack classes with MOZ_STACK_CLASS. r=allstarschh
[gecko.git] / js / src / builtin / temporal / ZonedDateTime.h
blob7d75a3320142512dd344c5d6d77cd7142998cdea
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"
13 #include <stdint.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"
21 #include "js/Value.h"
22 #include "vm/NativeObject.h"
24 class JS_PUBLIC_API JSTracer;
26 namespace js {
27 struct ClassSpec;
30 namespace js::temporal {
32 class ZonedDateTimeObject : public NativeObject {
33 public:
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);
52 return nanoseconds;
55 TimeZoneValue timeZone() const {
56 return TimeZoneValue(getFixedSlot(TIMEZONE_SLOT));
59 CalendarValue calendar() const {
60 return CalendarValue(getFixedSlot(CALENDAR_SLOT));
63 private:
64 static const ClassSpec classSpec_;
66 /**
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 {
74 Instant instant_;
75 TimeZoneValue timeZone_;
76 CalendarValue calendar_;
78 public:
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));
85 MOZ_ASSERT(timeZone);
86 MOZ_ASSERT(calendar);
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 [ ,
116 * newTarget ] )
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 [ ,
124 * overflow ] )
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 [ ,
134 * overflow ] )
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,
140 Instant* result);
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,
185 const Instant& ns2,
186 JS::Handle<TimeZoneRecord> timeZone,
187 JS::Handle<CalendarRecord> calendar,
188 TemporalUnit largestUnit,
189 const PlainDateTime& precalculatedPlainDateTime,
190 NormalizedDuration* result);
192 struct NormalizedTimeAndDays final {
193 int64_t days = 0;
194 int64_t time = 0;
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 */
238 namespace js {
240 template <typename Wrapper>
241 class WrappedPtrOperations<temporal::ZonedDateTime, Wrapper> {
242 const auto& container() const {
243 return static_cast<const Wrapper*>(this)->get();
246 public:
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());
262 } /* namespace js */
264 #endif /* builtin_temporal_ZonedDateTime_h */