Bug 1874684 - Part 28: Return DateDuration from DifferenceISODateTime. r=mgaudet
[gecko.git] / js / src / builtin / temporal / PlainDateTime.h
blob203189673ee3f7282b7126e206138b907bdd7db1
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_PlainDateTime_h
8 #define builtin_temporal_PlainDateTime_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/TemporalTypes.h"
17 #include "builtin/temporal/Wrapped.h"
18 #include "js/RootingAPI.h"
19 #include "js/TypeDecls.h"
20 #include "js/Value.h"
21 #include "vm/NativeObject.h"
23 class JS_PUBLIC_API JSTracer;
25 namespace js {
26 struct ClassSpec;
27 class PlainObject;
28 } // namespace js
30 namespace js::temporal {
32 class PlainDateTimeObject : public NativeObject {
33 public:
34 static const JSClass class_;
35 static const JSClass& protoClass_;
37 // TODO: Consider compacting fields to reduce object size.
39 // See also PlainDateObject and PlainTimeObject.
41 static constexpr uint32_t ISO_YEAR_SLOT = 0;
42 static constexpr uint32_t ISO_MONTH_SLOT = 1;
43 static constexpr uint32_t ISO_DAY_SLOT = 2;
44 static constexpr uint32_t ISO_HOUR_SLOT = 3;
45 static constexpr uint32_t ISO_MINUTE_SLOT = 4;
46 static constexpr uint32_t ISO_SECOND_SLOT = 5;
47 static constexpr uint32_t ISO_MILLISECOND_SLOT = 6;
48 static constexpr uint32_t ISO_MICROSECOND_SLOT = 7;
49 static constexpr uint32_t ISO_NANOSECOND_SLOT = 8;
50 static constexpr uint32_t CALENDAR_SLOT = 9;
51 static constexpr uint32_t SLOT_COUNT = 10;
53 int32_t isoYear() const { return getFixedSlot(ISO_YEAR_SLOT).toInt32(); }
55 int32_t isoMonth() const { return getFixedSlot(ISO_MONTH_SLOT).toInt32(); }
57 int32_t isoDay() const { return getFixedSlot(ISO_DAY_SLOT).toInt32(); }
59 int32_t isoHour() const { return getFixedSlot(ISO_HOUR_SLOT).toInt32(); }
61 int32_t isoMinute() const { return getFixedSlot(ISO_MINUTE_SLOT).toInt32(); }
63 int32_t isoSecond() const { return getFixedSlot(ISO_SECOND_SLOT).toInt32(); }
65 int32_t isoMillisecond() const {
66 return getFixedSlot(ISO_MILLISECOND_SLOT).toInt32();
69 int32_t isoMicrosecond() const {
70 return getFixedSlot(ISO_MICROSECOND_SLOT).toInt32();
73 int32_t isoNanosecond() const {
74 return getFixedSlot(ISO_NANOSECOND_SLOT).toInt32();
77 CalendarValue calendar() const {
78 return CalendarValue(getFixedSlot(CALENDAR_SLOT));
81 private:
82 static const ClassSpec classSpec_;
85 /**
86 * Extract the date fields from the PlainDateTime object.
88 inline PlainDate ToPlainDate(const PlainDateTimeObject* dateTime) {
89 return {dateTime->isoYear(), dateTime->isoMonth(), dateTime->isoDay()};
92 /**
93 * Extract the time fields from the PlainDateTime object.
95 inline PlainTime ToPlainTime(const PlainDateTimeObject* dateTime) {
96 return {dateTime->isoHour(), dateTime->isoMinute(),
97 dateTime->isoSecond(), dateTime->isoMillisecond(),
98 dateTime->isoMicrosecond(), dateTime->isoNanosecond()};
102 * Extract the date-time fields from the PlainDateTime object.
104 inline PlainDateTime ToPlainDateTime(const PlainDateTimeObject* dateTime) {
105 return {ToPlainDate(dateTime), ToPlainTime(dateTime)};
108 enum class TemporalUnit;
110 #ifdef DEBUG
112 * IsValidISODateTime ( year, month, day, hour, minute, second, millisecond,
113 * microsecond, nanosecond )
115 bool IsValidISODateTime(const PlainDateTime& dateTime);
116 #endif
119 * ISODateTimeWithinLimits ( year, month, day, hour, minute, second,
120 * millisecond, microsecond, nanosecond )
122 bool ISODateTimeWithinLimits(const PlainDateTime& dateTime);
125 * ISODateTimeWithinLimits ( year, month, day, hour, minute, second,
126 * millisecond, microsecond, nanosecond )
128 bool ISODateTimeWithinLimits(const PlainDate& date);
131 * ISODateTimeWithinLimits ( year, month, day, hour, minute, second,
132 * millisecond, microsecond, nanosecond )
134 bool ISODateTimeWithinLimits(double year, double month, double day);
137 * CreateTemporalDateTime ( isoYear, isoMonth, isoDay, hour, minute, second,
138 * millisecond, microsecond, nanosecond, calendar [ , newTarget ] )
140 PlainDateTimeObject* CreateTemporalDateTime(JSContext* cx,
141 const PlainDateTime& dateTime,
142 JS::Handle<CalendarValue> calendar);
145 * ToTemporalDateTime ( item [ , options ] )
147 Wrapped<PlainDateTimeObject*> ToTemporalDateTime(JSContext* cx,
148 JS::Handle<JS::Value> item);
151 * ToTemporalDateTime ( item [ , options ] )
153 bool ToTemporalDateTime(JSContext* cx, JS::Handle<JS::Value> item,
154 PlainDateTime* result);
157 * InterpretTemporalDateTimeFields ( calendarRec, fields, options )
159 bool InterpretTemporalDateTimeFields(JSContext* cx,
160 JS::Handle<CalendarRecord> calendar,
161 JS::Handle<PlainObject*> fields,
162 JS::Handle<PlainObject*> options,
163 PlainDateTime* result);
166 * InterpretTemporalDateTimeFields ( calendarRec, fields, options )
168 bool InterpretTemporalDateTimeFields(JSContext* cx,
169 JS::Handle<CalendarRecord> calendar,
170 JS::Handle<PlainObject*> fields,
171 PlainDateTime* result);
174 * DifferenceISODateTime ( y1, mon1, d1, h1, min1, s1, ms1, mus1, ns1, y2, mon2,
175 * d2, h2, min2, s2, ms2, mus2, ns2, calendarRec, largestUnit, options )
177 bool DifferenceISODateTime(JSContext* cx, const PlainDateTime& one,
178 const PlainDateTime& two,
179 JS::Handle<CalendarRecord> calendar,
180 TemporalUnit largestUnit, DateDuration* result);
183 * DifferenceISODateTime ( y1, mon1, d1, h1, min1, s1, ms1, mus1, ns1, y2, mon2,
184 * d2, h2, min2, s2, ms2, mus2, ns2, calendarRec, largestUnit, options )
186 bool DifferenceISODateTime(JSContext* cx, const PlainDateTime& one,
187 const PlainDateTime& two,
188 JS::Handle<CalendarRecord> calendar,
189 TemporalUnit largestUnit,
190 JS::Handle<PlainObject*> options,
191 DateDuration* result);
193 class MOZ_STACK_CLASS PlainDateTimeWithCalendar final {
194 PlainDateTime dateTime_;
195 CalendarValue calendar_;
197 public:
198 PlainDateTimeWithCalendar() = default;
200 PlainDateTimeWithCalendar(const PlainDateTime& dateTime,
201 const CalendarValue& calendar)
202 : dateTime_(dateTime), calendar_(calendar) {
203 MOZ_ASSERT(ISODateTimeWithinLimits(dateTime));
206 explicit PlainDateTimeWithCalendar(const PlainDateTimeObject* dateTime)
207 : PlainDateTimeWithCalendar(ToPlainDateTime(dateTime),
208 dateTime->calendar()) {}
210 const auto& dateTime() const { return dateTime_; }
211 const auto& date() const { return dateTime_.date; }
212 const auto& time() const { return dateTime_.time; }
213 const auto& calendar() const { return calendar_; }
215 // Allow implicit conversion to a calendar-less PlainDateTime.
216 operator const PlainDateTime&() const { return dateTime(); }
218 void trace(JSTracer* trc) { calendar_.trace(trc); }
220 const auto* calendarDoNotUse() const { return &calendar_; }
224 * Extract the date-time fields from the PlainDateTimeWithCalendar object.
226 inline const auto& ToPlainDateTime(const PlainDateTimeWithCalendar& dateTime) {
227 return dateTime.dateTime();
231 * CreateTemporalDateTime ( isoYear, isoMonth, isoDay, hour, minute, second,
232 * millisecond, microsecond, nanosecond, calendar [ , newTarget ] )
234 bool CreateTemporalDateTime(
235 JSContext* cx, const PlainDateTime& dateTime,
236 JS::Handle<CalendarValue> calendar,
237 JS::MutableHandle<PlainDateTimeWithCalendar> result);
239 } /* namespace js::temporal */
241 namespace js {
243 template <typename Wrapper>
244 class WrappedPtrOperations<temporal::PlainDateTimeWithCalendar, Wrapper> {
245 const auto& container() const {
246 return static_cast<const Wrapper*>(this)->get();
249 public:
250 const auto& dateTime() const { return container().dateTime(); }
251 const auto& date() const { return container().date(); }
252 const auto& time() const { return container().time(); }
254 auto calendar() const {
255 return JS::Handle<temporal::CalendarValue>::fromMarkedLocation(
256 container().calendarDoNotUse());
259 // Allow implicit conversion to a calendar-less PlainDateTime.
260 operator const temporal::PlainDateTime&() const { return dateTime(); }
263 } // namespace js
265 #endif /* builtin_temporal_PlainDateTime_h */