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