PlainDateTime.h (5992B)
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/. */ 6 7 #ifndef builtin_temporal_PlainDateTime_h 8 #define builtin_temporal_PlainDateTime_h 9 10 #include "mozilla/Assertions.h" 11 #include "mozilla/Attributes.h" 12 #include "mozilla/Casting.h" 13 14 #include <stdint.h> 15 16 #include "builtin/temporal/Calendar.h" 17 #include "builtin/temporal/TemporalTypes.h" 18 #include "js/RootingAPI.h" 19 #include "js/TypeDecls.h" 20 #include "js/Value.h" 21 #include "vm/NativeObject.h" 22 23 class JS_PUBLIC_API JSTracer; 24 25 namespace js { 26 struct ClassSpec; 27 } // namespace js 28 29 namespace js::temporal { 30 31 class PlainDateTimeObject : public NativeObject { 32 public: 33 static const JSClass class_; 34 static const JSClass& protoClass_; 35 36 static constexpr uint32_t PACKED_DATE_SLOT = 0; 37 static constexpr uint32_t PACKED_TIME_SLOT = 1; 38 static constexpr uint32_t CALENDAR_SLOT = 2; 39 static constexpr uint32_t SLOT_COUNT = 3; 40 41 /** 42 * Extract the date fields from this PlainDateTime object. 43 */ 44 ISODate date() const { 45 auto packed = PackedDate{getFixedSlot(PACKED_DATE_SLOT).toPrivateUint32()}; 46 return PackedDate::unpack(packed); 47 } 48 49 /** 50 * Extract the time fields from this PlainDateTime object. 51 */ 52 Time time() const { 53 auto packed = PackedTime{mozilla::BitwiseCast<uint64_t>( 54 getFixedSlot(PACKED_TIME_SLOT).toDouble())}; 55 return PackedTime::unpack(packed); 56 } 57 58 /** 59 * Extract the date-time fields from this PlainDateTime object. 60 */ 61 ISODateTime dateTime() const { return {date(), time()}; } 62 63 CalendarValue calendar() const { 64 return CalendarValue(getFixedSlot(CALENDAR_SLOT)); 65 } 66 67 private: 68 static const ClassSpec classSpec_; 69 }; 70 71 struct DifferenceSettings; 72 class Increment; 73 class CalendarFields; 74 enum class TemporalOverflow; 75 enum class TemporalRoundingMode; 76 enum class TemporalUnit; 77 78 #ifdef DEBUG 79 /** 80 * IsValidISODate ( year, month, day ) 81 * IsValidTime ( hour, minute, second, millisecond, microsecond, nanosecond ) 82 */ 83 bool IsValidISODateTime(const ISODateTime& isoDateTime); 84 #endif 85 86 /** 87 * ISODateTimeWithinLimits ( isoDateTime ) 88 */ 89 bool ISODateTimeWithinLimits(const ISODateTime& isoDateTime); 90 91 class MOZ_STACK_CLASS PlainDateTime final { 92 ISODateTime dateTime_; 93 CalendarValue calendar_; 94 95 public: 96 PlainDateTime() = default; 97 98 PlainDateTime(const ISODateTime& dateTime, const CalendarValue& calendar) 99 : dateTime_(dateTime), calendar_(calendar) { 100 MOZ_ASSERT(ISODateTimeWithinLimits(dateTime)); 101 } 102 103 explicit PlainDateTime(const PlainDateTimeObject* dateTime) 104 : PlainDateTime(dateTime->dateTime(), dateTime->calendar()) {} 105 106 const auto& dateTime() const { return dateTime_; } 107 const auto& date() const { return dateTime_.date; } 108 const auto& time() const { return dateTime_.time; } 109 const auto& calendar() const { return calendar_; } 110 111 // Allow implicit conversion to an ISODateTime. 112 operator const ISODateTime&() const { return dateTime(); } 113 114 void trace(JSTracer* trc) { calendar_.trace(trc); } 115 116 const auto* calendarDoNotUse() const { return &calendar_; } 117 }; 118 119 /** 120 * CreateTemporalDateTime ( isoDateTime, calendar [ , newTarget ] ) 121 */ 122 PlainDateTimeObject* CreateTemporalDateTime(JSContext* cx, 123 const ISODateTime& dateTime, 124 JS::Handle<CalendarValue> calendar); 125 126 /** 127 * InterpretTemporalDateTimeFields ( calendar, fields, overflow ) 128 */ 129 bool InterpretTemporalDateTimeFields(JSContext* cx, 130 JS::Handle<CalendarValue> calendar, 131 JS::Handle<CalendarFields> fields, 132 TemporalOverflow overflow, 133 ISODateTime* result); 134 135 /** 136 * RoundISODateTime ( isoDateTime, increment, unit, roundingMode ) 137 */ 138 ISODateTime RoundISODateTime(const ISODateTime& isoDateTime, 139 Increment increment, TemporalUnit unit, 140 TemporalRoundingMode roundingMode); 141 142 /** 143 * DifferencePlainDateTimeWithRounding ( isoDateTime1, isoDateTime2, calendar, 144 * largestUnit, roundingIncrement, smallestUnit, roundingMode ) 145 */ 146 bool DifferencePlainDateTimeWithRounding(JSContext* cx, 147 const ISODateTime& isoDateTime1, 148 const ISODateTime& isoDateTime2, 149 JS::Handle<CalendarValue> calendar, 150 const DifferenceSettings& settings, 151 InternalDuration* result); 152 /** 153 * DifferencePlainDateTimeWithTotal ( isoDateTime1, isoDateTime2, calendar, unit 154 * ) 155 */ 156 bool DifferencePlainDateTimeWithTotal(JSContext* cx, 157 const ISODateTime& isoDateTime1, 158 const ISODateTime& isoDateTime2, 159 JS::Handle<CalendarValue> calendar, 160 TemporalUnit unit, double* result); 161 162 } /* namespace js::temporal */ 163 164 namespace js { 165 166 template <typename Wrapper> 167 class WrappedPtrOperations<temporal::PlainDateTime, Wrapper> { 168 const auto& container() const { 169 return static_cast<const Wrapper*>(this)->get(); 170 } 171 172 public: 173 const auto& dateTime() const { return container().dateTime(); } 174 const auto& date() const { return container().date(); } 175 const auto& time() const { return container().time(); } 176 177 auto calendar() const { 178 return JS::Handle<temporal::CalendarValue>::fromMarkedLocation( 179 container().calendarDoNotUse()); 180 } 181 182 // Allow implicit conversion to an ISODateTime. 183 operator const temporal::ISODateTime&() const { return dateTime(); } 184 }; 185 186 } // namespace js 187 188 #endif /* builtin_temporal_PlainDateTime_h */