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 143564 : if (std::isfinite(day) && std::isfinite(time)) {
44 62377 : 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 64321 : double MakeDay(double year, double month, double date) {
51 127778 : if ((kMinYear <= year && year <= kMaxYear) &&
52 189390 : (kMinMonth <= month && month <= kMaxMonth) && std::isfinite(date)) {
53 : int y = FastD2I(year);
54 : int m = FastD2I(month);
55 62233 : y += m / 12;
56 62233 : m %= 12;
57 62233 : 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 124466 : int day_from_year = 365 * (y + kYearDelta) + (y + kYearDelta) / 4 -
77 124466 : (y + kYearDelta) / 100 + (y + kYearDelta) / 400 -
78 62233 : kBaseDay;
79 62233 : 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 45218 : 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 17015 : day_from_year += kDayFromMonth[m];
87 : }
88 62233 : 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 70567 : double MakeTime(double hour, double min, double sec, double ms) {
95 262819 : if (std::isfinite(hour) && std::isfinite(min) && std::isfinite(sec) &&
96 : std::isfinite(ms)) {
97 62206 : double const h = DoubleToInteger(hour);
98 62206 : double const m = DoubleToInteger(min);
99 62206 : double const s = DoubleToInteger(sec);
100 62206 : double const milli = DoubleToInteger(ms);
101 62206 : 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 58351 : double ParseDateTimeString(Isolate* isolate, Handle<String> str) {
113 58351 : str = String::Flatten(isolate, str);
114 : // TODO(bmeurer): Change DateParser to not use the FixedArray.
115 : Handle<FixedArray> tmp =
116 58351 : isolate->factory()->NewFixedArray(DateParser::OUTPUT_SIZE);
117 : DisallowHeapAllocation no_gc;
118 58351 : String::FlatContent str_content = str->GetFlatContent(no_gc);
119 : bool result;
120 58351 : if (str_content.IsOneByte()) {
121 58351 : result = DateParser::Parse(isolate, str_content.ToOneByteVector(), *tmp);
122 : } else {
123 0 : result = DateParser::Parse(isolate, str_content.ToUC16Vector(), *tmp);
124 : }
125 58351 : if (!result) return std::numeric_limits<double>::quiet_NaN();
126 : double const day = MakeDay(tmp->get(0)->Number(), tmp->get(1)->Number(),
127 57837 : tmp->get(2)->Number());
128 : double const time = MakeTime(tmp->get(3)->Number(), tmp->get(4)->Number(),
129 57837 : tmp->get(5)->Number(), tmp->get(6)->Number());
130 : double date = MakeDate(day, time);
131 57837 : if (tmp->get(7)->IsNull(isolate)) {
132 529 : if (date >= -DateCache::kMaxTimeBeforeUTCInMs &&
133 : date <= DateCache::kMaxTimeBeforeUTCInMs) {
134 1022 : 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 57819 : 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 53469 : DateBuffer FormatDate(const char* format, Args... args) {
150 : DateBuffer buffer;
151 : SmallStringOptimizedAllocator<DateBuffer::kInlineSize> allocator(&buffer);
152 : StringStream sstream(&allocator);
153 53469 : sstream.Add(format, args...);
154 53469 : buffer.resize_no_init(sstream.length());
155 53469 : return buffer;
156 : }
157 :
158 : // ES6 section 20.3.4.41.1 ToDateString(tv)
159 53469 : DateBuffer ToDateString(double time_val, DateCache* date_cache,
160 : ToDateStringMode mode = kDateAndTime) {
161 53469 : if (std::isnan(time_val)) {
162 63 : return FormatDate("Invalid Date");
163 : }
164 53406 : 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 53406 : &min, &sec, &ms);
169 53406 : int timezone_offset = -date_cache->TimezoneOffset(time_ms);
170 53406 : int timezone_hour = std::abs(timezone_offset) / 60;
171 53406 : int timezone_min = std::abs(timezone_offset) % 60;
172 53406 : const char* local_timezone = date_cache->LocalTimezone(time_ms);
173 53406 : switch (mode) {
174 : case kDateOnly:
175 : return FormatDate("%s %s %02d %04d", kShortWeekDays[weekday],
176 18 : kShortMonths[month], day, year);
177 : case kTimeOnly:
178 : return FormatDate("%02d:%02d:%02d GMT%c%02d%02d (%s)", hour, min, sec,
179 : (timezone_offset < 0) ? '-' : '+', timezone_hour,
180 9 : timezone_min, local_timezone);
181 : case kDateAndTime:
182 : return FormatDate("%s %s %02d %04d %02d:%02d:%02d GMT%c%02d%02d (%s)",
183 : kShortWeekDays[weekday], kShortMonths[month], day, year,
184 : hour, min, sec, (timezone_offset < 0) ? '-' : '+',
185 53379 : timezone_hour, timezone_min, local_timezone);
186 : }
187 0 : UNREACHABLE();
188 : }
189 :
190 5814 : Object SetLocalDateValue(Isolate* isolate, Handle<JSDate> date,
191 : double time_val) {
192 5814 : if (time_val >= -DateCache::kMaxTimeBeforeUTCInMs &&
193 : time_val <= DateCache::kMaxTimeBeforeUTCInMs) {
194 684 : time_val = isolate->date_cache()->ToUTC(static_cast<int64_t>(time_val));
195 : } else {
196 : time_val = std::numeric_limits<double>::quiet_NaN();
197 : }
198 11628 : return *JSDate::SetValue(date, DateCache::TimeClip(time_val));
199 : }
200 :
201 : } // namespace
202 :
203 : // ES #sec-date-constructor
204 744665 : BUILTIN(DateConstructor) {
205 : HandleScope scope(isolate);
206 148933 : if (args.new_target()->IsUndefined(isolate)) {
207 36 : double const time_val = JSDate::CurrentTimeValue(isolate);
208 36 : DateBuffer buffer = ToDateString(time_val, isolate->date_cache());
209 72 : RETURN_RESULT_OR_FAILURE(
210 : isolate, isolate->factory()->NewStringFromUtf8(VectorOf(buffer)));
211 : }
212 : // [Construct]
213 148897 : int const argc = args.length() - 1;
214 148897 : Handle<JSFunction> target = args.target();
215 148897 : Handle<JSReceiver> new_target = Handle<JSReceiver>::cast(args.new_target());
216 : double time_val;
217 148897 : if (argc == 0) {
218 91291 : time_val = JSDate::CurrentTimeValue(isolate);
219 57606 : } else if (argc == 1) {
220 : Handle<Object> value = args.at(1);
221 55227 : if (value->IsJSDate()) {
222 : time_val = Handle<JSDate>::cast(value)->value()->Number();
223 : } else {
224 110139 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, value,
225 : Object::ToPrimitive(value));
226 55056 : if (value->IsString()) {
227 375 : time_val = ParseDateTimeString(isolate, Handle<String>::cast(value));
228 : } else {
229 109362 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, value,
230 : Object::ToNumber(isolate, value));
231 : time_val = value->Number();
232 : }
233 : }
234 : } else {
235 : Handle<Object> year_object;
236 4758 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, year_object,
237 : Object::ToNumber(isolate, args.at(1)));
238 : Handle<Object> month_object;
239 4758 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, month_object,
240 : Object::ToNumber(isolate, args.at(2)));
241 : double year = year_object->Number();
242 : double month = month_object->Number();
243 : double date = 1.0, hours = 0.0, minutes = 0.0, seconds = 0.0, ms = 0.0;
244 2379 : if (argc >= 3) {
245 : Handle<Object> date_object;
246 4578 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, date_object,
247 : Object::ToNumber(isolate, args.at(3)));
248 : date = date_object->Number();
249 2289 : if (argc >= 4) {
250 : Handle<Object> hours_object;
251 4122 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
252 : isolate, hours_object, Object::ToNumber(isolate, args.at(4)));
253 : hours = hours_object->Number();
254 2061 : if (argc >= 5) {
255 : Handle<Object> minutes_object;
256 2304 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
257 : isolate, minutes_object, Object::ToNumber(isolate, args.at(5)));
258 : minutes = minutes_object->Number();
259 1152 : if (argc >= 6) {
260 : Handle<Object> seconds_object;
261 450 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
262 : isolate, seconds_object, Object::ToNumber(isolate, args.at(6)));
263 : seconds = seconds_object->Number();
264 225 : if (argc >= 7) {
265 : Handle<Object> ms_object;
266 378 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
267 : isolate, ms_object, Object::ToNumber(isolate, args.at(7)));
268 : ms = ms_object->Number();
269 : }
270 : }
271 : }
272 : }
273 : }
274 2379 : if (!std::isnan(year)) {
275 2361 : double const y = DoubleToInteger(year);
276 2361 : if (0.0 <= y && y <= 99) year = 1900 + y;
277 : }
278 2379 : double const day = MakeDay(year, month, date);
279 2379 : double const time = MakeTime(hours, minutes, seconds, ms);
280 : time_val = MakeDate(day, time);
281 2379 : if (time_val >= -DateCache::kMaxTimeBeforeUTCInMs &&
282 : time_val <= DateCache::kMaxTimeBeforeUTCInMs) {
283 4398 : time_val = isolate->date_cache()->ToUTC(static_cast<int64_t>(time_val));
284 : } else {
285 : time_val = std::numeric_limits<double>::quiet_NaN();
286 : }
287 : }
288 297776 : RETURN_RESULT_OR_FAILURE(isolate, JSDate::New(target, new_target, time_val));
289 : }
290 :
291 : // ES6 section 20.3.3.1 Date.now ( )
292 1780955 : BUILTIN(DateNow) {
293 : HandleScope scope(isolate);
294 1068573 : return *isolate->factory()->NewNumber(JSDate::CurrentTimeValue(isolate));
295 : }
296 :
297 : // ES6 section 20.3.3.2 Date.parse ( string )
298 289880 : BUILTIN(DateParse) {
299 : HandleScope scope(isolate);
300 : Handle<String> string;
301 115952 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
302 : isolate, string,
303 : Object::ToString(isolate, args.atOrUndefined(isolate, 1)));
304 115952 : return *isolate->factory()->NewNumber(ParseDateTimeString(isolate, string));
305 : }
306 :
307 : // ES6 section 20.3.3.4 Date.UTC (year,month,date,hours,minutes,seconds,ms)
308 9230 : BUILTIN(DateUTC) {
309 : HandleScope scope(isolate);
310 1846 : int const argc = args.length() - 1;
311 : double year = std::numeric_limits<double>::quiet_NaN();
312 : double month = 0.0, date = 1.0, hours = 0.0, minutes = 0.0, seconds = 0.0,
313 : ms = 0.0;
314 1846 : if (argc >= 1) {
315 : Handle<Object> year_object;
316 3692 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, year_object,
317 : Object::ToNumber(isolate, args.at(1)));
318 : year = year_object->Number();
319 1846 : if (argc >= 2) {
320 : Handle<Object> month_object;
321 3692 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, month_object,
322 : Object::ToNumber(isolate, args.at(2)));
323 : month = month_object->Number();
324 1846 : if (argc >= 3) {
325 : Handle<Object> date_object;
326 3692 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
327 : isolate, date_object, Object::ToNumber(isolate, args.at(3)));
328 : date = date_object->Number();
329 1846 : if (argc >= 4) {
330 : Handle<Object> hours_object;
331 3546 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
332 : isolate, hours_object, Object::ToNumber(isolate, args.at(4)));
333 : hours = hours_object->Number();
334 1773 : if (argc >= 5) {
335 : Handle<Object> minutes_object;
336 1872 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
337 : isolate, minutes_object, Object::ToNumber(isolate, args.at(5)));
338 : minutes = minutes_object->Number();
339 936 : if (argc >= 6) {
340 : Handle<Object> seconds_object;
341 234 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
342 : isolate, seconds_object,
343 : Object::ToNumber(isolate, args.at(6)));
344 : seconds = seconds_object->Number();
345 117 : if (argc >= 7) {
346 : Handle<Object> ms_object;
347 198 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
348 : isolate, ms_object, Object::ToNumber(isolate, args.at(7)));
349 : ms = ms_object->Number();
350 : }
351 : }
352 : }
353 : }
354 : }
355 : }
356 : }
357 1846 : if (!std::isnan(year)) {
358 1846 : double const y = DoubleToInteger(year);
359 1846 : if (0.0 <= y && y <= 99) year = 1900 + y;
360 : }
361 1846 : double const day = MakeDay(year, month, date);
362 1846 : double const time = MakeTime(hours, minutes, seconds, ms);
363 3692 : return *isolate->factory()->NewNumber(
364 1846 : DateCache::TimeClip(MakeDate(day, time)));
365 : }
366 :
367 : // ES6 section 20.3.4.20 Date.prototype.setDate ( date )
368 1350 : BUILTIN(DatePrototypeSetDate) {
369 : HandleScope scope(isolate);
370 783 : CHECK_RECEIVER(JSDate, date, "Date.prototype.setDate");
371 : Handle<Object> value = args.atOrUndefined(isolate, 1);
372 198 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, value,
373 : Object::ToNumber(isolate, value));
374 : double time_val = date->value()->Number();
375 99 : if (!std::isnan(time_val)) {
376 81 : int64_t const time_ms = static_cast<int64_t>(time_val);
377 : int64_t local_time_ms = isolate->date_cache()->ToLocal(time_ms);
378 : int const days = isolate->date_cache()->DaysFromTime(local_time_ms);
379 : int time_within_day = isolate->date_cache()->TimeInDay(local_time_ms, days);
380 : int year, month, day;
381 81 : isolate->date_cache()->YearMonthDayFromDays(days, &year, &month, &day);
382 162 : time_val = MakeDate(MakeDay(year, month, value->Number()), time_within_day);
383 : }
384 99 : return SetLocalDateValue(isolate, date, time_val);
385 : }
386 :
387 : // ES6 section 20.3.4.21 Date.prototype.setFullYear (year, month, date)
388 4725 : BUILTIN(DatePrototypeSetFullYear) {
389 : HandleScope scope(isolate);
390 1431 : CHECK_RECEIVER(JSDate, date, "Date.prototype.setFullYear");
391 783 : int const argc = args.length() - 1;
392 : Handle<Object> year = args.atOrUndefined(isolate, 1);
393 1566 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, year,
394 : Object::ToNumber(isolate, year));
395 : double y = year->Number(), m = 0.0, dt = 1.0;
396 : int time_within_day = 0;
397 783 : if (!std::isnan(date->value()->Number())) {
398 765 : int64_t const time_ms = static_cast<int64_t>(date->value()->Number());
399 : int64_t local_time_ms = isolate->date_cache()->ToLocal(time_ms);
400 : int const days = isolate->date_cache()->DaysFromTime(local_time_ms);
401 : time_within_day = isolate->date_cache()->TimeInDay(local_time_ms, days);
402 : int year, month, day;
403 765 : isolate->date_cache()->YearMonthDayFromDays(days, &year, &month, &day);
404 765 : m = month;
405 765 : dt = day;
406 : }
407 783 : if (argc >= 2) {
408 : Handle<Object> month = args.at(2);
409 1422 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, month,
410 : Object::ToNumber(isolate, month));
411 : m = month->Number();
412 711 : if (argc >= 3) {
413 : Handle<Object> date = args.at(3);
414 1152 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, date,
415 : Object::ToNumber(isolate, date));
416 : dt = date->Number();
417 : }
418 : }
419 783 : double time_val = MakeDate(MakeDay(y, m, dt), time_within_day);
420 783 : return SetLocalDateValue(isolate, date, time_val);
421 : }
422 :
423 : // ES6 section 20.3.4.22 Date.prototype.setHours(hour, min, sec, ms)
424 16515 : BUILTIN(DatePrototypeSetHours) {
425 : HandleScope scope(isolate);
426 3816 : CHECK_RECEIVER(JSDate, date, "Date.prototype.setHours");
427 3132 : int const argc = args.length() - 1;
428 : Handle<Object> hour = args.atOrUndefined(isolate, 1);
429 6264 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, hour,
430 : Object::ToNumber(isolate, hour));
431 : double h = hour->Number();
432 : double time_val = date->value()->Number();
433 3132 : if (!std::isnan(time_val)) {
434 3087 : int64_t const time_ms = static_cast<int64_t>(time_val);
435 : int64_t local_time_ms = isolate->date_cache()->ToLocal(time_ms);
436 : int day = isolate->date_cache()->DaysFromTime(local_time_ms);
437 : int time_within_day = isolate->date_cache()->TimeInDay(local_time_ms, day);
438 3087 : double m = (time_within_day / (60 * 1000)) % 60;
439 3087 : double s = (time_within_day / 1000) % 60;
440 3087 : double milli = time_within_day % 1000;
441 3087 : if (argc >= 2) {
442 : Handle<Object> min = args.at(2);
443 6048 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, min,
444 : Object::ToNumber(isolate, min));
445 : m = min->Number();
446 3024 : if (argc >= 3) {
447 : Handle<Object> sec = args.at(3);
448 5760 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, sec,
449 : Object::ToNumber(isolate, sec));
450 : s = sec->Number();
451 2880 : if (argc >= 4) {
452 : Handle<Object> ms = args.at(4);
453 4608 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, ms,
454 : Object::ToNumber(isolate, ms));
455 : milli = ms->Number();
456 : }
457 : }
458 : }
459 3087 : time_val = MakeDate(day, MakeTime(h, m, s, milli));
460 : }
461 3132 : return SetLocalDateValue(isolate, date, time_val);
462 : }
463 :
464 : // ES6 section 20.3.4.23 Date.prototype.setMilliseconds(ms)
465 2610 : BUILTIN(DatePrototypeSetMilliseconds) {
466 : HandleScope scope(isolate);
467 1008 : CHECK_RECEIVER(JSDate, date, "Date.prototype.setMilliseconds");
468 : Handle<Object> ms = args.atOrUndefined(isolate, 1);
469 720 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, ms,
470 : Object::ToNumber(isolate, ms));
471 : double time_val = date->value()->Number();
472 360 : if (!std::isnan(time_val)) {
473 342 : int64_t const time_ms = static_cast<int64_t>(time_val);
474 : int64_t local_time_ms = isolate->date_cache()->ToLocal(time_ms);
475 : int day = isolate->date_cache()->DaysFromTime(local_time_ms);
476 : int time_within_day = isolate->date_cache()->TimeInDay(local_time_ms, day);
477 342 : int h = time_within_day / (60 * 60 * 1000);
478 342 : int m = (time_within_day / (60 * 1000)) % 60;
479 342 : int s = (time_within_day / 1000) % 60;
480 342 : time_val = MakeDate(day, MakeTime(h, m, s, ms->Number()));
481 : }
482 360 : return SetLocalDateValue(isolate, date, time_val);
483 : }
484 :
485 : // ES6 section 20.3.4.24 Date.prototype.setMinutes ( min, sec, ms )
486 4905 : BUILTIN(DatePrototypeSetMinutes) {
487 : HandleScope scope(isolate);
488 1467 : CHECK_RECEIVER(JSDate, date, "Date.prototype.setMinutes");
489 819 : int const argc = args.length() - 1;
490 : Handle<Object> min = args.atOrUndefined(isolate, 1);
491 1638 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, min,
492 : Object::ToNumber(isolate, min));
493 : double time_val = date->value()->Number();
494 819 : if (!std::isnan(time_val)) {
495 783 : int64_t const time_ms = static_cast<int64_t>(time_val);
496 : int64_t local_time_ms = isolate->date_cache()->ToLocal(time_ms);
497 : int day = isolate->date_cache()->DaysFromTime(local_time_ms);
498 : int time_within_day = isolate->date_cache()->TimeInDay(local_time_ms, day);
499 783 : int h = time_within_day / (60 * 60 * 1000);
500 : double m = min->Number();
501 783 : double s = (time_within_day / 1000) % 60;
502 783 : double milli = time_within_day % 1000;
503 783 : if (argc >= 2) {
504 : Handle<Object> sec = args.at(2);
505 1440 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, sec,
506 : Object::ToNumber(isolate, sec));
507 : s = sec->Number();
508 720 : if (argc >= 3) {
509 : Handle<Object> ms = args.at(3);
510 1152 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, ms,
511 : Object::ToNumber(isolate, ms));
512 : milli = ms->Number();
513 : }
514 : }
515 783 : time_val = MakeDate(day, MakeTime(h, m, s, milli));
516 : }
517 819 : return SetLocalDateValue(isolate, date, time_val);
518 : }
519 :
520 : // ES6 section 20.3.4.25 Date.prototype.setMonth ( month, date )
521 2025 : BUILTIN(DatePrototypeSetMonth) {
522 : HandleScope scope(isolate);
523 891 : CHECK_RECEIVER(JSDate, date, "Date.prototype.setMonth");
524 : int const argc = args.length() - 1;
525 : Handle<Object> month = args.atOrUndefined(isolate, 1);
526 486 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, month,
527 : Object::ToNumber(isolate, month));
528 : double time_val = date->value()->Number();
529 243 : if (!std::isnan(time_val)) {
530 216 : int64_t const time_ms = static_cast<int64_t>(time_val);
531 : int64_t local_time_ms = isolate->date_cache()->ToLocal(time_ms);
532 : int days = isolate->date_cache()->DaysFromTime(local_time_ms);
533 : int time_within_day = isolate->date_cache()->TimeInDay(local_time_ms, days);
534 : int year, unused, day;
535 216 : isolate->date_cache()->YearMonthDayFromDays(days, &year, &unused, &day);
536 : double m = month->Number();
537 216 : double dt = day;
538 216 : if (argc >= 2) {
539 : Handle<Object> date = args.at(2);
540 288 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, date,
541 : Object::ToNumber(isolate, date));
542 : dt = date->Number();
543 : }
544 216 : time_val = MakeDate(MakeDay(year, m, dt), time_within_day);
545 : }
546 243 : return SetLocalDateValue(isolate, date, time_val);
547 : }
548 :
549 : // ES6 section 20.3.4.26 Date.prototype.setSeconds ( sec, ms )
550 2025 : BUILTIN(DatePrototypeSetSeconds) {
551 : HandleScope scope(isolate);
552 891 : CHECK_RECEIVER(JSDate, date, "Date.prototype.setSeconds");
553 : int const argc = args.length() - 1;
554 : Handle<Object> sec = args.atOrUndefined(isolate, 1);
555 486 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, sec,
556 : Object::ToNumber(isolate, sec));
557 : double time_val = date->value()->Number();
558 243 : if (!std::isnan(time_val)) {
559 216 : int64_t const time_ms = static_cast<int64_t>(time_val);
560 : int64_t local_time_ms = isolate->date_cache()->ToLocal(time_ms);
561 : int day = isolate->date_cache()->DaysFromTime(local_time_ms);
562 : int time_within_day = isolate->date_cache()->TimeInDay(local_time_ms, day);
563 216 : int h = time_within_day / (60 * 60 * 1000);
564 216 : double m = (time_within_day / (60 * 1000)) % 60;
565 : double s = sec->Number();
566 216 : double milli = time_within_day % 1000;
567 216 : if (argc >= 2) {
568 : Handle<Object> ms = args.at(2);
569 306 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, ms,
570 : Object::ToNumber(isolate, ms));
571 : milli = ms->Number();
572 : }
573 216 : time_val = MakeDate(day, MakeTime(h, m, s, milli));
574 : }
575 243 : return SetLocalDateValue(isolate, date, time_val);
576 : }
577 :
578 : // ES6 section 20.3.4.27 Date.prototype.setTime ( time )
579 1170 : BUILTIN(DatePrototypeSetTime) {
580 : HandleScope scope(isolate);
581 747 : CHECK_RECEIVER(JSDate, date, "Date.prototype.setTime");
582 : Handle<Object> value = args.atOrUndefined(isolate, 1);
583 126 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, value,
584 : Object::ToNumber(isolate, value));
585 126 : return *JSDate::SetValue(date, DateCache::TimeClip(value->Number()));
586 : }
587 :
588 : // ES6 section 20.3.4.28 Date.prototype.setUTCDate ( date )
589 1215 : BUILTIN(DatePrototypeSetUTCDate) {
590 : HandleScope scope(isolate);
591 729 : CHECK_RECEIVER(JSDate, date, "Date.prototype.setUTCDate");
592 : Handle<Object> value = args.atOrUndefined(isolate, 1);
593 162 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, value,
594 : Object::ToNumber(isolate, value));
595 81 : if (std::isnan(date->value()->Number())) return date->value();
596 63 : int64_t const time_ms = static_cast<int64_t>(date->value()->Number());
597 : int const days = isolate->date_cache()->DaysFromTime(time_ms);
598 : int const time_within_day = isolate->date_cache()->TimeInDay(time_ms, days);
599 : int year, month, day;
600 63 : isolate->date_cache()->YearMonthDayFromDays(days, &year, &month, &day);
601 : double const time_val =
602 126 : MakeDate(MakeDay(year, month, value->Number()), time_within_day);
603 126 : return *JSDate::SetValue(date, DateCache::TimeClip(time_val));
604 : }
605 :
606 : // ES6 section 20.3.4.29 Date.prototype.setUTCFullYear (year, month, date)
607 4725 : BUILTIN(DatePrototypeSetUTCFullYear) {
608 : HandleScope scope(isolate);
609 1431 : CHECK_RECEIVER(JSDate, date, "Date.prototype.setUTCFullYear");
610 783 : int const argc = args.length() - 1;
611 : Handle<Object> year = args.atOrUndefined(isolate, 1);
612 1566 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, year,
613 : Object::ToNumber(isolate, year));
614 : double y = year->Number(), m = 0.0, dt = 1.0;
615 : int time_within_day = 0;
616 783 : if (!std::isnan(date->value()->Number())) {
617 765 : int64_t const time_ms = static_cast<int64_t>(date->value()->Number());
618 : int const days = isolate->date_cache()->DaysFromTime(time_ms);
619 : time_within_day = isolate->date_cache()->TimeInDay(time_ms, days);
620 : int year, month, day;
621 765 : isolate->date_cache()->YearMonthDayFromDays(days, &year, &month, &day);
622 765 : m = month;
623 765 : dt = day;
624 : }
625 783 : if (argc >= 2) {
626 : Handle<Object> month = args.at(2);
627 1422 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, month,
628 : Object::ToNumber(isolate, month));
629 : m = month->Number();
630 711 : if (argc >= 3) {
631 : Handle<Object> date = args.at(3);
632 1152 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, date,
633 : Object::ToNumber(isolate, date));
634 : dt = date->Number();
635 : }
636 : }
637 783 : double const time_val = MakeDate(MakeDay(y, m, dt), time_within_day);
638 1566 : return *JSDate::SetValue(date, DateCache::TimeClip(time_val));
639 : }
640 :
641 : // ES6 section 20.3.4.30 Date.prototype.setUTCHours(hour, min, sec, ms)
642 16425 : BUILTIN(DatePrototypeSetUTCHours) {
643 : HandleScope scope(isolate);
644 3771 : CHECK_RECEIVER(JSDate, date, "Date.prototype.setUTCHours");
645 3123 : int const argc = args.length() - 1;
646 : Handle<Object> hour = args.atOrUndefined(isolate, 1);
647 6246 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, hour,
648 : Object::ToNumber(isolate, hour));
649 : double h = hour->Number();
650 : double time_val = date->value()->Number();
651 3123 : if (!std::isnan(time_val)) {
652 3069 : int64_t const time_ms = static_cast<int64_t>(time_val);
653 : int day = isolate->date_cache()->DaysFromTime(time_ms);
654 : int time_within_day = isolate->date_cache()->TimeInDay(time_ms, day);
655 3069 : double m = (time_within_day / (60 * 1000)) % 60;
656 3069 : double s = (time_within_day / 1000) % 60;
657 3069 : double milli = time_within_day % 1000;
658 3069 : if (argc >= 2) {
659 : Handle<Object> min = args.at(2);
660 6012 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, min,
661 : Object::ToNumber(isolate, min));
662 : m = min->Number();
663 3006 : if (argc >= 3) {
664 : Handle<Object> sec = args.at(3);
665 5742 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, sec,
666 : Object::ToNumber(isolate, sec));
667 : s = sec->Number();
668 2871 : if (argc >= 4) {
669 : Handle<Object> ms = args.at(4);
670 4608 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, ms,
671 : Object::ToNumber(isolate, ms));
672 : milli = ms->Number();
673 : }
674 : }
675 : }
676 3069 : time_val = MakeDate(day, MakeTime(h, m, s, milli));
677 : }
678 6246 : return *JSDate::SetValue(date, DateCache::TimeClip(time_val));
679 : }
680 :
681 : // ES6 section 20.3.4.31 Date.prototype.setUTCMilliseconds(ms)
682 1170 : BUILTIN(DatePrototypeSetUTCMilliseconds) {
683 : HandleScope scope(isolate);
684 720 : CHECK_RECEIVER(JSDate, date, "Date.prototype.setUTCMilliseconds");
685 : Handle<Object> ms = args.atOrUndefined(isolate, 1);
686 144 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, ms,
687 : Object::ToNumber(isolate, ms));
688 : double time_val = date->value()->Number();
689 72 : if (!std::isnan(time_val)) {
690 54 : int64_t const time_ms = static_cast<int64_t>(time_val);
691 : int day = isolate->date_cache()->DaysFromTime(time_ms);
692 : int time_within_day = isolate->date_cache()->TimeInDay(time_ms, day);
693 54 : int h = time_within_day / (60 * 60 * 1000);
694 54 : int m = (time_within_day / (60 * 1000)) % 60;
695 54 : int s = (time_within_day / 1000) % 60;
696 54 : time_val = MakeDate(day, MakeTime(h, m, s, ms->Number()));
697 : }
698 144 : return *JSDate::SetValue(date, DateCache::TimeClip(time_val));
699 : }
700 :
701 : // ES6 section 20.3.4.32 Date.prototype.setUTCMinutes ( min, sec, ms )
702 4725 : BUILTIN(DatePrototypeSetUTCMinutes) {
703 : HandleScope scope(isolate);
704 1431 : CHECK_RECEIVER(JSDate, date, "Date.prototype.setUTCMinutes");
705 783 : int const argc = args.length() - 1;
706 : Handle<Object> min = args.atOrUndefined(isolate, 1);
707 1566 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, min,
708 : Object::ToNumber(isolate, min));
709 : double time_val = date->value()->Number();
710 783 : if (!std::isnan(time_val)) {
711 756 : int64_t const time_ms = static_cast<int64_t>(time_val);
712 : int day = isolate->date_cache()->DaysFromTime(time_ms);
713 : int time_within_day = isolate->date_cache()->TimeInDay(time_ms, day);
714 756 : int h = time_within_day / (60 * 60 * 1000);
715 : double m = min->Number();
716 756 : double s = (time_within_day / 1000) % 60;
717 756 : double milli = time_within_day % 1000;
718 756 : if (argc >= 2) {
719 : Handle<Object> sec = args.at(2);
720 1422 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, sec,
721 : Object::ToNumber(isolate, sec));
722 : s = sec->Number();
723 711 : if (argc >= 3) {
724 : Handle<Object> ms = args.at(3);
725 1152 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, ms,
726 : Object::ToNumber(isolate, ms));
727 : milli = ms->Number();
728 : }
729 : }
730 756 : time_val = MakeDate(day, MakeTime(h, m, s, milli));
731 : }
732 1566 : return *JSDate::SetValue(date, DateCache::TimeClip(time_val));
733 : }
734 :
735 : // ES6 section 20.3.4.31 Date.prototype.setUTCMonth ( month, date )
736 1935 : BUILTIN(DatePrototypeSetUTCMonth) {
737 : HandleScope scope(isolate);
738 873 : CHECK_RECEIVER(JSDate, date, "Date.prototype.setUTCMonth");
739 : int const argc = args.length() - 1;
740 : Handle<Object> month = args.atOrUndefined(isolate, 1);
741 450 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, month,
742 : Object::ToNumber(isolate, month));
743 : double time_val = date->value()->Number();
744 225 : if (!std::isnan(time_val)) {
745 198 : int64_t const time_ms = static_cast<int64_t>(time_val);
746 : int days = isolate->date_cache()->DaysFromTime(time_ms);
747 : int time_within_day = isolate->date_cache()->TimeInDay(time_ms, days);
748 : int year, unused, day;
749 198 : isolate->date_cache()->YearMonthDayFromDays(days, &year, &unused, &day);
750 : double m = month->Number();
751 198 : double dt = day;
752 198 : if (argc >= 2) {
753 : Handle<Object> date = args.at(2);
754 288 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, date,
755 : Object::ToNumber(isolate, date));
756 : dt = date->Number();
757 : }
758 198 : time_val = MakeDate(MakeDay(year, m, dt), time_within_day);
759 : }
760 450 : return *JSDate::SetValue(date, DateCache::TimeClip(time_val));
761 : }
762 :
763 : // ES6 section 20.3.4.34 Date.prototype.setUTCSeconds ( sec, ms )
764 1935 : BUILTIN(DatePrototypeSetUTCSeconds) {
765 : HandleScope scope(isolate);
766 873 : CHECK_RECEIVER(JSDate, date, "Date.prototype.setUTCSeconds");
767 : int const argc = args.length() - 1;
768 : Handle<Object> sec = args.atOrUndefined(isolate, 1);
769 450 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, sec,
770 : Object::ToNumber(isolate, sec));
771 : double time_val = date->value()->Number();
772 225 : if (!std::isnan(time_val)) {
773 198 : int64_t const time_ms = static_cast<int64_t>(time_val);
774 : int day = isolate->date_cache()->DaysFromTime(time_ms);
775 : int time_within_day = isolate->date_cache()->TimeInDay(time_ms, day);
776 198 : int h = time_within_day / (60 * 60 * 1000);
777 198 : double m = (time_within_day / (60 * 1000)) % 60;
778 : double s = sec->Number();
779 198 : double milli = time_within_day % 1000;
780 198 : if (argc >= 2) {
781 : Handle<Object> ms = args.at(2);
782 288 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, ms,
783 : Object::ToNumber(isolate, ms));
784 : milli = ms->Number();
785 : }
786 198 : time_val = MakeDate(day, MakeTime(h, m, s, milli));
787 : }
788 450 : return *JSDate::SetValue(date, DateCache::TimeClip(time_val));
789 : }
790 :
791 : // ES6 section 20.3.4.35 Date.prototype.toDateString ( )
792 900 : BUILTIN(DatePrototypeToDateString) {
793 : HandleScope scope(isolate);
794 666 : CHECK_RECEIVER(JSDate, date, "Date.prototype.toDateString");
795 : DateBuffer buffer =
796 18 : ToDateString(date->value()->Number(), isolate->date_cache(), kDateOnly);
797 36 : RETURN_RESULT_OR_FAILURE(
798 : isolate, isolate->factory()->NewStringFromUtf8(VectorOf(buffer)));
799 : }
800 :
801 : // ES6 section 20.3.4.36 Date.prototype.toISOString ( )
802 1495 : BUILTIN(DatePrototypeToISOString) {
803 : HandleScope scope(isolate);
804 785 : CHECK_RECEIVER(JSDate, date, "Date.prototype.toISOString");
805 : double const time_val = date->value()->Number();
806 137 : if (std::isnan(time_val)) {
807 36 : THROW_NEW_ERROR_RETURN_FAILURE(
808 : isolate, NewRangeError(MessageTemplate::kInvalidTimeValue));
809 : }
810 119 : int64_t const time_ms = static_cast<int64_t>(time_val);
811 : int year, month, day, weekday, hour, min, sec, ms;
812 : isolate->date_cache()->BreakDownTime(time_ms, &year, &month, &day, &weekday,
813 119 : &hour, &min, &sec, &ms);
814 : char buffer[128];
815 119 : if (year >= 0 && year <= 9999) {
816 110 : SNPrintF(ArrayVector(buffer), "%04d-%02d-%02dT%02d:%02d:%02d.%03dZ", year,
817 220 : month + 1, day, hour, min, sec, ms);
818 9 : } else if (year < 0) {
819 0 : SNPrintF(ArrayVector(buffer), "-%06d-%02d-%02dT%02d:%02d:%02d.%03dZ", -year,
820 0 : month + 1, day, hour, min, sec, ms);
821 : } else {
822 9 : SNPrintF(ArrayVector(buffer), "+%06d-%02d-%02dT%02d:%02d:%02d.%03dZ", year,
823 18 : month + 1, day, hour, min, sec, ms);
824 : }
825 238 : return *isolate->factory()->NewStringFromAsciiChecked(buffer);
826 : }
827 :
828 : // ES6 section 20.3.4.41 Date.prototype.toString ( )
829 267885 : BUILTIN(DatePrototypeToString) {
830 : HandleScope scope(isolate);
831 54090 : CHECK_RECEIVER(JSDate, date, "Date.prototype.toString");
832 : DateBuffer buffer =
833 53406 : ToDateString(date->value()->Number(), isolate->date_cache());
834 106812 : RETURN_RESULT_OR_FAILURE(
835 : isolate, isolate->factory()->NewStringFromUtf8(VectorOf(buffer)));
836 : }
837 :
838 : // ES6 section 20.3.4.42 Date.prototype.toTimeString ( )
839 855 : BUILTIN(DatePrototypeToTimeString) {
840 : HandleScope scope(isolate);
841 657 : CHECK_RECEIVER(JSDate, date, "Date.prototype.toTimeString");
842 : DateBuffer buffer =
843 9 : ToDateString(date->value()->Number(), isolate->date_cache(), kTimeOnly);
844 18 : RETURN_RESULT_OR_FAILURE(
845 : isolate, isolate->factory()->NewStringFromUtf8(VectorOf(buffer)));
846 : }
847 :
848 : #ifdef V8_INTL_SUPPORT
849 : // ecma402 #sup-date.prototype.tolocaledatestring
850 1260 : BUILTIN(DatePrototypeToLocaleDateString) {
851 : HandleScope scope(isolate);
852 :
853 252 : isolate->CountUsage(v8::Isolate::UseCounterFeature::kDateToLocaleDateString);
854 :
855 738 : CHECK_RECEIVER(JSDate, date, "Date.prototype.toLocaleDateString");
856 :
857 189 : RETURN_RESULT_OR_FAILURE(
858 : isolate, JSDateTimeFormat::ToLocaleDateTime(
859 : isolate,
860 : date, // date
861 : args.atOrUndefined(isolate, 1), // locales
862 : args.atOrUndefined(isolate, 2), // options
863 : JSDateTimeFormat::RequiredOption::kDate, // required
864 : JSDateTimeFormat::DefaultsOption::kDate)); // defaults
865 : }
866 :
867 : // ecma402 #sup-date.prototype.tolocalestring
868 1125 : BUILTIN(DatePrototypeToLocaleString) {
869 : HandleScope scope(isolate);
870 :
871 225 : isolate->CountUsage(v8::Isolate::UseCounterFeature::kDateToLocaleString);
872 :
873 711 : CHECK_RECEIVER(JSDate, date, "Date.prototype.toLocaleString");
874 :
875 126 : RETURN_RESULT_OR_FAILURE(
876 : isolate, JSDateTimeFormat::ToLocaleDateTime(
877 : isolate,
878 : date, // date
879 : args.atOrUndefined(isolate, 1), // locales
880 : args.atOrUndefined(isolate, 2), // options
881 : JSDateTimeFormat::RequiredOption::kAny, // required
882 : JSDateTimeFormat::DefaultsOption::kAll)); // defaults
883 : }
884 :
885 : // ecma402 #sup-date.prototype.tolocaletimestring
886 1035 : BUILTIN(DatePrototypeToLocaleTimeString) {
887 : HandleScope scope(isolate);
888 :
889 207 : isolate->CountUsage(v8::Isolate::UseCounterFeature::kDateToLocaleTimeString);
890 :
891 693 : CHECK_RECEIVER(JSDate, date, "Date.prototype.toLocaleTimeString");
892 :
893 90 : RETURN_RESULT_OR_FAILURE(
894 : isolate, JSDateTimeFormat::ToLocaleDateTime(
895 : isolate,
896 : date, // date
897 : args.atOrUndefined(isolate, 1), // locales
898 : args.atOrUndefined(isolate, 2), // options
899 : JSDateTimeFormat::RequiredOption::kTime, // required
900 : JSDateTimeFormat::DefaultsOption::kTime)); // defaults
901 : }
902 : #endif // V8_INTL_SUPPORT
903 :
904 : // ES6 section 20.3.4.43 Date.prototype.toUTCString ( )
905 945 : BUILTIN(DatePrototypeToUTCString) {
906 : HandleScope scope(isolate);
907 675 : CHECK_RECEIVER(JSDate, date, "Date.prototype.toUTCString");
908 : double const time_val = date->value()->Number();
909 27 : if (std::isnan(time_val)) {
910 0 : return *isolate->factory()->NewStringFromAsciiChecked("Invalid Date");
911 : }
912 : char buffer[128];
913 27 : int64_t time_ms = static_cast<int64_t>(time_val);
914 : int year, month, day, weekday, hour, min, sec, ms;
915 : isolate->date_cache()->BreakDownTime(time_ms, &year, &month, &day, &weekday,
916 27 : &hour, &min, &sec, &ms);
917 54 : SNPrintF(ArrayVector(buffer), "%s, %02d %s %04d %02d:%02d:%02d GMT",
918 : kShortWeekDays[weekday], day, kShortMonths[month], year, hour, min,
919 81 : sec);
920 54 : return *isolate->factory()->NewStringFromAsciiChecked(buffer);
921 : }
922 :
923 : // ES6 section B.2.4.1 Date.prototype.getYear ( )
924 675 : BUILTIN(DatePrototypeGetYear) {
925 : HandleScope scope(isolate);
926 189 : CHECK_RECEIVER(JSDate, date, "Date.prototype.getYear");
927 : double time_val = date->value()->Number();
928 117 : if (std::isnan(time_val)) return date->value();
929 81 : int64_t time_ms = static_cast<int64_t>(time_val);
930 : int64_t local_time_ms = isolate->date_cache()->ToLocal(time_ms);
931 : int days = isolate->date_cache()->DaysFromTime(local_time_ms);
932 : int year, month, day;
933 81 : isolate->date_cache()->YearMonthDayFromDays(days, &year, &month, &day);
934 162 : return Smi::FromInt(year - 1900);
935 : }
936 :
937 : // ES6 section B.2.4.2 Date.prototype.setYear ( year )
938 720 : BUILTIN(DatePrototypeSetYear) {
939 : HandleScope scope(isolate);
940 171 : CHECK_RECEIVER(JSDate, date, "Date.prototype.setYear");
941 : Handle<Object> year = args.atOrUndefined(isolate, 1);
942 270 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, year,
943 : Object::ToNumber(isolate, year));
944 : double m = 0.0, dt = 1.0, y = year->Number();
945 135 : if (!std::isnan(y)) {
946 117 : double y_int = DoubleToInteger(y);
947 117 : if (0.0 <= y_int && y_int <= 99.0) {
948 27 : y = 1900.0 + y_int;
949 : }
950 : }
951 : int time_within_day = 0;
952 135 : if (!std::isnan(date->value()->Number())) {
953 117 : int64_t const time_ms = static_cast<int64_t>(date->value()->Number());
954 : int64_t local_time_ms = isolate->date_cache()->ToLocal(time_ms);
955 : int const days = isolate->date_cache()->DaysFromTime(local_time_ms);
956 : time_within_day = isolate->date_cache()->TimeInDay(local_time_ms, days);
957 : int year, month, day;
958 117 : isolate->date_cache()->YearMonthDayFromDays(days, &year, &month, &day);
959 117 : m = month;
960 117 : dt = day;
961 : }
962 135 : double time_val = MakeDate(MakeDay(y, m, dt), time_within_day);
963 135 : return SetLocalDateValue(isolate, date, time_val);
964 : }
965 :
966 : // ES6 section 20.3.4.37 Date.prototype.toJSON ( key )
967 1440 : BUILTIN(DatePrototypeToJson) {
968 : HandleScope scope(isolate);
969 288 : Handle<Object> receiver = args.atOrUndefined(isolate, 0);
970 : Handle<JSReceiver> receiver_obj;
971 738 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver_obj,
972 : Object::ToObject(isolate, receiver));
973 : Handle<Object> primitive;
974 261 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
975 : isolate, primitive,
976 : Object::ToPrimitive(receiver_obj, ToPrimitiveHint::kNumber));
977 198 : if (primitive->IsNumber() && !std::isfinite(primitive->Number())) {
978 18 : return ReadOnlyRoots(isolate).null_value();
979 : } else {
980 : Handle<String> name =
981 99 : isolate->factory()->NewStringFromAsciiChecked("toISOString");
982 : Handle<Object> function;
983 198 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
984 : isolate, function, Object::GetProperty(isolate, receiver_obj, name));
985 99 : if (!function->IsCallable()) {
986 36 : THROW_NEW_ERROR_RETURN_FAILURE(
987 : isolate, NewTypeError(MessageTemplate::kCalledNonCallable, name));
988 : }
989 162 : RETURN_RESULT_OR_FAILURE(
990 : isolate, Execution::Call(isolate, function, receiver_obj, 0, nullptr));
991 : }
992 : }
993 :
994 : } // namespace internal
995 120216 : } // namespace v8
|