5 #include "src/builtins/builtins-utils-inl.h" 6 #include "src/builtins/builtins.h" 7 #include "src/code-factory.h" 8 #include "src/code-stub-assembler.h" 9 #include "src/conversions.h" 10 #include "src/counters.h" 12 #include "src/dateparser-inl.h" 13 #include "src/objects-inl.h" 14 #ifdef V8_INTL_SUPPORT 15 #include "src/objects/intl-objects.h" 16 #include "src/objects/js-date-time-format.h" 28 const double kMinYear = -1000000.0;
29 const double kMaxYear = -kMinYear;
30 const double kMinMonth = -10000000.0;
31 const double kMaxMonth = -kMinMonth;
34 const double kMsPerDay = 86400000.0;
37 const double kMsPerSecond = 1000.0;
38 const double kMsPerMinute = 60000.0;
39 const double kMsPerHour = 3600000.0;
42 double MakeDate(
double day,
double time) {
43 if (std::isfinite(day) && std::isfinite(time)) {
44 return time + day * kMsPerDay;
46 return std::numeric_limits<double>::quiet_NaN();
50 double MakeDay(
double year,
double month,
double date) {
51 if ((kMinYear <= year && year <= kMaxYear) &&
52 (kMinMonth <= month && month <= kMaxMonth) && std::isfinite(date)) {
53 int y = FastD2I(year);
54 int m = FastD2I(month);
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 int day_from_year = 365 * (y + kYearDelta) + (y + kYearDelta) / 4 -
77 (y + kYearDelta) / 100 + (y + kYearDelta) / 400 -
79 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 day_from_year += kDayFromMonth[m];
84 static const int kDayFromMonth[] = {0, 31, 60, 91, 121, 152,
85 182, 213, 244, 274, 305, 335};
86 day_from_year += kDayFromMonth[m];
88 return static_cast<double>(day_from_year - 1) + DoubleToInteger(date);
90 return std::numeric_limits<double>::quiet_NaN();
94 double MakeTime(
double hour,
double min,
double sec,
double ms) {
95 if (std::isfinite(hour) && std::isfinite(min) && std::isfinite(sec) &&
97 double const h = DoubleToInteger(hour);
98 double const m = DoubleToInteger(min);
99 double const s = DoubleToInteger(sec);
100 double const milli = DoubleToInteger(ms);
101 return h * kMsPerHour + m * kMsPerMinute + s * kMsPerSecond + milli;
103 return std::numeric_limits<double>::quiet_NaN();
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"};
112 double ParseDateTimeString(Isolate* isolate, Handle<String> str) {
113 str = String::Flatten(isolate, str);
115 Handle<FixedArray> tmp =
116 isolate->factory()->NewFixedArray(DateParser::OUTPUT_SIZE);
117 DisallowHeapAllocation no_gc;
118 String::FlatContent str_content = str->GetFlatContent();
120 if (str_content.IsOneByte()) {
121 result = DateParser::Parse(isolate, str_content.ToOneByteVector(), *tmp);
123 result = DateParser::Parse(isolate, str_content.ToUC16Vector(), *tmp);
125 if (!result)
return std::numeric_limits<double>::quiet_NaN();
126 double const day = MakeDay(tmp->get(0)->Number(), tmp->get(1)->Number(),
127 tmp->get(2)->Number());
128 double const time = MakeTime(tmp->get(3)->Number(), tmp->get(4)->Number(),
129 tmp->get(5)->Number(), tmp->get(6)->Number());
130 double date = MakeDate(day, time);
131 if (tmp->get(7)->IsNull(isolate)) {
132 if (date >= -DateCache::kMaxTimeBeforeUTCInMs &&
133 date <= DateCache::kMaxTimeBeforeUTCInMs) {
134 date = isolate->date_cache()->ToUTC(static_cast<int64_t>(date));
136 return std::numeric_limits<double>::quiet_NaN();
139 date -= tmp->get(7)->Number() * 1000.0;
141 return DateCache::TimeClip(date);
144 enum ToDateStringMode { kDateOnly, kTimeOnly, kDateAndTime };
147 void ToDateString(
double time_val, Vector<char> str, DateCache* date_cache,
148 ToDateStringMode mode = kDateAndTime) {
149 if (std::isnan(time_val)) {
150 SNPrintF(str,
"Invalid Date");
154 int64_t local_time_ms = date_cache->ToLocal(time_ms);
155 int year, month, day, weekday, hour, min, sec, ms;
156 date_cache->BreakDownTime(local_time_ms, &year, &month, &day, &weekday, &hour,
158 int timezone_offset = -date_cache->TimezoneOffset(time_ms);
159 int timezone_hour = std::abs(timezone_offset) / 60;
160 int timezone_min = std::abs(timezone_offset) % 60;
161 const char* local_timezone = date_cache->LocalTimezone(time_ms);
164 SNPrintF(str,
"%s %s %02d %04d", kShortWeekDays[weekday],
165 kShortMonths[month], day, year);
169 SNPrintF(str,
"%02d:%02d:%02d GMT%c%02d%02d (%s)", hour, min, sec,
170 (timezone_offset < 0) ?
'-' :
'+', timezone_hour, timezone_min,
175 SNPrintF(str,
"%s %s %02d %04d %02d:%02d:%02d GMT%c%02d%02d (%s)",
176 kShortWeekDays[weekday], kShortMonths[month], day, year, hour,
177 min, sec, (timezone_offset < 0) ?
'-' :
'+', timezone_hour,
178 timezone_min, local_timezone);
184 Object* SetLocalDateValue(Isolate* isolate, Handle<JSDate> date,
186 if (time_val >= -DateCache::kMaxTimeBeforeUTCInMs &&
187 time_val <= DateCache::kMaxTimeBeforeUTCInMs) {
188 time_val = isolate->date_cache()->ToUTC(static_cast<int64_t>(time_val));
190 time_val = std::numeric_limits<double>::quiet_NaN();
192 return *JSDate::SetValue(date, DateCache::TimeClip(time_val));
198 BUILTIN(DateConstructor) {
199 HandleScope scope(isolate);
200 if (args.new_target()->IsUndefined(isolate)) {
201 double const time_val = JSDate::CurrentTimeValue(isolate);
203 ToDateString(time_val, ArrayVector(buffer), isolate->date_cache());
204 RETURN_RESULT_OR_FAILURE(
205 isolate, isolate->factory()->NewStringFromUtf8(CStrVector(buffer)));
208 int const argc = args.length() - 1;
209 Handle<JSFunction> target = args.target();
210 Handle<JSReceiver> new_target = Handle<JSReceiver>::cast(args.new_target());
213 time_val = JSDate::CurrentTimeValue(isolate);
214 }
else if (argc == 1) {
215 Handle<Object> value = args.at(1);
216 if (value->IsJSDate()) {
217 time_val = Handle<JSDate>::cast(value)->value()->Number();
219 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, value,
220 Object::ToPrimitive(value));
221 if (value->IsString()) {
222 time_val = ParseDateTimeString(isolate, Handle<String>::cast(value));
224 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, value,
225 Object::ToNumber(isolate, value));
226 time_val = value->Number();
230 Handle<Object> year_object;
231 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, year_object,
232 Object::ToNumber(isolate, args.at(1)));
233 Handle<Object> month_object;
234 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, month_object,
235 Object::ToNumber(isolate, args.at(2)));
236 double year = year_object->Number();
237 double month = month_object->Number();
238 double date = 1.0, hours = 0.0, minutes = 0.0, seconds = 0.0, ms = 0.0;
240 Handle<Object> date_object;
241 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, date_object,
242 Object::ToNumber(isolate, args.at(3)));
243 date = date_object->Number();
245 Handle<Object> hours_object;
246 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
247 isolate, hours_object, Object::ToNumber(isolate, args.at(4)));
248 hours = hours_object->Number();
250 Handle<Object> minutes_object;
251 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
252 isolate, minutes_object, Object::ToNumber(isolate, args.at(5)));
253 minutes = minutes_object->Number();
255 Handle<Object> seconds_object;
256 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
257 isolate, seconds_object, Object::ToNumber(isolate, args.at(6)));
258 seconds = seconds_object->Number();
260 Handle<Object> ms_object;
261 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
262 isolate, ms_object, Object::ToNumber(isolate, args.at(7)));
263 ms = ms_object->Number();
269 if (!std::isnan(year)) {
270 double const y = DoubleToInteger(year);
271 if (0.0 <= y && y <= 99) year = 1900 + y;
273 double const day = MakeDay(year, month, date);
274 double const time = MakeTime(hours, minutes, seconds, ms);
275 time_val = MakeDate(day, time);
276 if (time_val >= -DateCache::kMaxTimeBeforeUTCInMs &&
277 time_val <= DateCache::kMaxTimeBeforeUTCInMs) {
278 time_val = isolate->date_cache()->ToUTC(static_cast<int64_t>(time_val));
280 time_val = std::numeric_limits<double>::quiet_NaN();
283 RETURN_RESULT_OR_FAILURE(isolate, JSDate::New(target, new_target, time_val));
288 HandleScope scope(isolate);
289 return *isolate->factory()->NewNumber(JSDate::CurrentTimeValue(isolate));
294 HandleScope scope(isolate);
295 Handle<String> string;
296 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
298 Object::ToString(isolate, args.atOrUndefined(isolate, 1)));
299 return *isolate->factory()->NewNumber(ParseDateTimeString(isolate,
string));
304 HandleScope scope(isolate);
305 int const argc = args.length() - 1;
306 double year = std::numeric_limits<double>::quiet_NaN();
307 double month = 0.0, date = 1.0, hours = 0.0, minutes = 0.0, seconds = 0.0,
310 Handle<Object> year_object;
311 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, year_object,
312 Object::ToNumber(isolate, args.at(1)));
313 year = year_object->Number();
315 Handle<Object> month_object;
316 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, month_object,
317 Object::ToNumber(isolate, args.at(2)));
318 month = month_object->Number();
320 Handle<Object> date_object;
321 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
322 isolate, date_object, Object::ToNumber(isolate, args.at(3)));
323 date = date_object->Number();
325 Handle<Object> hours_object;
326 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
327 isolate, hours_object, Object::ToNumber(isolate, args.at(4)));
328 hours = hours_object->Number();
330 Handle<Object> minutes_object;
331 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
332 isolate, minutes_object, Object::ToNumber(isolate, args.at(5)));
333 minutes = minutes_object->Number();
335 Handle<Object> seconds_object;
336 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
337 isolate, seconds_object,
338 Object::ToNumber(isolate, args.at(6)));
339 seconds = seconds_object->Number();
341 Handle<Object> ms_object;
342 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
343 isolate, ms_object, Object::ToNumber(isolate, args.at(7)));
344 ms = ms_object->Number();
352 if (!std::isnan(year)) {
353 double const y = DoubleToInteger(year);
354 if (0.0 <= y && y <= 99) year = 1900 + y;
356 double const day = MakeDay(year, month, date);
357 double const time = MakeTime(hours, minutes, seconds, ms);
358 return *isolate->factory()->NewNumber(
359 DateCache::TimeClip(MakeDate(day, time)));
363 BUILTIN(DatePrototypeSetDate) {
364 HandleScope scope(isolate);
365 CHECK_RECEIVER(JSDate, date,
"Date.prototype.setDate");
366 Handle<Object> value = args.atOrUndefined(isolate, 1);
367 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, value,
368 Object::ToNumber(isolate, value));
369 double time_val = date->value()->Number();
370 if (!std::isnan(time_val)) {
372 int64_t local_time_ms = isolate->date_cache()->ToLocal(time_ms);
373 int const days = isolate->date_cache()->DaysFromTime(local_time_ms);
374 int time_within_day = isolate->date_cache()->TimeInDay(local_time_ms, days);
375 int year, month, day;
376 isolate->date_cache()->YearMonthDayFromDays(days, &year, &month, &day);
377 time_val = MakeDate(MakeDay(year, month, value->Number()), time_within_day);
379 return SetLocalDateValue(isolate, date, time_val);
383 BUILTIN(DatePrototypeSetFullYear) {
384 HandleScope scope(isolate);
385 CHECK_RECEIVER(JSDate, date,
"Date.prototype.setFullYear");
386 int const argc = args.length() - 1;
387 Handle<Object> year = args.atOrUndefined(isolate, 1);
388 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, year,
389 Object::ToNumber(isolate, year));
390 double y = year->Number(), m = 0.0, dt = 1.0;
391 int time_within_day = 0;
392 if (!std::isnan(date->value()->Number())) {
393 int64_t const time_ms =
static_cast<int64_t>(date->value()->Number());
394 int64_t local_time_ms = isolate->date_cache()->ToLocal(time_ms);
395 int const days = isolate->date_cache()->DaysFromTime(local_time_ms);
396 time_within_day = isolate->date_cache()->TimeInDay(local_time_ms, days);
397 int year, month, day;
398 isolate->date_cache()->YearMonthDayFromDays(days, &year, &month, &day);
403 Handle<Object> month = args.at(2);
404 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, month,
405 Object::ToNumber(isolate, month));
408 Handle<Object> date = args.at(3);
409 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, date,
410 Object::ToNumber(isolate, date));
414 double time_val = MakeDate(MakeDay(y, m, dt), time_within_day);
415 return SetLocalDateValue(isolate, date, time_val);
419 BUILTIN(DatePrototypeSetHours) {
420 HandleScope scope(isolate);
421 CHECK_RECEIVER(JSDate, date,
"Date.prototype.setHours");
422 int const argc = args.length() - 1;
423 Handle<Object> hour = args.atOrUndefined(isolate, 1);
424 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, hour,
425 Object::ToNumber(isolate, hour));
426 double h = hour->Number();
427 double time_val = date->value()->Number();
428 if (!std::isnan(time_val)) {
430 int64_t local_time_ms = isolate->date_cache()->ToLocal(time_ms);
431 int day = isolate->date_cache()->DaysFromTime(local_time_ms);
432 int time_within_day = isolate->date_cache()->TimeInDay(local_time_ms, day);
433 double m = (time_within_day / (60 * 1000)) % 60;
434 double s = (time_within_day / 1000) % 60;
435 double milli = time_within_day % 1000;
437 Handle<Object> min = args.at(2);
438 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, min,
439 Object::ToNumber(isolate, min));
442 Handle<Object> sec = args.at(3);
443 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, sec,
444 Object::ToNumber(isolate, sec));
447 Handle<Object> ms = args.at(4);
448 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, ms,
449 Object::ToNumber(isolate, ms));
450 milli = ms->Number();
454 time_val = MakeDate(day, MakeTime(h, m, s, milli));
456 return SetLocalDateValue(isolate, date, time_val);
460 BUILTIN(DatePrototypeSetMilliseconds) {
461 HandleScope scope(isolate);
462 CHECK_RECEIVER(JSDate, date,
"Date.prototype.setMilliseconds");
463 Handle<Object> ms = args.atOrUndefined(isolate, 1);
464 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, ms,
465 Object::ToNumber(isolate, ms));
466 double time_val = date->value()->Number();
467 if (!std::isnan(time_val)) {
469 int64_t local_time_ms = isolate->date_cache()->ToLocal(time_ms);
470 int day = isolate->date_cache()->DaysFromTime(local_time_ms);
471 int time_within_day = isolate->date_cache()->TimeInDay(local_time_ms, day);
472 int h = time_within_day / (60 * 60 * 1000);
473 int m = (time_within_day / (60 * 1000)) % 60;
474 int s = (time_within_day / 1000) % 60;
475 time_val = MakeDate(day, MakeTime(h, m, s, ms->Number()));
477 return SetLocalDateValue(isolate, date, time_val);
481 BUILTIN(DatePrototypeSetMinutes) {
482 HandleScope scope(isolate);
483 CHECK_RECEIVER(JSDate, date,
"Date.prototype.setMinutes");
484 int const argc = args.length() - 1;
485 Handle<Object> min = args.atOrUndefined(isolate, 1);
486 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, min,
487 Object::ToNumber(isolate, min));
488 double time_val = date->value()->Number();
489 if (!std::isnan(time_val)) {
491 int64_t local_time_ms = isolate->date_cache()->ToLocal(time_ms);
492 int day = isolate->date_cache()->DaysFromTime(local_time_ms);
493 int time_within_day = isolate->date_cache()->TimeInDay(local_time_ms, day);
494 int h = time_within_day / (60 * 60 * 1000);
495 double m = min->Number();
496 double s = (time_within_day / 1000) % 60;
497 double milli = time_within_day % 1000;
499 Handle<Object> sec = args.at(2);
500 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, sec,
501 Object::ToNumber(isolate, sec));
504 Handle<Object> ms = args.at(3);
505 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, ms,
506 Object::ToNumber(isolate, ms));
507 milli = ms->Number();
510 time_val = MakeDate(day, MakeTime(h, m, s, milli));
512 return SetLocalDateValue(isolate, date, time_val);
516 BUILTIN(DatePrototypeSetMonth) {
517 HandleScope scope(isolate);
518 CHECK_RECEIVER(JSDate, date,
"Date.prototype.setMonth");
519 int const argc = args.length() - 1;
520 Handle<Object> month = args.atOrUndefined(isolate, 1);
521 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, month,
522 Object::ToNumber(isolate, month));
523 double time_val = date->value()->Number();
524 if (!std::isnan(time_val)) {
526 int64_t local_time_ms = isolate->date_cache()->ToLocal(time_ms);
527 int days = isolate->date_cache()->DaysFromTime(local_time_ms);
528 int time_within_day = isolate->date_cache()->TimeInDay(local_time_ms, days);
529 int year, unused, day;
530 isolate->date_cache()->YearMonthDayFromDays(days, &year, &unused, &day);
531 double m = month->Number();
534 Handle<Object> date = args.at(2);
535 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, date,
536 Object::ToNumber(isolate, date));
539 time_val = MakeDate(MakeDay(year, m, dt), time_within_day);
541 return SetLocalDateValue(isolate, date, time_val);
545 BUILTIN(DatePrototypeSetSeconds) {
546 HandleScope scope(isolate);
547 CHECK_RECEIVER(JSDate, date,
"Date.prototype.setSeconds");
548 int const argc = args.length() - 1;
549 Handle<Object> sec = args.atOrUndefined(isolate, 1);
550 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, sec,
551 Object::ToNumber(isolate, sec));
552 double time_val = date->value()->Number();
553 if (!std::isnan(time_val)) {
555 int64_t local_time_ms = isolate->date_cache()->ToLocal(time_ms);
556 int day = isolate->date_cache()->DaysFromTime(local_time_ms);
557 int time_within_day = isolate->date_cache()->TimeInDay(local_time_ms, day);
558 int h = time_within_day / (60 * 60 * 1000);
559 double m = (time_within_day / (60 * 1000)) % 60;
560 double s = sec->Number();
561 double milli = time_within_day % 1000;
563 Handle<Object> ms = args.at(2);
564 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, ms,
565 Object::ToNumber(isolate, ms));
566 milli = ms->Number();
568 time_val = MakeDate(day, MakeTime(h, m, s, milli));
570 return SetLocalDateValue(isolate, date, time_val);
574 BUILTIN(DatePrototypeSetTime) {
575 HandleScope scope(isolate);
576 CHECK_RECEIVER(JSDate, date,
"Date.prototype.setTime");
577 Handle<Object> value = args.atOrUndefined(isolate, 1);
578 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, value,
579 Object::ToNumber(isolate, value));
580 return *JSDate::SetValue(date, DateCache::TimeClip(value->Number()));
584 BUILTIN(DatePrototypeSetUTCDate) {
585 HandleScope scope(isolate);
586 CHECK_RECEIVER(JSDate, date,
"Date.prototype.setUTCDate");
587 Handle<Object> value = args.atOrUndefined(isolate, 1);
588 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, value,
589 Object::ToNumber(isolate, value));
590 if (std::isnan(date->value()->Number()))
return date->value();
591 int64_t const time_ms =
static_cast<int64_t>(date->value()->Number());
592 int const days = isolate->date_cache()->DaysFromTime(time_ms);
593 int const time_within_day = isolate->date_cache()->TimeInDay(time_ms, days);
594 int year, month, day;
595 isolate->date_cache()->YearMonthDayFromDays(days, &year, &month, &day);
596 double const time_val =
597 MakeDate(MakeDay(year, month, value->Number()), time_within_day);
598 return *JSDate::SetValue(date, DateCache::TimeClip(time_val));
602 BUILTIN(DatePrototypeSetUTCFullYear) {
603 HandleScope scope(isolate);
604 CHECK_RECEIVER(JSDate, date,
"Date.prototype.setUTCFullYear");
605 int const argc = args.length() - 1;
606 Handle<Object> year = args.atOrUndefined(isolate, 1);
607 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, year,
608 Object::ToNumber(isolate, year));
609 double y = year->Number(), m = 0.0, dt = 1.0;
610 int time_within_day = 0;
611 if (!std::isnan(date->value()->Number())) {
612 int64_t const time_ms =
static_cast<int64_t>(date->value()->Number());
613 int const days = isolate->date_cache()->DaysFromTime(time_ms);
614 time_within_day = isolate->date_cache()->TimeInDay(time_ms, days);
615 int year, month, day;
616 isolate->date_cache()->YearMonthDayFromDays(days, &year, &month, &day);
621 Handle<Object> month = args.at(2);
622 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, month,
623 Object::ToNumber(isolate, month));
626 Handle<Object> date = args.at(3);
627 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, date,
628 Object::ToNumber(isolate, date));
632 double const time_val = MakeDate(MakeDay(y, m, dt), time_within_day);
633 return *JSDate::SetValue(date, DateCache::TimeClip(time_val));
637 BUILTIN(DatePrototypeSetUTCHours) {
638 HandleScope scope(isolate);
639 CHECK_RECEIVER(JSDate, date,
"Date.prototype.setUTCHours");
640 int const argc = args.length() - 1;
641 Handle<Object> hour = args.atOrUndefined(isolate, 1);
642 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, hour,
643 Object::ToNumber(isolate, hour));
644 double h = hour->Number();
645 double time_val = date->value()->Number();
646 if (!std::isnan(time_val)) {
648 int day = isolate->date_cache()->DaysFromTime(time_ms);
649 int time_within_day = isolate->date_cache()->TimeInDay(time_ms, day);
650 double m = (time_within_day / (60 * 1000)) % 60;
651 double s = (time_within_day / 1000) % 60;
652 double milli = time_within_day % 1000;
654 Handle<Object> min = args.at(2);
655 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, min,
656 Object::ToNumber(isolate, min));
659 Handle<Object> sec = args.at(3);
660 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, sec,
661 Object::ToNumber(isolate, sec));
664 Handle<Object> ms = args.at(4);
665 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, ms,
666 Object::ToNumber(isolate, ms));
667 milli = ms->Number();
671 time_val = MakeDate(day, MakeTime(h, m, s, milli));
673 return *JSDate::SetValue(date, DateCache::TimeClip(time_val));
677 BUILTIN(DatePrototypeSetUTCMilliseconds) {
678 HandleScope scope(isolate);
679 CHECK_RECEIVER(JSDate, date,
"Date.prototype.setUTCMilliseconds");
680 Handle<Object> ms = args.atOrUndefined(isolate, 1);
681 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, ms,
682 Object::ToNumber(isolate, ms));
683 double time_val = date->value()->Number();
684 if (!std::isnan(time_val)) {
686 int day = isolate->date_cache()->DaysFromTime(time_ms);
687 int time_within_day = isolate->date_cache()->TimeInDay(time_ms, day);
688 int h = time_within_day / (60 * 60 * 1000);
689 int m = (time_within_day / (60 * 1000)) % 60;
690 int s = (time_within_day / 1000) % 60;
691 time_val = MakeDate(day, MakeTime(h, m, s, ms->Number()));
693 return *JSDate::SetValue(date, DateCache::TimeClip(time_val));
697 BUILTIN(DatePrototypeSetUTCMinutes) {
698 HandleScope scope(isolate);
699 CHECK_RECEIVER(JSDate, date,
"Date.prototype.setUTCMinutes");
700 int const argc = args.length() - 1;
701 Handle<Object> min = args.atOrUndefined(isolate, 1);
702 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, min,
703 Object::ToNumber(isolate, min));
704 double time_val = date->value()->Number();
705 if (!std::isnan(time_val)) {
707 int day = isolate->date_cache()->DaysFromTime(time_ms);
708 int time_within_day = isolate->date_cache()->TimeInDay(time_ms, day);
709 int h = time_within_day / (60 * 60 * 1000);
710 double m = min->Number();
711 double s = (time_within_day / 1000) % 60;
712 double milli = time_within_day % 1000;
714 Handle<Object> sec = args.at(2);
715 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, sec,
716 Object::ToNumber(isolate, sec));
719 Handle<Object> ms = args.at(3);
720 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, ms,
721 Object::ToNumber(isolate, ms));
722 milli = ms->Number();
725 time_val = MakeDate(day, MakeTime(h, m, s, milli));
727 return *JSDate::SetValue(date, DateCache::TimeClip(time_val));
731 BUILTIN(DatePrototypeSetUTCMonth) {
732 HandleScope scope(isolate);
733 CHECK_RECEIVER(JSDate, date,
"Date.prototype.setUTCMonth");
734 int const argc = args.length() - 1;
735 Handle<Object> month = args.atOrUndefined(isolate, 1);
736 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, month,
737 Object::ToNumber(isolate, month));
738 double time_val = date->value()->Number();
739 if (!std::isnan(time_val)) {
741 int days = isolate->date_cache()->DaysFromTime(time_ms);
742 int time_within_day = isolate->date_cache()->TimeInDay(time_ms, days);
743 int year, unused, day;
744 isolate->date_cache()->YearMonthDayFromDays(days, &year, &unused, &day);
745 double m = month->Number();
748 Handle<Object> date = args.at(2);
749 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, date,
750 Object::ToNumber(isolate, date));
753 time_val = MakeDate(MakeDay(year, m, dt), time_within_day);
755 return *JSDate::SetValue(date, DateCache::TimeClip(time_val));
759 BUILTIN(DatePrototypeSetUTCSeconds) {
760 HandleScope scope(isolate);
761 CHECK_RECEIVER(JSDate, date,
"Date.prototype.setUTCSeconds");
762 int const argc = args.length() - 1;
763 Handle<Object> sec = args.atOrUndefined(isolate, 1);
764 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, sec,
765 Object::ToNumber(isolate, sec));
766 double time_val = date->value()->Number();
767 if (!std::isnan(time_val)) {
769 int day = isolate->date_cache()->DaysFromTime(time_ms);
770 int time_within_day = isolate->date_cache()->TimeInDay(time_ms, day);
771 int h = time_within_day / (60 * 60 * 1000);
772 double m = (time_within_day / (60 * 1000)) % 60;
773 double s = sec->Number();
774 double milli = time_within_day % 1000;
776 Handle<Object> ms = args.at(2);
777 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, ms,
778 Object::ToNumber(isolate, ms));
779 milli = ms->Number();
781 time_val = MakeDate(day, MakeTime(h, m, s, milli));
783 return *JSDate::SetValue(date, DateCache::TimeClip(time_val));
787 BUILTIN(DatePrototypeToDateString) {
788 HandleScope scope(isolate);
789 CHECK_RECEIVER(JSDate, date,
"Date.prototype.toDateString");
791 ToDateString(date->value()->Number(), ArrayVector(buffer),
792 isolate->date_cache(), kDateOnly);
793 RETURN_RESULT_OR_FAILURE(
794 isolate, isolate->factory()->NewStringFromUtf8(CStrVector(buffer)));
798 BUILTIN(DatePrototypeToISOString) {
799 HandleScope scope(isolate);
800 CHECK_RECEIVER(JSDate, date,
"Date.prototype.toISOString");
801 double const time_val = date->value()->Number();
802 if (std::isnan(time_val)) {
803 THROW_NEW_ERROR_RETURN_FAILURE(
804 isolate, NewRangeError(MessageTemplate::kInvalidTimeValue));
807 int year, month, day, weekday, hour, min, sec, ms;
808 isolate->date_cache()->BreakDownTime(time_ms, &year, &month, &day, &weekday,
809 &hour, &min, &sec, &ms);
811 if (year >= 0 && year <= 9999) {
812 SNPrintF(ArrayVector(buffer),
"%04d-%02d-%02dT%02d:%02d:%02d.%03dZ", year,
813 month + 1, day, hour, min, sec, ms);
814 }
else if (year < 0) {
815 SNPrintF(ArrayVector(buffer),
"-%06d-%02d-%02dT%02d:%02d:%02d.%03dZ", -year,
816 month + 1, day, hour, min, sec, ms);
818 SNPrintF(ArrayVector(buffer),
"+%06d-%02d-%02dT%02d:%02d:%02d.%03dZ", year,
819 month + 1, day, hour, min, sec, ms);
821 return *isolate->factory()->NewStringFromAsciiChecked(buffer);
825 BUILTIN(DatePrototypeToString) {
826 HandleScope scope(isolate);
827 CHECK_RECEIVER(JSDate, date,
"Date.prototype.toString");
829 ToDateString(date->value()->Number(), ArrayVector(buffer),
830 isolate->date_cache());
831 RETURN_RESULT_OR_FAILURE(
832 isolate, isolate->factory()->NewStringFromUtf8(CStrVector(buffer)));
836 BUILTIN(DatePrototypeToTimeString) {
837 HandleScope scope(isolate);
838 CHECK_RECEIVER(JSDate, date,
"Date.prototype.toTimeString");
840 ToDateString(date->value()->Number(), ArrayVector(buffer),
841 isolate->date_cache(), kTimeOnly);
842 RETURN_RESULT_OR_FAILURE(
843 isolate, isolate->factory()->NewStringFromUtf8(CStrVector(buffer)));
846 #ifdef V8_INTL_SUPPORT 848 BUILTIN(DatePrototypeToLocaleDateString) {
849 HandleScope scope(isolate);
851 isolate->CountUsage(v8::Isolate::UseCounterFeature::kDateToLocaleDateString);
853 CHECK_RECEIVER(JSDate, date,
"Date.prototype.toLocaleDateString");
855 RETURN_RESULT_OR_FAILURE(
856 isolate, JSDateTimeFormat::ToLocaleDateTime(
859 args.atOrUndefined(isolate, 1),
860 args.atOrUndefined(isolate, 2),
861 JSDateTimeFormat::RequiredOption::kDate,
862 JSDateTimeFormat::DefaultsOption::kDate));
866 BUILTIN(DatePrototypeToLocaleString) {
867 HandleScope scope(isolate);
869 isolate->CountUsage(v8::Isolate::UseCounterFeature::kDateToLocaleString);
871 CHECK_RECEIVER(JSDate, date,
"Date.prototype.toLocaleString");
873 RETURN_RESULT_OR_FAILURE(
874 isolate, JSDateTimeFormat::ToLocaleDateTime(
877 args.atOrUndefined(isolate, 1),
878 args.atOrUndefined(isolate, 2),
879 JSDateTimeFormat::RequiredOption::kAny,
880 JSDateTimeFormat::DefaultsOption::kAll));
884 BUILTIN(DatePrototypeToLocaleTimeString) {
885 HandleScope scope(isolate);
887 isolate->CountUsage(v8::Isolate::UseCounterFeature::kDateToLocaleTimeString);
889 CHECK_RECEIVER(JSDate, date,
"Date.prototype.toLocaleTimeString");
891 RETURN_RESULT_OR_FAILURE(
892 isolate, JSDateTimeFormat::ToLocaleDateTime(
895 args.atOrUndefined(isolate, 1),
896 args.atOrUndefined(isolate, 2),
897 JSDateTimeFormat::RequiredOption::kTime,
898 JSDateTimeFormat::DefaultsOption::kTime));
900 #endif // V8_INTL_SUPPORT 903 BUILTIN(DatePrototypeToUTCString) {
904 HandleScope scope(isolate);
905 CHECK_RECEIVER(JSDate, date,
"Date.prototype.toUTCString");
906 double const time_val = date->value()->Number();
907 if (std::isnan(time_val)) {
908 return *isolate->factory()->NewStringFromAsciiChecked(
"Invalid Date");
912 int year, month, day, weekday, hour, min, sec, ms;
913 isolate->date_cache()->BreakDownTime(time_ms, &year, &month, &day, &weekday,
914 &hour, &min, &sec, &ms);
915 SNPrintF(ArrayVector(buffer),
"%s, %02d %s %04d %02d:%02d:%02d GMT",
916 kShortWeekDays[weekday], day, kShortMonths[month], year, hour, min,
918 return *isolate->factory()->NewStringFromAsciiChecked(buffer);
922 BUILTIN(DatePrototypeGetYear) {
923 HandleScope scope(isolate);
924 CHECK_RECEIVER(JSDate, date,
"Date.prototype.getYear");
925 double time_val = date->value()->Number();
926 if (std::isnan(time_val))
return date->value();
928 int64_t local_time_ms = isolate->date_cache()->ToLocal(time_ms);
929 int days = isolate->date_cache()->DaysFromTime(local_time_ms);
930 int year, month, day;
931 isolate->date_cache()->YearMonthDayFromDays(days, &year, &month, &day);
932 return Smi::FromInt(year - 1900);
936 BUILTIN(DatePrototypeSetYear) {
937 HandleScope scope(isolate);
938 CHECK_RECEIVER(JSDate, date,
"Date.prototype.setYear");
939 Handle<Object> year = args.atOrUndefined(isolate, 1);
940 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, year,
941 Object::ToNumber(isolate, year));
942 double m = 0.0, dt = 1.0, y = year->Number();
943 if (0.0 <= y && y <= 99.0) {
944 y = 1900.0 + DoubleToInteger(y);
946 int time_within_day = 0;
947 if (!std::isnan(date->value()->Number())) {
948 int64_t const time_ms =
static_cast<int64_t>(date->value()->Number());
949 int64_t local_time_ms = isolate->date_cache()->ToLocal(time_ms);
950 int const days = isolate->date_cache()->DaysFromTime(local_time_ms);
951 time_within_day = isolate->date_cache()->TimeInDay(local_time_ms, days);
952 int year, month, day;
953 isolate->date_cache()->YearMonthDayFromDays(days, &year, &month, &day);
957 double time_val = MakeDate(MakeDay(y, m, dt), time_within_day);
958 return SetLocalDateValue(isolate, date, time_val);
962 BUILTIN(DatePrototypeToJson) {
963 HandleScope scope(isolate);
964 Handle<Object> receiver = args.atOrUndefined(isolate, 0);
965 Handle<JSReceiver> receiver_obj;
966 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver_obj,
967 Object::ToObject(isolate, receiver));
968 Handle<Object> primitive;
969 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
971 Object::ToPrimitive(receiver_obj, ToPrimitiveHint::kNumber));
972 if (primitive->IsNumber() && !std::isfinite(primitive->Number())) {
973 return ReadOnlyRoots(isolate).null_value();
975 Handle<String> name =
976 isolate->factory()->NewStringFromAsciiChecked(
"toISOString");
977 Handle<Object>
function;
978 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
979 isolate,
function, Object::GetProperty(isolate, receiver_obj, name));
980 if (!function->IsCallable()) {
981 THROW_NEW_ERROR_RETURN_FAILURE(
982 isolate, NewTypeError(MessageTemplate::kCalledNonCallable, name));
984 RETURN_RESULT_OR_FAILURE(
985 isolate, Execution::Call(isolate,
function, receiver_obj, 0,
nullptr));