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 vm_DateObject_h_ 8 #define vm_DateObject_h_ 9 10 #include "js/Date.h" 11 #include "js/Value.h" 12 #include "vm/JSObject.h" 13 14 namespace js { 15 16 class DateObject : public NativeObject { 17 // Time in milliseconds since the (Unix) epoch. 18 static const uint32_t UTC_TIME_SLOT = 0; 19 20 // Raw time zone offset in seconds, i.e. without daylight saving adjustment, 21 // of the current system zone. 22 // 23 // This value is exclusively used to verify the cached slots are still valid. 24 // 25 // It is NOT the return value of Date.prototype.getTimezoneOffset()! 26 static const uint32_t UTC_TIME_ZONE_OFFSET_SLOT = 1; 27 28 /* 29 * Cached slots holding local properties of the date. 30 * These are undefined until the first actual lookup occurs 31 * and are reset to undefined whenever the date's time is modified. 32 */ 33 static const uint32_t COMPONENTS_START_SLOT = 2; 34 35 static const uint32_t LOCAL_TIME_SLOT = COMPONENTS_START_SLOT + 0; 36 static const uint32_t LOCAL_YEAR_SLOT = COMPONENTS_START_SLOT + 1; 37 static const uint32_t LOCAL_MONTH_SLOT = COMPONENTS_START_SLOT + 2; 38 static const uint32_t LOCAL_DATE_SLOT = COMPONENTS_START_SLOT + 3; 39 static const uint32_t LOCAL_DAY_SLOT = COMPONENTS_START_SLOT + 4; 40 41 /* 42 * Unlike the above slots that hold LocalTZA-adjusted component values, 43 * LOCAL_SECONDS_INTO_YEAR_SLOT holds a composite value that can be used 44 * to compute LocalTZA-adjusted hours, minutes, and seconds values. 45 * Specifically, LOCAL_SECONDS_INTO_YEAR_SLOT holds the number of 46 * LocalTZA-adjusted seconds into the year. Unix timestamps ignore leap 47 * seconds, so recovering hours/minutes/seconds requires only trivial 48 * division/modulus operations. 49 */ 50 static const uint32_t LOCAL_SECONDS_INTO_YEAR_SLOT = 51 COMPONENTS_START_SLOT + 5; 52 53 static const uint32_t RESERVED_SLOTS = LOCAL_SECONDS_INTO_YEAR_SLOT + 1; 54 55 public: 56 static const JSClass class_; 57 static const JSClass protoClass_; 58 clippedTime()59 JS::ClippedTime clippedTime() const { 60 double t = getFixedSlot(UTC_TIME_SLOT).toDouble(); 61 JS::ClippedTime clipped = JS::TimeClip(t); 62 MOZ_ASSERT(mozilla::NumbersAreIdentical(clipped.toDouble(), t)); 63 return clipped; 64 } 65 UTCTime()66 const js::Value& UTCTime() const { return getFixedSlot(UTC_TIME_SLOT); } 67 68 // Set UTC time to a given time and invalidate cached local time. 69 void setUTCTime(JS::ClippedTime t); 70 void setUTCTime(JS::ClippedTime t, MutableHandleValue vp); 71 72 inline double cachedLocalTime(); 73 74 // Cache the local time, year, month, and so forth of the object. 75 // If UTC time is not finite (e.g., NaN), the local time 76 // slots will be set to the UTC time without conversion. 77 void fillLocalTimeSlots(); 78 localYear()79 const js::Value& localYear() const { 80 return getReservedSlot(LOCAL_YEAR_SLOT); 81 } localMonth()82 const js::Value& localMonth() const { 83 return getReservedSlot(LOCAL_MONTH_SLOT); 84 } localDate()85 const js::Value& localDate() const { 86 return getReservedSlot(LOCAL_DATE_SLOT); 87 } localDay()88 const js::Value& localDay() const { return getReservedSlot(LOCAL_DAY_SLOT); } 89 localSecondsIntoYear()90 const js::Value& localSecondsIntoYear() const { 91 return getReservedSlot(LOCAL_SECONDS_INTO_YEAR_SLOT); 92 } 93 }; 94 95 } // namespace js 96 97 #endif // vm_DateObject_h_ 98