Line data Source code
1 : // Copyright 2016 the V8 project authors. All rights reserved.
2 : // Use of this source code is governed by a BSD-style license that can be
3 : // found in the LICENSE file.
4 :
5 : #include "src/builtins/builtins-utils-inl.h"
6 : #include "src/builtins/builtins.h"
7 : #include "src/code-factory.h"
8 : #include "src/conversions.h"
9 : #include "src/counters.h"
10 : #include "src/date.h"
11 : #include "src/dateparser-inl.h"
12 : #include "src/objects-inl.h"
13 : #ifdef V8_INTL_SUPPORT
14 : #include "src/objects/intl-objects.h"
15 : #include "src/objects/js-date-time-format.h"
16 : #endif
17 : #include "src/string-stream.h"
18 :
19 : namespace v8 {
20 : namespace internal {
21 :
22 : // -----------------------------------------------------------------------------
23 : // ES6 section 20.3 Date Objects
24 :
25 : namespace {
26 :
27 : // ES6 section 20.3.1.1 Time Values and Time Range
28 : const double kMinYear = -1000000.0;
29 : const double kMaxYear = -kMinYear;
30 : const double kMinMonth = -10000000.0;
31 : const double kMaxMonth = -kMinMonth;
32 :
33 : // 20.3.1.2 Day Number and Time within Day
34 : const double kMsPerDay = 86400000.0;
35 :
36 : // ES6 section 20.3.1.11 Hours, Minutes, Second, and Milliseconds
37 : const double kMsPerSecond = 1000.0;
38 : const double kMsPerMinute = 60000.0;
39 : const double kMsPerHour = 3600000.0;
40 :
41 : // ES6 section 20.3.1.14 MakeDate (day, time)
42 : double MakeDate(double day, double time) {
43 144293 : if (std::isfinite(day) && std::isfinite(time)) {
44 62431 : return time + day * kMsPerDay;
45 : }
46 : return std::numeric_limits<double>::quiet_NaN();
47 : }
48 :
49 : // ES6 section 20.3.1.13 MakeDay (year, month, date)
50 64564 : double MakeDay(double year, double month, double date) {
51 128183 : if ((kMinYear <= year && year <= kMaxYear) &&
52 189849 : (kMinMonth <= month && month <= kMaxMonth) && std::isfinite(date)) {
53 : int y = FastD2I(year);
54 : int m = FastD2I(month);
55 62287 : y += m / 12;
56 62287 : m %= 12;
57 62287 : if (m < 0) {
58 9 : m += 12;
59 9 : y -= 1;
60 : }
61 : DCHECK_LE(0, m);
62 : DCHECK_LT(m, 12);
63 :
64 : // kYearDelta is an arbitrary number such that:
65 : // a) kYearDelta = -1 (mod 400)
66 : // b) year + kYearDelta > 0 for years in the range defined by
67 : // ECMA 262 - 15.9.1.1, i.e. upto 100,000,000 days on either side of
68 : // Jan 1 1970. This is required so that we don't run into integer
69 : // division of negative numbers.
70 : // c) there shouldn't be an overflow for 32-bit integers in the following
71 : // operations.
72 : static const int kYearDelta = 399999;
73 : static const int kBaseDay =
74 : 365 * (1970 + kYearDelta) + (1970 + kYearDelta) / 4 -
75 : (1970 + kYearDelta) / 100 + (1970 + kYearDelta) / 400;
76 124574 : int day_from_year = 365 * (y + kYearDelta) + (y + kYearDelta) / 4 -
77 124574 : (y + kYearDelta) / 100 + (y + kYearDelta) / 400 -
78 62287 : kBaseDay;
79 62287 : if ((y % 4 != 0) || (y % 100 == 0 && y % 400 != 0)) {
80 : static const int kDayFromMonth[] = {0, 31, 59, 90, 120, 151,
81 : 181, 212, 243, 273, 304, 334};
82 45263 : day_from_year += kDayFromMonth[m];
83 : } else {
84 : static const int kDayFromMonth[] = {0, 31, 60, 91, 121, 152,
85 : 182, 213, 244, 274, 305, 335};
86 17024 : day_from_year += kDayFromMonth[m];
87 : }
88 62287 : return static_cast<double>(day_from_year - 1) + DoubleToInteger(date);
89 : }
90 : return std::numeric_limits<double>::quiet_NaN();
91 : }
92 :
93 : // ES6 section 20.3.1.12 MakeTime (hour, min, sec, ms)
94 70837 : double MakeTime(double hour, double min, double sec, double ms) {
95 263575 : if (std::isfinite(hour) && std::isfinite(min) && std::isfinite(sec) &&
96 : std::isfinite(ms)) {
97 62260 : double const h = DoubleToInteger(hour);
98 62260 : double const m = DoubleToInteger(min);
99 62260 : double const s = DoubleToInteger(sec);
100 62260 : double const milli = DoubleToInteger(ms);
101 62260 : return h * kMsPerHour + m * kMsPerMinute + s * kMsPerSecond + milli;
102 : }
103 : return std::numeric_limits<double>::quiet_NaN();
104 : }
105 :
106 : const char* kShortWeekDays[] = {"Sun", "Mon", "Tue", "Wed",
107 : "Thu", "Fri", "Sat"};
108 : const char* kShortMonths[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
109 : "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
110 :
111 : // ES6 section 20.3.1.16 Date Time String Format
112 58405 : double ParseDateTimeString(Isolate* isolate, Handle<String> str) {
113 58405 : str = String::Flatten(isolate, str);
114 : // TODO(bmeurer): Change DateParser to not use the FixedArray.
115 : Handle<FixedArray> tmp =
116 58405 : isolate->factory()->NewFixedArray(DateParser::OUTPUT_SIZE);
117 : DisallowHeapAllocation no_gc;
118 58405 : String::FlatContent str_content = str->GetFlatContent(no_gc);
119 : bool result;
120 58405 : if (str_content.IsOneByte()) {
121 58405 : result = DateParser::Parse(isolate, str_content.ToOneByteVector(), *tmp);
122 : } else {
123 0 : result = DateParser::Parse(isolate, str_content.ToUC16Vector(), *tmp);
124 : }
125 58405 : if (!result) return std::numeric_limits<double>::quiet_NaN();
126 : double const day = MakeDay(tmp->get(0)->Number(), tmp->get(1)->Number(),
127 57891 : tmp->get(2)->Number());
128 : double const time = MakeTime(tmp->get(3)->Number(), tmp->get(4)->Number(),
129 57891 : tmp->get(5)->Number(), tmp->get(6)->Number());
130 : double date = MakeDate(day, time);
131 57891 : if (tmp->get(7)->IsNull(isolate)) {
132 583 : if (date >= -DateCache::kMaxTimeBeforeUTCInMs &&
133 : date <= DateCache::kMaxTimeBeforeUTCInMs) {
134 1130 : date = isolate->date_cache()->ToUTC(static_cast<int64_t>(date));
135 : } else {
136 : return std::numeric_limits<double>::quiet_NaN();
137 : }
138 : } else {
139 57308 : date -= tmp->get(7)->Number() * 1000.0;
140 : }
141 57873 : return DateCache::TimeClip(date);
142 : }
143 :
144 : enum ToDateStringMode { kDateOnly, kTimeOnly, kDateAndTime };
145 :
146 : typedef base::SmallVector<char, 128> DateBuffer;
147 :
148 : template <class... Args>
149 53631 : DateBuffer FormatDate(const char* format, Args... args) {
150 : DateBuffer buffer;
151 : SmallStringOptimizedAllocator<DateBuffer::kInlineSize> allocator(&buffer);
152 : StringStream sstream(&allocator);
153 53631 : sstream.Add(format, args...);
154 53631 : buffer.resize_no_init(sstream.length());
155 53631 : return buffer;
156 : }
157 :
158 : // ES6 section 20.3.4.41.1 ToDateString(tv)
159 53631 : DateBuffer ToDateString(double time_val, DateCache* date_cache,
160 : ToDateStringMode mode = kDateAndTime) {
161 53631 : if (std::isnan(time_val)) {
162 63 : return FormatDate("Invalid Date");
163 : }
164 53568 : int64_t time_ms = static_cast<int64_t>(time_val);
165 : int64_t local_time_ms = date_cache->ToLocal(time_ms);
166 : int year, month, day, weekday, hour, min, sec, ms;
167 : date_cache->BreakDownTime(local_time_ms, &year, &month, &day, &weekday, &hour,
168 53568 : &min, &sec, &ms);
169 53568 : int timezone_offset = -date_cache->TimezoneOffset(time_ms);
170 53568 : int timezone_hour = std::abs(timezone_offset) / 60;
171 53568 : int timezone_min = std::abs(timezone_offset) % 60;
172 53568 : const char* local_timezone = date_cache->LocalTimezone(time_ms);
173 53568 : switch (mode) {
174 : case kDateOnly:
175 45 : return FormatDate((year < 0) ? "%s %s %02d %05d" : "%s %s %02d %04d",
176 : kShortWeekDays[weekday], kShortMonths[month], day,
177 90 : year);
178 : case kTimeOnly:
179 : return FormatDate("%02d:%02d:%02d GMT%c%02d%02d (%s)", hour, min, sec,
180 : (timezone_offset < 0) ? '-' : '+', timezone_hour,
181 36 : timezone_min, local_timezone);
182 : case kDateAndTime:
183 : return FormatDate(
184 53487 : (year < 0) ? "%s %s %02d %05d %02d:%02d:%02d GMT%c%02d%02d (%s)"
185 : : "%s %s %02d %04d %02d:%02d:%02d GMT%c%02d%02d (%s)",
186 : kShortWeekDays[weekday], kShortMonths[month], day, year, hour, min,
187 : sec, (timezone_offset < 0) ? '-' : '+', timezone_hour, timezone_min,
188 106974 : local_timezone);
189 : }
190 0 : UNREACHABLE();
191 : }
192 :
193 6030 : Object SetLocalDateValue(Isolate* isolate, Handle<JSDate> date,
194 : double time_val) {
195 6030 : if (time_val >= -DateCache::kMaxTimeBeforeUTCInMs &&
196 : time_val <= DateCache::kMaxTimeBeforeUTCInMs) {
197 684 : time_val = isolate->date_cache()->ToUTC(static_cast<int64_t>(time_val));
198 : } else {
199 : time_val = std::numeric_limits<double>::quiet_NaN();
200 : }
201 12060 : return *JSDate::SetValue(date, DateCache::TimeClip(time_val));
202 : }
203 :
204 : } // namespace
205 :
206 : // ES #sec-date-constructor
207 752000 : BUILTIN(DateConstructor) {
208 : HandleScope scope(isolate);
209 150400 : if (args.new_target()->IsUndefined(isolate)) {
210 63 : double const time_val = JSDate::CurrentTimeValue(isolate);
211 63 : DateBuffer buffer = ToDateString(time_val, isolate->date_cache());
212 126 : RETURN_RESULT_OR_FAILURE(
213 : isolate, isolate->factory()->NewStringFromUtf8(VectorOf(buffer)));
214 : }
215 : // [Construct]
216 150337 : int const argc = args.length() - 1;
217 150337 : Handle<JSFunction> target = args.target();
218 150337 : Handle<JSReceiver> new_target = Handle<JSReceiver>::cast(args.new_target());
219 : double time_val;
220 150337 : if (argc == 0) {
221 92668 : time_val = JSDate::CurrentTimeValue(isolate);
222 57669 : } else if (argc == 1) {
223 : Handle<Object> value = args.at(1);
224 55290 : if (value->IsJSDate()) {
225 : time_val = Handle<JSDate>::cast(value)->value()->Number();
226 : } else {
227 110265 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, value,
228 : Object::ToPrimitive(value));
229 55119 : if (value->IsString()) {
230 429 : time_val = ParseDateTimeString(isolate, Handle<String>::cast(value));
231 : } else {
232 109380 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, value,
233 : Object::ToNumber(isolate, value));
234 : time_val = value->Number();
235 : }
236 : }
237 : } else {
238 : Handle<Object> year_object;
239 4758 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, year_object,
240 : Object::ToNumber(isolate, args.at(1)));
241 : Handle<Object> month_object;
242 4758 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, month_object,
243 : Object::ToNumber(isolate, args.at(2)));
244 : double year = year_object->Number();
245 : double month = month_object->Number();
246 : double date = 1.0, hours = 0.0, minutes = 0.0, seconds = 0.0, ms = 0.0;
247 2379 : if (argc >= 3) {
248 : Handle<Object> date_object;
249 4578 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, date_object,
250 : Object::ToNumber(isolate, args.at(3)));
251 : date = date_object->Number();
252 2289 : if (argc >= 4) {
253 : Handle<Object> hours_object;
254 4122 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
255 : isolate, hours_object, Object::ToNumber(isolate, args.at(4)));
256 : hours = hours_object->Number();
257 2061 : if (argc >= 5) {
258 : Handle<Object> minutes_object;
259 2304 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
260 : isolate, minutes_object, Object::ToNumber(isolate, args.at(5)));
261 : minutes = minutes_object->Number();
262 1152 : if (argc >= 6) {
263 : Handle<Object> seconds_object;
264 450 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
265 : isolate, seconds_object, Object::ToNumber(isolate, args.at(6)));
266 : seconds = seconds_object->Number();
267 225 : if (argc >= 7) {
268 : Handle<Object> ms_object;
269 378 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
270 : isolate, ms_object, Object::ToNumber(isolate, args.at(7)));
271 : ms = ms_object->Number();
272 : }
273 : }
274 : }
275 : }
276 : }
277 2379 : if (!std::isnan(year)) {
278 2361 : double const y = DoubleToInteger(year);
279 2361 : if (0.0 <= y && y <= 99) year = 1900 + y;
280 : }
281 2379 : double const day = MakeDay(year, month, date);
282 2379 : double const time = MakeTime(hours, minutes, seconds, ms);
283 : time_val = MakeDate(day, time);
284 2379 : if (time_val >= -DateCache::kMaxTimeBeforeUTCInMs &&
285 : time_val <= DateCache::kMaxTimeBeforeUTCInMs) {
286 4398 : time_val = isolate->date_cache()->ToUTC(static_cast<int64_t>(time_val));
287 : } else {
288 : time_val = std::numeric_limits<double>::quiet_NaN();
289 : }
290 : }
291 300656 : RETURN_RESULT_OR_FAILURE(isolate, JSDate::New(target, new_target, time_val));
292 : }
293 :
294 : // ES6 section 20.3.3.1 Date.now ( )
295 2359375 : BUILTIN(DateNow) {
296 : HandleScope scope(isolate);
297 1415625 : return *isolate->factory()->NewNumber(JSDate::CurrentTimeValue(isolate));
298 : }
299 :
300 : // ES6 section 20.3.3.2 Date.parse ( string )
301 289880 : BUILTIN(DateParse) {
302 : HandleScope scope(isolate);
303 : Handle<String> string;
304 115952 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
305 : isolate, string,
306 : Object::ToString(isolate, args.atOrUndefined(isolate, 1)));
307 115952 : return *isolate->factory()->NewNumber(ParseDateTimeString(isolate, string));
308 : }
309 :
310 : // ES6 section 20.3.3.4 Date.UTC (year,month,date,hours,minutes,seconds,ms)
311 9230 : BUILTIN(DateUTC) {
312 : HandleScope scope(isolate);
313 1846 : int const argc = args.length() - 1;
314 : double year = std::numeric_limits<double>::quiet_NaN();
315 : double month = 0.0, date = 1.0, hours = 0.0, minutes = 0.0, seconds = 0.0,
316 : ms = 0.0;
317 1846 : if (argc >= 1) {
318 : Handle<Object> year_object;
319 3692 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, year_object,
320 : Object::ToNumber(isolate, args.at(1)));
321 : year = year_object->Number();
322 1846 : if (argc >= 2) {
323 : Handle<Object> month_object;
324 3692 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, month_object,
325 : Object::ToNumber(isolate, args.at(2)));
326 : month = month_object->Number();
327 1846 : if (argc >= 3) {
328 : Handle<Object> date_object;
329 3692 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
330 : isolate, date_object, Object::ToNumber(isolate, args.at(3)));
331 : date = date_object->Number();
332 1846 : if (argc >= 4) {
333 : Handle<Object> hours_object;
334 3546 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
335 : isolate, hours_object, Object::ToNumber(isolate, args.at(4)));
336 : hours = hours_object->Number();
337 1773 : if (argc >= 5) {
338 : Handle<Object> minutes_object;
339 1872 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
340 : isolate, minutes_object, Object::ToNumber(isolate, args.at(5)));
341 : minutes = minutes_object->Number();
342 936 : if (argc >= 6) {
343 : Handle<Object> seconds_object;
344 234 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
345 : isolate, seconds_object,
346 : Object::ToNumber(isolate, args.at(6)));
347 : seconds = seconds_object->Number();
348 117 : if (argc >= 7) {
349 : Handle<Object> ms_object;
350 198 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
351 : isolate, ms_object, Object::ToNumber(isolate, args.at(7)));
352 : ms = ms_object->Number();
353 : }
354 : }
355 : }
356 : }
357 : }
358 : }
359 : }
360 1846 : if (!std::isnan(year)) {
361 1846 : double const y = DoubleToInteger(year);
362 1846 : if (0.0 <= y && y <= 99) year = 1900 + y;
363 : }
364 1846 : double const day = MakeDay(year, month, date);
365 1846 : double const time = MakeTime(hours, minutes, seconds, ms);
366 3692 : return *isolate->factory()->NewNumber(
367 1846 : DateCache::TimeClip(MakeDate(day, time)));
368 : }
369 :
370 : // ES6 section 20.3.4.20 Date.prototype.setDate ( date )
371 1485 : BUILTIN(DatePrototypeSetDate) {
372 : HandleScope scope(isolate);
373 810 : CHECK_RECEIVER(JSDate, date, "Date.prototype.setDate");
374 : Handle<Object> value = args.atOrUndefined(isolate, 1);
375 252 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, value,
376 : Object::ToNumber(isolate, value));
377 : double time_val = date->value()->Number();
378 126 : if (!std::isnan(time_val)) {
379 108 : int64_t const time_ms = static_cast<int64_t>(time_val);
380 : int64_t local_time_ms = isolate->date_cache()->ToLocal(time_ms);
381 : int const days = isolate->date_cache()->DaysFromTime(local_time_ms);
382 : int time_within_day = isolate->date_cache()->TimeInDay(local_time_ms, days);
383 : int year, month, day;
384 108 : isolate->date_cache()->YearMonthDayFromDays(days, &year, &month, &day);
385 216 : time_val = MakeDate(MakeDay(year, month, value->Number()), time_within_day);
386 : }
387 126 : return SetLocalDateValue(isolate, date, time_val);
388 : }
389 :
390 : // ES6 section 20.3.4.21 Date.prototype.setFullYear (year, month, date)
391 4860 : BUILTIN(DatePrototypeSetFullYear) {
392 : HandleScope scope(isolate);
393 1458 : CHECK_RECEIVER(JSDate, date, "Date.prototype.setFullYear");
394 810 : int const argc = args.length() - 1;
395 : Handle<Object> year = args.atOrUndefined(isolate, 1);
396 1620 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, year,
397 : Object::ToNumber(isolate, year));
398 : double y = year->Number(), m = 0.0, dt = 1.0;
399 : int time_within_day = 0;
400 810 : if (!std::isnan(date->value()->Number())) {
401 792 : int64_t const time_ms = static_cast<int64_t>(date->value()->Number());
402 : int64_t local_time_ms = isolate->date_cache()->ToLocal(time_ms);
403 : int const days = isolate->date_cache()->DaysFromTime(local_time_ms);
404 : time_within_day = isolate->date_cache()->TimeInDay(local_time_ms, days);
405 : int year, month, day;
406 792 : isolate->date_cache()->YearMonthDayFromDays(days, &year, &month, &day);
407 792 : m = month;
408 792 : dt = day;
409 : }
410 810 : if (argc >= 2) {
411 : Handle<Object> month = args.at(2);
412 1422 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, month,
413 : Object::ToNumber(isolate, month));
414 : m = month->Number();
415 711 : if (argc >= 3) {
416 : Handle<Object> date = args.at(3);
417 1152 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, date,
418 : Object::ToNumber(isolate, date));
419 : dt = date->Number();
420 : }
421 : }
422 810 : double time_val = MakeDate(MakeDay(y, m, dt), time_within_day);
423 810 : return SetLocalDateValue(isolate, date, time_val);
424 : }
425 :
426 : // ES6 section 20.3.4.22 Date.prototype.setHours(hour, min, sec, ms)
427 16650 : BUILTIN(DatePrototypeSetHours) {
428 : HandleScope scope(isolate);
429 3843 : CHECK_RECEIVER(JSDate, date, "Date.prototype.setHours");
430 3159 : int const argc = args.length() - 1;
431 : Handle<Object> hour = args.atOrUndefined(isolate, 1);
432 6318 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, hour,
433 : Object::ToNumber(isolate, hour));
434 : double h = hour->Number();
435 : double time_val = date->value()->Number();
436 3159 : if (!std::isnan(time_val)) {
437 3114 : int64_t const time_ms = static_cast<int64_t>(time_val);
438 : int64_t local_time_ms = isolate->date_cache()->ToLocal(time_ms);
439 : int day = isolate->date_cache()->DaysFromTime(local_time_ms);
440 : int time_within_day = isolate->date_cache()->TimeInDay(local_time_ms, day);
441 3114 : double m = (time_within_day / (60 * 1000)) % 60;
442 3114 : double s = (time_within_day / 1000) % 60;
443 3114 : double milli = time_within_day % 1000;
444 3114 : if (argc >= 2) {
445 : Handle<Object> min = args.at(2);
446 6048 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, min,
447 : Object::ToNumber(isolate, min));
448 : m = min->Number();
449 3024 : if (argc >= 3) {
450 : Handle<Object> sec = args.at(3);
451 5760 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, sec,
452 : Object::ToNumber(isolate, sec));
453 : s = sec->Number();
454 2880 : if (argc >= 4) {
455 : Handle<Object> ms = args.at(4);
456 4608 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, ms,
457 : Object::ToNumber(isolate, ms));
458 : milli = ms->Number();
459 : }
460 : }
461 : }
462 3114 : time_val = MakeDate(day, MakeTime(h, m, s, milli));
463 : }
464 3159 : return SetLocalDateValue(isolate, date, time_val);
465 : }
466 :
467 : // ES6 section 20.3.4.23 Date.prototype.setMilliseconds(ms)
468 2745 : BUILTIN(DatePrototypeSetMilliseconds) {
469 : HandleScope scope(isolate);
470 1035 : CHECK_RECEIVER(JSDate, date, "Date.prototype.setMilliseconds");
471 : Handle<Object> ms = args.atOrUndefined(isolate, 1);
472 774 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, ms,
473 : Object::ToNumber(isolate, ms));
474 : double time_val = date->value()->Number();
475 387 : if (!std::isnan(time_val)) {
476 369 : int64_t const time_ms = static_cast<int64_t>(time_val);
477 : int64_t local_time_ms = isolate->date_cache()->ToLocal(time_ms);
478 : int day = isolate->date_cache()->DaysFromTime(local_time_ms);
479 : int time_within_day = isolate->date_cache()->TimeInDay(local_time_ms, day);
480 369 : int h = time_within_day / (60 * 60 * 1000);
481 369 : int m = (time_within_day / (60 * 1000)) % 60;
482 369 : int s = (time_within_day / 1000) % 60;
483 369 : time_val = MakeDate(day, MakeTime(h, m, s, ms->Number()));
484 : }
485 387 : return SetLocalDateValue(isolate, date, time_val);
486 : }
487 :
488 : // ES6 section 20.3.4.24 Date.prototype.setMinutes ( min, sec, ms )
489 5040 : BUILTIN(DatePrototypeSetMinutes) {
490 : HandleScope scope(isolate);
491 1494 : CHECK_RECEIVER(JSDate, date, "Date.prototype.setMinutes");
492 846 : int const argc = args.length() - 1;
493 : Handle<Object> min = args.atOrUndefined(isolate, 1);
494 1692 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, min,
495 : Object::ToNumber(isolate, min));
496 : double time_val = date->value()->Number();
497 846 : if (!std::isnan(time_val)) {
498 810 : int64_t const time_ms = static_cast<int64_t>(time_val);
499 : int64_t local_time_ms = isolate->date_cache()->ToLocal(time_ms);
500 : int day = isolate->date_cache()->DaysFromTime(local_time_ms);
501 : int time_within_day = isolate->date_cache()->TimeInDay(local_time_ms, day);
502 810 : int h = time_within_day / (60 * 60 * 1000);
503 : double m = min->Number();
504 810 : double s = (time_within_day / 1000) % 60;
505 810 : double milli = time_within_day % 1000;
506 810 : if (argc >= 2) {
507 : Handle<Object> sec = args.at(2);
508 1440 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, sec,
509 : Object::ToNumber(isolate, sec));
510 : s = sec->Number();
511 720 : if (argc >= 3) {
512 : Handle<Object> ms = args.at(3);
513 1152 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, ms,
514 : Object::ToNumber(isolate, ms));
515 : milli = ms->Number();
516 : }
517 : }
518 810 : time_val = MakeDate(day, MakeTime(h, m, s, milli));
519 : }
520 846 : return SetLocalDateValue(isolate, date, time_val);
521 : }
522 :
523 : // ES6 section 20.3.4.25 Date.prototype.setMonth ( month, date )
524 2160 : BUILTIN(DatePrototypeSetMonth) {
525 : HandleScope scope(isolate);
526 918 : CHECK_RECEIVER(JSDate, date, "Date.prototype.setMonth");
527 : int const argc = args.length() - 1;
528 : Handle<Object> month = args.atOrUndefined(isolate, 1);
529 540 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, month,
530 : Object::ToNumber(isolate, month));
531 : double time_val = date->value()->Number();
532 270 : if (!std::isnan(time_val)) {
533 243 : int64_t const time_ms = static_cast<int64_t>(time_val);
534 : int64_t local_time_ms = isolate->date_cache()->ToLocal(time_ms);
535 : int days = isolate->date_cache()->DaysFromTime(local_time_ms);
536 : int time_within_day = isolate->date_cache()->TimeInDay(local_time_ms, days);
537 : int year, unused, day;
538 243 : isolate->date_cache()->YearMonthDayFromDays(days, &year, &unused, &day);
539 : double m = month->Number();
540 243 : double dt = day;
541 243 : if (argc >= 2) {
542 : Handle<Object> date = args.at(2);
543 288 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, date,
544 : Object::ToNumber(isolate, date));
545 : dt = date->Number();
546 : }
547 243 : time_val = MakeDate(MakeDay(year, m, dt), time_within_day);
548 : }
549 270 : return SetLocalDateValue(isolate, date, time_val);
550 : }
551 :
552 : // ES6 section 20.3.4.26 Date.prototype.setSeconds ( sec, ms )
553 2160 : BUILTIN(DatePrototypeSetSeconds) {
554 : HandleScope scope(isolate);
555 918 : CHECK_RECEIVER(JSDate, date, "Date.prototype.setSeconds");
556 : int const argc = args.length() - 1;
557 : Handle<Object> sec = args.atOrUndefined(isolate, 1);
558 540 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, sec,
559 : Object::ToNumber(isolate, sec));
560 : double time_val = date->value()->Number();
561 270 : if (!std::isnan(time_val)) {
562 243 : int64_t const time_ms = static_cast<int64_t>(time_val);
563 : int64_t local_time_ms = isolate->date_cache()->ToLocal(time_ms);
564 : int day = isolate->date_cache()->DaysFromTime(local_time_ms);
565 : int time_within_day = isolate->date_cache()->TimeInDay(local_time_ms, day);
566 243 : int h = time_within_day / (60 * 60 * 1000);
567 243 : double m = (time_within_day / (60 * 1000)) % 60;
568 : double s = sec->Number();
569 243 : double milli = time_within_day % 1000;
570 243 : if (argc >= 2) {
571 : Handle<Object> ms = args.at(2);
572 306 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, ms,
573 : Object::ToNumber(isolate, ms));
574 : milli = ms->Number();
575 : }
576 243 : time_val = MakeDate(day, MakeTime(h, m, s, milli));
577 : }
578 270 : return SetLocalDateValue(isolate, date, time_val);
579 : }
580 :
581 : // ES6 section 20.3.4.27 Date.prototype.setTime ( time )
582 1305 : BUILTIN(DatePrototypeSetTime) {
583 : HandleScope scope(isolate);
584 774 : CHECK_RECEIVER(JSDate, date, "Date.prototype.setTime");
585 : Handle<Object> value = args.atOrUndefined(isolate, 1);
586 180 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, value,
587 : Object::ToNumber(isolate, value));
588 180 : return *JSDate::SetValue(date, DateCache::TimeClip(value->Number()));
589 : }
590 :
591 : // ES6 section 20.3.4.28 Date.prototype.setUTCDate ( date )
592 1350 : BUILTIN(DatePrototypeSetUTCDate) {
593 : HandleScope scope(isolate);
594 756 : CHECK_RECEIVER(JSDate, date, "Date.prototype.setUTCDate");
595 : Handle<Object> value = args.atOrUndefined(isolate, 1);
596 216 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, value,
597 : Object::ToNumber(isolate, value));
598 108 : if (std::isnan(date->value()->Number())) return date->value();
599 90 : int64_t const time_ms = static_cast<int64_t>(date->value()->Number());
600 : int const days = isolate->date_cache()->DaysFromTime(time_ms);
601 : int const time_within_day = isolate->date_cache()->TimeInDay(time_ms, days);
602 : int year, month, day;
603 90 : isolate->date_cache()->YearMonthDayFromDays(days, &year, &month, &day);
604 : double const time_val =
605 180 : MakeDate(MakeDay(year, month, value->Number()), time_within_day);
606 180 : return *JSDate::SetValue(date, DateCache::TimeClip(time_val));
607 : }
608 :
609 : // ES6 section 20.3.4.29 Date.prototype.setUTCFullYear (year, month, date)
610 4860 : BUILTIN(DatePrototypeSetUTCFullYear) {
611 : HandleScope scope(isolate);
612 1458 : CHECK_RECEIVER(JSDate, date, "Date.prototype.setUTCFullYear");
613 810 : int const argc = args.length() - 1;
614 : Handle<Object> year = args.atOrUndefined(isolate, 1);
615 1620 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, year,
616 : Object::ToNumber(isolate, year));
617 : double y = year->Number(), m = 0.0, dt = 1.0;
618 : int time_within_day = 0;
619 810 : if (!std::isnan(date->value()->Number())) {
620 792 : int64_t const time_ms = static_cast<int64_t>(date->value()->Number());
621 : int const days = isolate->date_cache()->DaysFromTime(time_ms);
622 : time_within_day = isolate->date_cache()->TimeInDay(time_ms, days);
623 : int year, month, day;
624 792 : isolate->date_cache()->YearMonthDayFromDays(days, &year, &month, &day);
625 792 : m = month;
626 792 : dt = day;
627 : }
628 810 : if (argc >= 2) {
629 : Handle<Object> month = args.at(2);
630 1422 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, month,
631 : Object::ToNumber(isolate, month));
632 : m = month->Number();
633 711 : if (argc >= 3) {
634 : Handle<Object> date = args.at(3);
635 1152 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, date,
636 : Object::ToNumber(isolate, date));
637 : dt = date->Number();
638 : }
639 : }
640 810 : double const time_val = MakeDate(MakeDay(y, m, dt), time_within_day);
641 1620 : return *JSDate::SetValue(date, DateCache::TimeClip(time_val));
642 : }
643 :
644 : // ES6 section 20.3.4.30 Date.prototype.setUTCHours(hour, min, sec, ms)
645 16560 : BUILTIN(DatePrototypeSetUTCHours) {
646 : HandleScope scope(isolate);
647 3798 : CHECK_RECEIVER(JSDate, date, "Date.prototype.setUTCHours");
648 3150 : int const argc = args.length() - 1;
649 : Handle<Object> hour = args.atOrUndefined(isolate, 1);
650 6300 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, hour,
651 : Object::ToNumber(isolate, hour));
652 : double h = hour->Number();
653 : double time_val = date->value()->Number();
654 3150 : if (!std::isnan(time_val)) {
655 3096 : int64_t const time_ms = static_cast<int64_t>(time_val);
656 : int day = isolate->date_cache()->DaysFromTime(time_ms);
657 : int time_within_day = isolate->date_cache()->TimeInDay(time_ms, day);
658 3096 : double m = (time_within_day / (60 * 1000)) % 60;
659 3096 : double s = (time_within_day / 1000) % 60;
660 3096 : double milli = time_within_day % 1000;
661 3096 : if (argc >= 2) {
662 : Handle<Object> min = args.at(2);
663 6012 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, min,
664 : Object::ToNumber(isolate, min));
665 : m = min->Number();
666 3006 : if (argc >= 3) {
667 : Handle<Object> sec = args.at(3);
668 5742 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, sec,
669 : Object::ToNumber(isolate, sec));
670 : s = sec->Number();
671 2871 : if (argc >= 4) {
672 : Handle<Object> ms = args.at(4);
673 4608 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, ms,
674 : Object::ToNumber(isolate, ms));
675 : milli = ms->Number();
676 : }
677 : }
678 : }
679 3096 : time_val = MakeDate(day, MakeTime(h, m, s, milli));
680 : }
681 6300 : return *JSDate::SetValue(date, DateCache::TimeClip(time_val));
682 : }
683 :
684 : // ES6 section 20.3.4.31 Date.prototype.setUTCMilliseconds(ms)
685 1305 : BUILTIN(DatePrototypeSetUTCMilliseconds) {
686 : HandleScope scope(isolate);
687 747 : CHECK_RECEIVER(JSDate, date, "Date.prototype.setUTCMilliseconds");
688 : Handle<Object> ms = args.atOrUndefined(isolate, 1);
689 198 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, ms,
690 : Object::ToNumber(isolate, ms));
691 : double time_val = date->value()->Number();
692 99 : if (!std::isnan(time_val)) {
693 81 : int64_t const time_ms = static_cast<int64_t>(time_val);
694 : int day = isolate->date_cache()->DaysFromTime(time_ms);
695 : int time_within_day = isolate->date_cache()->TimeInDay(time_ms, day);
696 81 : int h = time_within_day / (60 * 60 * 1000);
697 81 : int m = (time_within_day / (60 * 1000)) % 60;
698 81 : int s = (time_within_day / 1000) % 60;
699 81 : time_val = MakeDate(day, MakeTime(h, m, s, ms->Number()));
700 : }
701 198 : return *JSDate::SetValue(date, DateCache::TimeClip(time_val));
702 : }
703 :
704 : // ES6 section 20.3.4.32 Date.prototype.setUTCMinutes ( min, sec, ms )
705 4860 : BUILTIN(DatePrototypeSetUTCMinutes) {
706 : HandleScope scope(isolate);
707 1458 : CHECK_RECEIVER(JSDate, date, "Date.prototype.setUTCMinutes");
708 810 : int const argc = args.length() - 1;
709 : Handle<Object> min = args.atOrUndefined(isolate, 1);
710 1620 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, min,
711 : Object::ToNumber(isolate, min));
712 : double time_val = date->value()->Number();
713 810 : if (!std::isnan(time_val)) {
714 783 : int64_t const time_ms = static_cast<int64_t>(time_val);
715 : int day = isolate->date_cache()->DaysFromTime(time_ms);
716 : int time_within_day = isolate->date_cache()->TimeInDay(time_ms, day);
717 783 : int h = time_within_day / (60 * 60 * 1000);
718 : double m = min->Number();
719 783 : double s = (time_within_day / 1000) % 60;
720 783 : double milli = time_within_day % 1000;
721 783 : if (argc >= 2) {
722 : Handle<Object> sec = args.at(2);
723 1422 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, sec,
724 : Object::ToNumber(isolate, sec));
725 : s = sec->Number();
726 711 : if (argc >= 3) {
727 : Handle<Object> ms = args.at(3);
728 1152 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, ms,
729 : Object::ToNumber(isolate, ms));
730 : milli = ms->Number();
731 : }
732 : }
733 783 : time_val = MakeDate(day, MakeTime(h, m, s, milli));
734 : }
735 1620 : return *JSDate::SetValue(date, DateCache::TimeClip(time_val));
736 : }
737 :
738 : // ES6 section 20.3.4.31 Date.prototype.setUTCMonth ( month, date )
739 2070 : BUILTIN(DatePrototypeSetUTCMonth) {
740 : HandleScope scope(isolate);
741 900 : CHECK_RECEIVER(JSDate, date, "Date.prototype.setUTCMonth");
742 : int const argc = args.length() - 1;
743 : Handle<Object> month = args.atOrUndefined(isolate, 1);
744 504 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, month,
745 : Object::ToNumber(isolate, month));
746 : double time_val = date->value()->Number();
747 252 : if (!std::isnan(time_val)) {
748 225 : int64_t const time_ms = static_cast<int64_t>(time_val);
749 : int days = isolate->date_cache()->DaysFromTime(time_ms);
750 : int time_within_day = isolate->date_cache()->TimeInDay(time_ms, days);
751 : int year, unused, day;
752 225 : isolate->date_cache()->YearMonthDayFromDays(days, &year, &unused, &day);
753 : double m = month->Number();
754 225 : double dt = day;
755 225 : if (argc >= 2) {
756 : Handle<Object> date = args.at(2);
757 288 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, date,
758 : Object::ToNumber(isolate, date));
759 : dt = date->Number();
760 : }
761 225 : time_val = MakeDate(MakeDay(year, m, dt), time_within_day);
762 : }
763 504 : return *JSDate::SetValue(date, DateCache::TimeClip(time_val));
764 : }
765 :
766 : // ES6 section 20.3.4.34 Date.prototype.setUTCSeconds ( sec, ms )
767 2070 : BUILTIN(DatePrototypeSetUTCSeconds) {
768 : HandleScope scope(isolate);
769 900 : CHECK_RECEIVER(JSDate, date, "Date.prototype.setUTCSeconds");
770 : int const argc = args.length() - 1;
771 : Handle<Object> sec = args.atOrUndefined(isolate, 1);
772 504 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, sec,
773 : Object::ToNumber(isolate, sec));
774 : double time_val = date->value()->Number();
775 252 : if (!std::isnan(time_val)) {
776 225 : int64_t const time_ms = static_cast<int64_t>(time_val);
777 : int day = isolate->date_cache()->DaysFromTime(time_ms);
778 : int time_within_day = isolate->date_cache()->TimeInDay(time_ms, day);
779 225 : int h = time_within_day / (60 * 60 * 1000);
780 225 : double m = (time_within_day / (60 * 1000)) % 60;
781 : double s = sec->Number();
782 225 : double milli = time_within_day % 1000;
783 225 : if (argc >= 2) {
784 : Handle<Object> ms = args.at(2);
785 288 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, ms,
786 : Object::ToNumber(isolate, ms));
787 : milli = ms->Number();
788 : }
789 225 : time_val = MakeDate(day, MakeTime(h, m, s, milli));
790 : }
791 504 : return *JSDate::SetValue(date, DateCache::TimeClip(time_val));
792 : }
793 :
794 : // ES6 section 20.3.4.35 Date.prototype.toDateString ( )
795 1035 : BUILTIN(DatePrototypeToDateString) {
796 : HandleScope scope(isolate);
797 693 : CHECK_RECEIVER(JSDate, date, "Date.prototype.toDateString");
798 : DateBuffer buffer =
799 45 : ToDateString(date->value()->Number(), isolate->date_cache(), kDateOnly);
800 90 : RETURN_RESULT_OR_FAILURE(
801 : isolate, isolate->factory()->NewStringFromUtf8(VectorOf(buffer)));
802 : }
803 :
804 : // ES6 section 20.3.4.36 Date.prototype.toISOString ( )
805 1765 : BUILTIN(DatePrototypeToISOString) {
806 : HandleScope scope(isolate);
807 839 : CHECK_RECEIVER(JSDate, date, "Date.prototype.toISOString");
808 : double const time_val = date->value()->Number();
809 191 : if (std::isnan(time_val)) {
810 36 : THROW_NEW_ERROR_RETURN_FAILURE(
811 : isolate, NewRangeError(MessageTemplate::kInvalidTimeValue));
812 : }
813 173 : int64_t const time_ms = static_cast<int64_t>(time_val);
814 : int year, month, day, weekday, hour, min, sec, ms;
815 : isolate->date_cache()->BreakDownTime(time_ms, &year, &month, &day, &weekday,
816 173 : &hour, &min, &sec, &ms);
817 : char buffer[128];
818 173 : if (year >= 0 && year <= 9999) {
819 164 : SNPrintF(ArrayVector(buffer), "%04d-%02d-%02dT%02d:%02d:%02d.%03dZ", year,
820 328 : month + 1, day, hour, min, sec, ms);
821 9 : } else if (year < 0) {
822 0 : SNPrintF(ArrayVector(buffer), "-%06d-%02d-%02dT%02d:%02d:%02d.%03dZ", -year,
823 0 : month + 1, day, hour, min, sec, ms);
824 : } else {
825 9 : SNPrintF(ArrayVector(buffer), "+%06d-%02d-%02dT%02d:%02d:%02d.%03dZ", year,
826 18 : month + 1, day, hour, min, sec, ms);
827 : }
828 346 : return *isolate->factory()->NewStringFromAsciiChecked(buffer);
829 : }
830 :
831 : // ES6 section 20.3.4.41 Date.prototype.toString ( )
832 268290 : BUILTIN(DatePrototypeToString) {
833 : HandleScope scope(isolate);
834 54171 : CHECK_RECEIVER(JSDate, date, "Date.prototype.toString");
835 : DateBuffer buffer =
836 53487 : ToDateString(date->value()->Number(), isolate->date_cache());
837 106974 : RETURN_RESULT_OR_FAILURE(
838 : isolate, isolate->factory()->NewStringFromUtf8(VectorOf(buffer)));
839 : }
840 :
841 : // ES6 section 20.3.4.42 Date.prototype.toTimeString ( )
842 990 : BUILTIN(DatePrototypeToTimeString) {
843 : HandleScope scope(isolate);
844 684 : CHECK_RECEIVER(JSDate, date, "Date.prototype.toTimeString");
845 : DateBuffer buffer =
846 36 : ToDateString(date->value()->Number(), isolate->date_cache(), kTimeOnly);
847 72 : RETURN_RESULT_OR_FAILURE(
848 : isolate, isolate->factory()->NewStringFromUtf8(VectorOf(buffer)));
849 : }
850 :
851 : #ifdef V8_INTL_SUPPORT
852 : // ecma402 #sup-date.prototype.tolocaledatestring
853 1440 : BUILTIN(DatePrototypeToLocaleDateString) {
854 : HandleScope scope(isolate);
855 :
856 288 : isolate->CountUsage(v8::Isolate::UseCounterFeature::kDateToLocaleDateString);
857 :
858 774 : CHECK_RECEIVER(JSDate, date, "Date.prototype.toLocaleDateString");
859 :
860 261 : RETURN_RESULT_OR_FAILURE(
861 : isolate, JSDateTimeFormat::ToLocaleDateTime(
862 : isolate,
863 : date, // date
864 : args.atOrUndefined(isolate, 1), // locales
865 : args.atOrUndefined(isolate, 2), // options
866 : JSDateTimeFormat::RequiredOption::kDate, // required
867 : JSDateTimeFormat::DefaultsOption::kDate)); // defaults
868 : }
869 :
870 : // ecma402 #sup-date.prototype.tolocalestring
871 1305 : BUILTIN(DatePrototypeToLocaleString) {
872 : HandleScope scope(isolate);
873 :
874 261 : isolate->CountUsage(v8::Isolate::UseCounterFeature::kDateToLocaleString);
875 :
876 747 : CHECK_RECEIVER(JSDate, date, "Date.prototype.toLocaleString");
877 :
878 198 : RETURN_RESULT_OR_FAILURE(
879 : isolate, JSDateTimeFormat::ToLocaleDateTime(
880 : isolate,
881 : date, // date
882 : args.atOrUndefined(isolate, 1), // locales
883 : args.atOrUndefined(isolate, 2), // options
884 : JSDateTimeFormat::RequiredOption::kAny, // required
885 : JSDateTimeFormat::DefaultsOption::kAll)); // defaults
886 : }
887 :
888 : // ecma402 #sup-date.prototype.tolocaletimestring
889 1215 : BUILTIN(DatePrototypeToLocaleTimeString) {
890 : HandleScope scope(isolate);
891 :
892 243 : isolate->CountUsage(v8::Isolate::UseCounterFeature::kDateToLocaleTimeString);
893 :
894 729 : CHECK_RECEIVER(JSDate, date, "Date.prototype.toLocaleTimeString");
895 :
896 162 : RETURN_RESULT_OR_FAILURE(
897 : isolate, JSDateTimeFormat::ToLocaleDateTime(
898 : isolate,
899 : date, // date
900 : args.atOrUndefined(isolate, 1), // locales
901 : args.atOrUndefined(isolate, 2), // options
902 : JSDateTimeFormat::RequiredOption::kTime, // required
903 : JSDateTimeFormat::DefaultsOption::kTime)); // defaults
904 : }
905 : #endif // V8_INTL_SUPPORT
906 :
907 : // ES6 section 20.3.4.43 Date.prototype.toUTCString ( )
908 1215 : BUILTIN(DatePrototypeToUTCString) {
909 : HandleScope scope(isolate);
910 729 : CHECK_RECEIVER(JSDate, date, "Date.prototype.toUTCString");
911 : double const time_val = date->value()->Number();
912 81 : if (std::isnan(time_val)) {
913 0 : return *isolate->factory()->NewStringFromAsciiChecked("Invalid Date");
914 : }
915 : char buffer[128];
916 81 : int64_t time_ms = static_cast<int64_t>(time_val);
917 : int year, month, day, weekday, hour, min, sec, ms;
918 : isolate->date_cache()->BreakDownTime(time_ms, &year, &month, &day, &weekday,
919 81 : &hour, &min, &sec, &ms);
920 243 : SNPrintF(ArrayVector(buffer),
921 81 : (year < 0) ? "%s, %02d %s %05d %02d:%02d:%02d GMT"
922 : : "%s, %02d %s %04d %02d:%02d:%02d GMT",
923 : kShortWeekDays[weekday], day, kShortMonths[month], year, hour, min,
924 243 : sec);
925 162 : return *isolate->factory()->NewStringFromAsciiChecked(buffer);
926 : }
927 :
928 : // ES6 section B.2.4.1 Date.prototype.getYear ( )
929 810 : BUILTIN(DatePrototypeGetYear) {
930 : HandleScope scope(isolate);
931 216 : CHECK_RECEIVER(JSDate, date, "Date.prototype.getYear");
932 : double time_val = date->value()->Number();
933 144 : if (std::isnan(time_val)) return date->value();
934 108 : int64_t time_ms = static_cast<int64_t>(time_val);
935 : int64_t local_time_ms = isolate->date_cache()->ToLocal(time_ms);
936 : int days = isolate->date_cache()->DaysFromTime(local_time_ms);
937 : int year, month, day;
938 108 : isolate->date_cache()->YearMonthDayFromDays(days, &year, &month, &day);
939 216 : return Smi::FromInt(year - 1900);
940 : }
941 :
942 : // ES6 section B.2.4.2 Date.prototype.setYear ( year )
943 855 : BUILTIN(DatePrototypeSetYear) {
944 : HandleScope scope(isolate);
945 198 : CHECK_RECEIVER(JSDate, date, "Date.prototype.setYear");
946 : Handle<Object> year = args.atOrUndefined(isolate, 1);
947 324 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, year,
948 : Object::ToNumber(isolate, year));
949 : double m = 0.0, dt = 1.0, y = year->Number();
950 162 : if (!std::isnan(y)) {
951 117 : double y_int = DoubleToInteger(y);
952 117 : if (0.0 <= y_int && y_int <= 99.0) {
953 27 : y = 1900.0 + y_int;
954 : }
955 : }
956 : int time_within_day = 0;
957 162 : if (!std::isnan(date->value()->Number())) {
958 144 : int64_t const time_ms = static_cast<int64_t>(date->value()->Number());
959 : int64_t local_time_ms = isolate->date_cache()->ToLocal(time_ms);
960 : int const days = isolate->date_cache()->DaysFromTime(local_time_ms);
961 : time_within_day = isolate->date_cache()->TimeInDay(local_time_ms, days);
962 : int year, month, day;
963 144 : isolate->date_cache()->YearMonthDayFromDays(days, &year, &month, &day);
964 144 : m = month;
965 144 : dt = day;
966 : }
967 162 : double time_val = MakeDate(MakeDay(y, m, dt), time_within_day);
968 162 : return SetLocalDateValue(isolate, date, time_val);
969 : }
970 :
971 : // ES6 section 20.3.4.37 Date.prototype.toJSON ( key )
972 1575 : BUILTIN(DatePrototypeToJson) {
973 : HandleScope scope(isolate);
974 315 : Handle<Object> receiver = args.atOrUndefined(isolate, 0);
975 : Handle<JSReceiver> receiver_obj;
976 792 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver_obj,
977 : Object::ToObject(isolate, receiver));
978 : Handle<Object> primitive;
979 315 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
980 : isolate, primitive,
981 : Object::ToPrimitive(receiver_obj, ToPrimitiveHint::kNumber));
982 252 : if (primitive->IsNumber() && !std::isfinite(primitive->Number())) {
983 18 : return ReadOnlyRoots(isolate).null_value();
984 : } else {
985 : Handle<String> name =
986 126 : isolate->factory()->NewStringFromAsciiChecked("toISOString");
987 : Handle<Object> function;
988 252 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
989 : isolate, function, Object::GetProperty(isolate, receiver_obj, name));
990 126 : if (!function->IsCallable()) {
991 36 : THROW_NEW_ERROR_RETURN_FAILURE(
992 : isolate, NewTypeError(MessageTemplate::kCalledNonCallable, name));
993 : }
994 216 : RETURN_RESULT_OR_FAILURE(
995 : isolate, Execution::Call(isolate, function, receiver_obj, 0, nullptr));
996 : }
997 : }
998 :
999 : } // namespace internal
1000 122036 : } // namespace v8
|