Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qv4dateobject.cpp
Go to the documentation of this file.
1// Copyright (C) 2021 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qv4dateobject_p.h"
5#include "qv4runtime_p.h"
6#include "qv4symbol_p.h"
7
8#include <QtCore/QDebug>
9#include <QtCore/QDateTime>
10#include <QtCore/private/qlocaltime_p.h>
11#include <QtCore/QStringList>
12#include <QtCore/QTimeZone>
13
14#include <wtf/MathExtras.h>
15
16using namespace QV4;
17
18static const double HoursPerDay = 24.0;
19static const double MinutesPerHour = 60.0;
20static const double SecondsPerMinute = 60.0;
21static const double msPerSecond = 1000.0;
22static const double msPerMinute = 60000.0;
23static const double msPerHour = 3600000.0;
24static const double msPerDay = 86400000.0;
25
26static inline double TimeWithinDay(double t)
27{
28 double r = ::fmod(t, msPerDay);
29 return (r >= 0) ? r : r + msPerDay;
30}
31
32static inline int HourFromTime(double t)
33{
34 int r = int(::fmod(::floor(t / msPerHour), HoursPerDay));
35 return (r >= 0) ? r : r + int(HoursPerDay);
36}
37
38static inline int MinFromTime(double t)
39{
40 int r = int(::fmod(::floor(t / msPerMinute), MinutesPerHour));
41 return (r >= 0) ? r : r + int(MinutesPerHour);
42}
43
44static inline int SecFromTime(double t)
45{
46 int r = int(::fmod(::floor(t / msPerSecond), SecondsPerMinute));
47 return (r >= 0) ? r : r + int(SecondsPerMinute);
48}
49
50static inline int msFromTime(double t)
51{
52 int r = int(::fmod(t, msPerSecond));
53 return (r >= 0) ? r : r + int(msPerSecond);
54}
55
56static inline double Day(double t)
57{
58 return ::floor(t / msPerDay);
59}
60
61static inline double DaysInYear(double y)
62{
63 if (::fmod(y, 4))
64 return 365;
65
66 else if (::fmod(y, 100))
67 return 366;
68
69 else if (::fmod(y, 400))
70 return 365;
71
72 return 366;
73}
74
75static inline double DayFromYear(double y)
76{
77 return 365 * (y - 1970)
78 + ::floor((y - 1969) / 4)
79 - ::floor((y - 1901) / 100)
80 + ::floor((y - 1601) / 400);
81}
82
83static inline double TimeFromYear(double y)
84{
85 return msPerDay * DayFromYear(y);
86}
87
88static inline double YearFromTime(double t)
89{
90 int y = 1970;
91 y += (int) ::floor(t / (msPerDay * 365.2425));
92
93 double t2 = TimeFromYear(y);
94 return (t2 > t) ? y - 1 : ((t2 + msPerDay * DaysInYear(y)) <= t) ? y + 1 : y;
95}
96
97static inline bool InLeapYear(double t)
98{
99 double x = DaysInYear(YearFromTime(t));
100 if (x == 365)
101 return 0;
102
103 Q_ASSERT(x == 366);
104 return 1;
105}
106
107static inline double DayWithinYear(double t)
108{
109 return Day(t) - DayFromYear(YearFromTime(t));
110}
111
112static inline double MonthFromTime(double t)
113{
114 double d = DayWithinYear(t);
115 double l = InLeapYear(t);
116
117 if (d < 31.0)
118 return 0;
119
120 else if (d < 59.0 + l)
121 return 1;
122
123 else if (d < 90.0 + l)
124 return 2;
125
126 else if (d < 120.0 + l)
127 return 3;
128
129 else if (d < 151.0 + l)
130 return 4;
131
132 else if (d < 181.0 + l)
133 return 5;
134
135 else if (d < 212.0 + l)
136 return 6;
137
138 else if (d < 243.0 + l)
139 return 7;
140
141 else if (d < 273.0 + l)
142 return 8;
143
144 else if (d < 304.0 + l)
145 return 9;
146
147 else if (d < 334.0 + l)
148 return 10;
149
150 else if (d < 365.0 + l)
151 return 11;
152
153 return qt_qnan(); // ### assert?
154}
155
156static inline double DateFromTime(double t)
157{
159 double d = DayWithinYear(t);
160 double l = InLeapYear(t);
161
162 switch (m) {
163 case 0: return d + 1.0;
164 case 1: return d - 30.0;
165 case 2: return d - 58.0 - l;
166 case 3: return d - 89.0 - l;
167 case 4: return d - 119.0 - l;
168 case 5: return d - 150.0 - l;
169 case 6: return d - 180.0 - l;
170 case 7: return d - 211.0 - l;
171 case 8: return d - 242.0 - l;
172 case 9: return d - 272.0 - l;
173 case 10: return d - 303.0 - l;
174 case 11: return d - 333.0 - l;
175 }
176
177 return qt_qnan(); // ### assert
178}
179
180static inline double WeekDay(double t)
181{
182 double r = ::fmod (Day(t) + 4.0, 7.0);
183 return (r >= 0) ? r : r + 7.0;
184}
185
186
187static inline double MakeTime(double hour, double min, double sec, double ms)
188{
189 if (!qIsFinite(hour) || !qIsFinite(min) || !qIsFinite(sec) || !qIsFinite(ms))
190 return qQNaN();
191 hour = QV4::Value::toInteger(hour);
192 min = QV4::Value::toInteger(min);
193 sec = QV4::Value::toInteger(sec);
194 ms = QV4::Value::toInteger(ms);
195 return ((hour * MinutesPerHour + min) * SecondsPerMinute + sec) * msPerSecond + ms;
196}
197
198static inline double DayFromMonth(double month, double leap)
199{
200 switch ((int) month) {
201 case 0: return 0;
202 case 1: return 31.0;
203 case 2: return 59.0 + leap;
204 case 3: return 90.0 + leap;
205 case 4: return 120.0 + leap;
206 case 5: return 151.0 + leap;
207 case 6: return 181.0 + leap;
208 case 7: return 212.0 + leap;
209 case 8: return 243.0 + leap;
210 case 9: return 273.0 + leap;
211 case 10: return 304.0 + leap;
212 case 11: return 334.0 + leap;
213 }
214
215 return qt_qnan(); // ### assert?
216}
217
218static double MakeDay(double year, double month, double day)
219{
220 if (!qIsFinite(year) || !qIsFinite(month) || !qIsFinite(day))
221 return qQNaN();
222 year = QV4::Value::toInteger(year);
223 month = QV4::Value::toInteger(month);
224 day = QV4::Value::toInteger(day);
225
226 year += ::floor(month / 12.0);
227
228 month = ::fmod(month, 12.0);
229 if (month < 0)
230 month += 12.0;
231
232 /* Quoting the spec:
233
234 Find a value t such that YearFromTime(t) is ym and MonthFromTime(t) is mn
235 and DateFromTime(t) is 1; but if this is not possible (because some
236 argument is out of range), return NaN.
237 */
238 double first = DayFromYear(year);
239 /* Beware floating-point glitches: don't test the first millisecond of a
240 * year, month or day when we could test a moment firmly in the interior of
241 * the interval. A rounding glitch might give the first millisecond to the
242 * preceding interval.
243 */
244 bool leap = InLeapYear((first + 60) * msPerDay);
245
246 first += DayFromMonth(month, leap);
247 const double t = first * msPerDay + msPerDay / 2; // Noon on the first of the month
248 Q_ASSERT(Day(t) == first);
249 if (YearFromTime(t) != year || MonthFromTime(t) != month || DateFromTime(t) != 1) {
250 qWarning("Apparently out-of-range date %.0f-%02.0f-%02.0f", year, month, day);
251 return qt_qnan();
252 }
253 return first + day - 1;
254}
255
256static inline double MakeDate(double day, double time)
257{
258 return day * msPerDay + time;
259}
260
261/*
262 ECMAScript specifies use of a fixed (current, standard) time-zone offset,
263 LocalTZA; and LocalTZA + DaylightSavingTA(t) is taken to be (see LocalTime and
264 UTC, following) local time's offset from UTC at time t. For simple zones,
265 DaylightSavingTA(t) is thus the DST offset applicable at date/time t; however,
266 if a zone has changed its standard offset, the only way to make LocalTime and
267 UTC (if implemented in accord with the spec) perform correct transformations
268 is to have DaylightSavingTA(t) correct for the zone's standard offset change
269 as well as its actual DST offset.
270
271 This means we have to treat any historical changes in the zone's standard
272 offset as DST perturbations, regardless of historical reality. (This shall
273 mean a whole day of DST offset for some zones, that have crossed the
274 international date line. This shall confuse client code.) The bug report
275 against the ECMAScript spec is https://github.com/tc39/ecma262/issues/725
276 and they've now changed the spec so that the following conforms to it ;^>
277*/
278static inline double DaylightSavingTA(double t, double localTZA) // t is a UTC time
279{
280 return QLocalTime::getUtcOffset(qint64(t)) * 1e3 - localTZA;
281}
282
283static inline double LocalTime(double t, double localTZA)
284{
285 // Flawed, yet verbatim from the spec:
286 return t + localTZA + DaylightSavingTA(t, localTZA);
287}
288
289// The spec does note [*] that UTC and LocalTime are not quite mutually inverse.
290// [*] http://www.ecma-international.org/ecma-262/7.0/index.html#sec-utc-t
291
292static inline double UTC(double t, double localTZA)
293{
294 // Flawed, yet verbatim from the spec:
295 return t - localTZA - DaylightSavingTA(t - localTZA, localTZA);
296}
297
298static inline double currentTime()
299{
300 return QDateTime::currentDateTimeUtc().toMSecsSinceEpoch();
301}
302
303static inline double TimeClip(double t)
304{
305 if (!qt_is_finite(t) || fabs(t) > Date::MaxDateVal)
306 return qt_qnan();
307
308 // +0 looks weird, but is correct. See ES6 20.3.1.15. We must not return -0.
309 return QV4::Value::toInteger(t) + 0;
310}
311
312static inline double ParseString(const QString &s, double localTZA)
313{
314 /*
315 First, try the format defined in ECMA 262's "Date Time String Format";
316 only if that fails, fall back to QDateTime for parsing
317
318 The defined string format is yyyy-MM-ddTHH:mm:ss.zzzt; the time (T and all
319 after it) may be omitted. In each part, the second and later components
320 are optional. There's an extended syntax for negative and large positive
321 years: ±yyyyyy; the leading sign, even when +, isn't optional. If month
322 (MM) or day (dd) is omitted, it is 01; if minute (mm) or second (ss) is
323 omitted, it's 00; if milliseconds (zzz) are omitted, they're 000.
324
325 When the time zone offset (t) is absent, date-only forms are interpreted as
326 indicating a UTC time and date-time forms are interpreted in local time.
327 */
328
329 enum Format {
330 Year,
331 Month,
332 Day,
333 Hour,
334 Minute,
335 Second,
336 MilliSecond,
337 TimezoneHour,
338 TimezoneMinute,
339 Done
340 };
341
342 const QChar *ch = s.constData();
343 const QChar *end = ch + s.size();
344
345 uint format = Year;
346 int current = 0;
347 int currentSize = 0;
348 bool extendedYear = false;
349
350 int yearSign = 1;
351 int year = 0;
352 int month = 0;
353 int day = 1;
354 int hour = 0;
355 int minute = 0;
356 int second = 0;
357 int msec = 0;
358 int offsetSign = 1;
359 int offset = 0;
360 bool seenT = false;
361 bool seenZ = false; // Have seen zone, i.e. +HH:mm or literal Z.
362
363 bool error = false;
364 if (*ch == u'+' || *ch == u'-') {
365 extendedYear = true;
366 if (*ch == u'-')
367 yearSign = -1;
368 ++ch;
369 }
370 for (; ch <= end && !error && format != Done; ++ch) {
371 if (*ch >= u'0' && *ch <= u'9') {
372 current *= 10;
373 current += ch->unicode() - u'0';
374 ++currentSize;
375 } else { // other char, delimits field
376 switch (format) {
377 case Year:
378 year = current;
379 if (extendedYear)
380 error = (currentSize != 6);
381 else
382 error = (currentSize != 4);
383 break;
384 case Month:
385 month = current - 1;
386 error = (currentSize != 2) || month > 11;
387 break;
388 case Day:
389 day = current;
390 error = (currentSize != 2) || day > 31;
391 break;
392 case Hour:
393 hour = current;
394 error = (currentSize != 2) || hour > 24;
395 break;
396 case Minute:
397 minute = current;
398 error = (currentSize != 2) || minute >= 60;
399 break;
400 case Second:
401 second = current;
402 error = (currentSize != 2) || second > 60;
403 break;
404 case MilliSecond:
405 msec = current;
406 error = (currentSize != 3);
407 break;
408 case TimezoneHour:
409 Q_ASSERT(offset == 0 && !seenZ);
410 offset = current * 60;
411 error = (currentSize != 2) || current > 23;
412 seenZ = true;
413 break;
414 case TimezoneMinute:
415 offset += current;
416 error = (currentSize != 2) || current >= 60;
417 break;
418 }
419 if (*ch == u'T') {
420 if (format >= Hour)
421 error = true;
422 format = Hour;
423 seenT = true;
424 } else if (*ch == u'-') {
425 if (format < Day)
426 ++format;
427 else if (format < Minute)
428 error = true;
429 else if (format >= TimezoneHour)
430 error = true;
431 else {
432 Q_ASSERT(offset == 0 && !seenZ);
433 offsetSign = -1;
434 format = TimezoneHour;
435 }
436 } else if (*ch == u':') {
437 if (format != Hour && format != Minute && format != TimezoneHour)
438 error = true;
439 ++format;
440 } else if (*ch == u'.') {
441 if (format != Second)
442 error = true;
443 ++format;
444 } else if (*ch == u'+') {
445 if (seenZ || format < Minute || format >= TimezoneHour)
446 error = true;
447 format = TimezoneHour;
448 } else if (*ch == u'Z') {
449 if (seenZ || format < Minute || format >= TimezoneHour)
450 error = true;
451 else
452 Q_ASSERT(offset == 0);
453 format = Done;
454 seenZ = true;
455 } else if (ch->unicode() == 0) {
456 format = Done;
457 }
458 current = 0;
459 currentSize = 0;
460 }
461 }
462
463 if (!error) {
464 double t = MakeDate(MakeDay(year * yearSign, month, day), MakeTime(hour, minute, second, msec));
465 if (seenZ)
466 t -= offset * offsetSign * 60 * 1000;
467 else if (seenT) // No zone specified, treat date-time as local time
468 t = UTC(t, localTZA);
469 // else: treat plain date as already in UTC
470 return TimeClip(t);
471 }
472
473 QDateTime dt = QDateTime::fromString(s, Qt::TextDate);
474 if (!dt.isValid())
475 dt = QDateTime::fromString(s, Qt::ISODate);
476 if (!dt.isValid())
477 dt = QDateTime::fromString(s, Qt::RFC2822Date);
478 if (!dt.isValid()) {
479 const QString formats[] = {
480 QStringLiteral("M/d/yyyy"),
481 QStringLiteral("M/d/yyyy hh:mm"),
482 QStringLiteral("M/d/yyyy hh:mm A"),
483
484 QStringLiteral("M/d/yyyy, hh:mm"),
485 QStringLiteral("M/d/yyyy, hh:mm A"),
486
487 QStringLiteral("MMM d yyyy"),
488 QStringLiteral("MMM d yyyy hh:mm"),
489 QStringLiteral("MMM d yyyy hh:mm:ss"),
490 QStringLiteral("MMM d yyyy, hh:mm"),
491 QStringLiteral("MMM d yyyy, hh:mm:ss"),
492
493 QStringLiteral("MMMM d yyyy"),
494 QStringLiteral("MMMM d yyyy hh:mm"),
495 QStringLiteral("MMMM d yyyy hh:mm:ss"),
496 QStringLiteral("MMMM d yyyy, hh:mm"),
497 QStringLiteral("MMMM d yyyy, hh:mm:ss"),
498
499 QStringLiteral("MMM d, yyyy"),
500 QStringLiteral("MMM d, yyyy hh:mm"),
501 QStringLiteral("MMM d, yyyy hh:mm:ss"),
502
503 QStringLiteral("MMMM d, yyyy"),
504 QStringLiteral("MMMM d, yyyy hh:mm"),
505 QStringLiteral("MMMM d, yyyy hh:mm:ss"),
506
507 QStringLiteral("d MMM yyyy"),
508 QStringLiteral("d MMM yyyy hh:mm"),
509 QStringLiteral("d MMM yyyy hh:mm:ss"),
510 QStringLiteral("d MMM yyyy, hh:mm"),
511 QStringLiteral("d MMM yyyy, hh:mm:ss"),
512
513 QStringLiteral("d MMMM yyyy"),
514 QStringLiteral("d MMMM yyyy hh:mm"),
515 QStringLiteral("d MMMM yyyy hh:mm:ss"),
516 QStringLiteral("d MMMM yyyy, hh:mm"),
517 QStringLiteral("d MMMM yyyy, hh:mm:ss"),
518
519 QStringLiteral("d MMM, yyyy"),
520 QStringLiteral("d MMM, yyyy hh:mm"),
521 QStringLiteral("d MMM, yyyy hh:mm:ss"),
522
523 QStringLiteral("d MMMM, yyyy"),
524 QStringLiteral("d MMMM, yyyy hh:mm"),
525 QStringLiteral("d MMMM, yyyy hh:mm:ss"),
526
527 // ISO 8601 and RFC 2822 with a GMT as prefix on its offset, or GMT as zone.
528 QStringLiteral("yyyy-MM-dd hh:mm:ss t"),
529 QStringLiteral("ddd, d MMM yyyy hh:mm:ss t"),
530 };
531
532 for (const QString &format : formats) {
533 dt = format.indexOf(QLatin1String("hh:mm")) < 0
534 ? QDate::fromString(s, format).startOfDay(QTimeZone::UTC)
535 : QDateTime::fromString(s, format); // as local time
536 if (dt.isValid())
537 break;
538 }
539 }
540 if (!dt.isValid())
541 return qt_qnan();
542 return TimeClip(dt.toMSecsSinceEpoch());
543}
544
551static inline QDateTime ToDateTime(double t, QTimeZone zone)
552{
553 if (std::isnan(t))
554 return QDateTime().toTimeZone(zone);
555 return QDateTime::fromMSecsSinceEpoch(t, zone);
556}
557
558static inline QString ToString(double t, double localTZA)
559{
560 if (std::isnan(t))
561 return QStringLiteral("Invalid Date");
562 QString str = ToDateTime(t, QTimeZone::LocalTime).toString() + QLatin1String(" GMT");
563 double tzoffset = localTZA + DaylightSavingTA(t, localTZA);
564 if (tzoffset) {
565 int hours = static_cast<int>(::fabs(tzoffset) / 1000 / 60 / 60);
566 int mins = int(::fabs(tzoffset) / 1000 / 60) % 60;
567 str.append(QLatin1Char((tzoffset > 0) ? '+' : '-'));
568 if (hours < 10)
569 str.append(QLatin1Char('0'));
570 str.append(QString::number(hours));
571 if (mins < 10)
572 str.append(QLatin1Char('0'));
574 }
575 return str;
576}
577
578static inline QString ToUTCString(double t)
579{
580 if (std::isnan(t))
581 return QStringLiteral("Invalid Date");
582 return ToDateTime(t, QTimeZone::UTC).toString();
583}
584
585static inline QString ToDateString(double t)
586{
587 return ToDateTime(t, QTimeZone::LocalTime).date().toString();
588}
589
590static inline QString ToTimeString(double t)
591{
592 return ToDateTime(t, QTimeZone::LocalTime).time().toString();
593}
594
599
604
609
610static double getLocalTZA()
611{
613}
614
616
617quint64 Date::encode(double value)
618{
619 if (std::isnan(value) || fabs(value) > MaxDateVal)
620 return InvalidDateVal;
621
622 // Do the addition in qint64. This way we won't overflow if value is negative
623 // and we will round value in the right direction.
624 // We know we can do this because we know we have more than one bit left in quint64.
626
627 return encoded + Extra;
628}
629
630quint64 Date::encode(const QDateTime &dateTime)
631{
633}
634
635void Date::init(double value)
636{
637 storage = encode(value);
638}
639
640void Date::init(const QDateTime &when)
641{
642 storage = encode(when) | HasQDate | HasQTime;
643}
644
646{
647 storage = encode(date.startOfDay(QTimeZone::UTC)) | HasQDate;
648}
649
651{
652 if (!time.isValid()) {
653 storage = encode(qt_qnan()) | HasQTime;
654 return;
655 }
656
657 /* We have to chose a date on which to instantiate this time. All we really
658 * care about is that it round-trips back to the same time if we extract the
659 * time from it, which shall (via toQDateTime(), below) discard the date
660 * part. We need a date for which time-zone data is likely to be sane (so
661 * MakeDay(0, 0, 0) was a bad choice; 2 BC, December 31st is before
662 * time-zones were standardized), with no transition nearby in date.
663 * QDateTime ignores DST transitions before 1970, but even then zone
664 * transitions did happen; and DaylightSavingTA() will include DST, at odds
665 * with QDateTime. So pick a date since 1970 and prefer one when no zone
666 * was in DST. One such interval (according to the Olson database, at
667 * least) was 1971 March 15th to April 17th. Since converting a time to a
668 * date-time without specifying a date is foolish, let's use April Fools'
669 * day.
670 */
671 static const double d = MakeDay(1971, 3, 1);
672 double t = MakeTime(time.hour(), time.minute(), time.second(), time.msec());
673 storage = encode(UTC(MakeDate(d, t), engine->localTZA)) | HasQTime;
674}
675
677{
678 return toQDateTime().date();
679}
680
682{
683 return toQDateTime().time();
684}
685
687{
688 return ToDateTime(operator double(), QTimeZone::LocalTime);
689}
690
692{
693 switch (storage & (HasQDate | HasQTime)) {
694 case HasQDate:
695 return toQDate();
696 case HasQTime:
697 return toQTime();
698 case (HasQDate | HasQTime):
699 return toQDateTime();
700 default:
701 return QVariant();
702 }
703}
704
706{
707 return d()->toQDateTime();
708}
709
711{
712 return ToString(d()->date(), engine()->localTZA);
713}
714
721
723{
724 if (!dateTime.isValid())
725 return qQNaN();
727}
728
733
735{
736 return ToDateTime(timestamp, zone);
737}
738
740 double year, double month, double day, double hours,
741 double mins, double secs, double ms, ExecutionEngine *v4)
742{
743 if (year >= 0 && year <= 99)
744 year += 1900;
745 const double t = MakeDate(MakeDay(year, month, day), MakeTime(hours, mins, secs, ms));
746 return UTC(t, v4->localTZA);
747}
748
750{
751 // If the Date object was parse()d from a string with no time part
752 // or zone specifier it's really the UTC start of the relevant day,
753 // but it's here represented as a local time, which may fall in the
754 // preceding day. See QTBUG-92466 for the gory details.
755 const auto utc = dateTime.toUTC();
756 if (utc.date() != dateTime.date() && utc.addSecs(-1).date() == dateTime.date())
757 return utc.date();
758
759 // This may, of course, be The Wrong Thing if the date was
760 // constructed as a full local date-time that happens to coincide
761 // with the start of a UTC day; however, that would be an odd value
762 // to give to something that, apparently, someone thinks belongs in
763 // a QDate.
764 return dateTime.date();
765}
766
768
770{
771 Heap::FunctionObject::init(engine, QStringLiteral("Date"));
772}
773
774ReturnedValue DateCtor::virtualCallAsConstructor(const FunctionObject *that, const Value *argv, int argc, const Value *newTarget)
775{
776 ExecutionEngine *v4 = that->engine();
777 double t = 0;
778
779 if (argc == 0)
780 t = currentTime();
781
782 else if (argc == 1) {
783 Scope scope(v4);
784 ScopedValue arg(scope, argv[0]);
785 if (DateObject *d = arg->as<DateObject>()) {
786 t = d->date();
787 } else {
789
790 if (String *s = arg->stringValue())
791 t = ParseString(s->toQString(), v4->localTZA);
792 else
793 t = arg->toNumber();
794 }
795 }
796
797 else { // d.argc > 1
798 const double year = argv[0].toNumber();
799 const double month = argv[1].toNumber();
800 const double day = argc >= 3 ? argv[2].toNumber() : 1;
801 const double hours = argc >= 4 ? argv[3].toNumber() : 0;
802 const double mins = argc >= 5 ? argv[4].toNumber() : 0;
803 const double secs = argc >= 6 ? argv[5].toNumber() : 0;
804 const double ms = argc >= 7 ? argv[6].toNumber() : 0;
805 t = DateObject::componentsToTimestamp(year, month, day, hours, mins, secs, ms, v4);
806 }
807
809 if (!newTarget)
810 return o;
811 Scope scope(v4);
812 ScopedObject obj(scope, o);
813 obj->setProtoFromNewTarget(newTarget);
814 return obj->asReturnedValue();
815}
816
818{
819 ExecutionEngine *e = m->engine();
820 double t = currentTime();
821 return e->newString(ToString(t, e->localTZA))->asReturnedValue();
822}
823
825{
826 Scope scope(engine);
827 ScopedObject o(scope);
828 ctor->defineReadonlyProperty(engine->id_prototype(), (o = this));
829 ctor->defineReadonlyConfigurableProperty(engine->id_length(), Value::fromInt32(7));
830 engine->localTZA = getLocalTZA();
831
832 ctor->defineDefaultProperty(QStringLiteral("parse"), method_parse, 1);
833 ctor->defineDefaultProperty(QStringLiteral("UTC"), method_UTC, 7);
834 ctor->defineDefaultProperty(QStringLiteral("now"), method_now, 0);
835
836 defineDefaultProperty(QStringLiteral("constructor"), (o = ctor));
837 defineDefaultProperty(engine->id_toString(), method_toString, 0);
838 defineDefaultProperty(QStringLiteral("toDateString"), method_toDateString, 0);
839 defineDefaultProperty(QStringLiteral("toTimeString"), method_toTimeString, 0);
840 defineDefaultProperty(engine->id_toLocaleString(), method_toLocaleString, 0);
841 defineDefaultProperty(QStringLiteral("toLocaleDateString"), method_toLocaleDateString, 0);
842 defineDefaultProperty(QStringLiteral("toLocaleTimeString"), method_toLocaleTimeString, 0);
843 defineDefaultProperty(engine->id_valueOf(), method_valueOf, 0);
844 defineDefaultProperty(QStringLiteral("getTime"), method_getTime, 0);
845 defineDefaultProperty(QStringLiteral("getYear"), method_getYear, 0);
846 defineDefaultProperty(QStringLiteral("getFullYear"), method_getFullYear, 0);
847 defineDefaultProperty(QStringLiteral("getUTCFullYear"), method_getUTCFullYear, 0);
848 defineDefaultProperty(QStringLiteral("getMonth"), method_getMonth, 0);
849 defineDefaultProperty(QStringLiteral("getUTCMonth"), method_getUTCMonth, 0);
850 defineDefaultProperty(QStringLiteral("getDate"), method_getDate, 0);
851 defineDefaultProperty(QStringLiteral("getUTCDate"), method_getUTCDate, 0);
852 defineDefaultProperty(QStringLiteral("getDay"), method_getDay, 0);
853 defineDefaultProperty(QStringLiteral("getUTCDay"), method_getUTCDay, 0);
854 defineDefaultProperty(QStringLiteral("getHours"), method_getHours, 0);
855 defineDefaultProperty(QStringLiteral("getUTCHours"), method_getUTCHours, 0);
856 defineDefaultProperty(QStringLiteral("getMinutes"), method_getMinutes, 0);
857 defineDefaultProperty(QStringLiteral("getUTCMinutes"), method_getUTCMinutes, 0);
858 defineDefaultProperty(QStringLiteral("getSeconds"), method_getSeconds, 0);
859 defineDefaultProperty(QStringLiteral("getUTCSeconds"), method_getUTCSeconds, 0);
860 defineDefaultProperty(QStringLiteral("getMilliseconds"), method_getMilliseconds, 0);
861 defineDefaultProperty(QStringLiteral("getUTCMilliseconds"), method_getUTCMilliseconds, 0);
862 defineDefaultProperty(QStringLiteral("getTimezoneOffset"), method_getTimezoneOffset, 0);
863 defineDefaultProperty(QStringLiteral("setTime"), method_setTime, 1);
864 defineDefaultProperty(QStringLiteral("setMilliseconds"), method_setMilliseconds, 1);
865 defineDefaultProperty(QStringLiteral("setUTCMilliseconds"), method_setUTCMilliseconds, 1);
866 defineDefaultProperty(QStringLiteral("setSeconds"), method_setSeconds, 2);
867 defineDefaultProperty(QStringLiteral("setUTCSeconds"), method_setUTCSeconds, 2);
868 defineDefaultProperty(QStringLiteral("setMinutes"), method_setMinutes, 3);
869 defineDefaultProperty(QStringLiteral("setUTCMinutes"), method_setUTCMinutes, 3);
870 defineDefaultProperty(QStringLiteral("setHours"), method_setHours, 4);
871 defineDefaultProperty(QStringLiteral("setUTCHours"), method_setUTCHours, 4);
872 defineDefaultProperty(QStringLiteral("setDate"), method_setDate, 1);
873 defineDefaultProperty(QStringLiteral("setUTCDate"), method_setUTCDate, 1);
874 defineDefaultProperty(QStringLiteral("setMonth"), method_setMonth, 2);
875 defineDefaultProperty(QStringLiteral("setUTCMonth"), method_setUTCMonth, 2);
876 defineDefaultProperty(QStringLiteral("setYear"), method_setYear, 1);
877 defineDefaultProperty(QStringLiteral("setFullYear"), method_setFullYear, 3);
878 defineDefaultProperty(QStringLiteral("setUTCFullYear"), method_setUTCFullYear, 3);
879
880 // ES6: B.2.4.3 & 20.3.4.43:
881 // We have to use the *same object* for toUTCString and toGMTString
882 {
883 QString toUtcString(QStringLiteral("toUTCString"));
884 QString toGmtString(QStringLiteral("toGMTString"));
885 ScopedString us(scope, engine->newIdentifier(toUtcString));
886 ScopedString gs(scope, engine->newIdentifier(toGmtString));
887 ScopedFunctionObject toUtcGmtStringFn(scope, FunctionObject::createBuiltinFunction(engine, us, method_toUTCString, 0));
888 defineDefaultProperty(us, toUtcGmtStringFn);
889 defineDefaultProperty(gs, toUtcGmtStringFn);
890 }
891
892 defineDefaultProperty(QStringLiteral("toISOString"), method_toISOString, 0);
893 defineDefaultProperty(QStringLiteral("toJSON"), method_toJSON, 1);
894 defineDefaultProperty(engine->symbol_toPrimitive(), method_symbolToPrimitive, 1, Attr_ReadOnly_ButConfigurable);
895}
896
898{
899 if (const DateObject *that = thisObject->as<DateObject>())
900 return that->date();
901 v4->throwTypeError();
902 return 0;
903}
904
906{
907 if (!argc)
908 return Encode(qt_qnan());
909 else
910 return Encode(ParseString(argv[0].toQString(), f->engine()->localTZA));
911}
912
913ReturnedValue DatePrototype::method_UTC(const FunctionObject *f, const Value *, const Value *argv, int argc)
914{
915 const int numArgs = argc;
916 if (numArgs < 1)
917 return Encode(qQNaN());
918 ExecutionEngine *e = f->engine();
919 double year = argv[0].toNumber();
920 if (e->hasException)
921 return Encode::undefined();
922 double month = numArgs >= 2 ? argv[1].toNumber() : 0;
923 if (e->hasException)
924 return Encode::undefined();
925 double day = numArgs >= 3 ? argv[2].toNumber() : 1;
926 if (e->hasException)
927 return Encode::undefined();
928 double hours = numArgs >= 4 ? argv[3].toNumber() : 0;
929 if (e->hasException)
930 return Encode::undefined();
931 double mins = numArgs >= 5 ? argv[4].toNumber() : 0;
932 if (e->hasException)
933 return Encode::undefined();
934 double secs = numArgs >= 6 ? argv[5].toNumber() : 0;
935 if (e->hasException)
936 return Encode::undefined();
937 double ms = numArgs >= 7 ? argv[6].toNumber() : 0;
938 if (e->hasException)
939 return Encode::undefined();
940 double iyear = QV4::Value::toInteger(year);
941 if (!qIsNaN(year) && iyear >= 0 && iyear <= 99)
942 year = 1900 + iyear;
943 double t = MakeDate(MakeDay(year, month, day),
944 MakeTime(hours, mins, secs, ms));
945 return Encode(TimeClip(t));
946}
947
949{
950 return Encode(currentTime());
951}
952
954{
955 ExecutionEngine *v4 = b->engine();
956 double t = getThisDate(v4, thisObject);
957 return Encode(v4->newString(ToString(t, v4->localTZA)));
958}
959
961{
962 ExecutionEngine *v4 = b->engine();
963 double t = getThisDate(v4, thisObject);
964 return Encode(v4->newString(ToDateString(t)));
965}
966
968{
969 ExecutionEngine *v4 = b->engine();
970 double t = getThisDate(v4, thisObject);
971 return Encode(v4->newString(ToTimeString(t)));
972}
973
975{
976 ExecutionEngine *v4 = b->engine();
977 double t = getThisDate(v4, thisObject);
978 return Encode(v4->newString(ToLocaleString(t)));
979}
980
982{
983 ExecutionEngine *v4 = b->engine();
984 double t = getThisDate(v4, thisObject);
985 return Encode(v4->newString(ToLocaleDateString(t)));
986}
987
989{
990 ExecutionEngine *v4 = b->engine();
991 double t = getThisDate(v4, thisObject);
992 return Encode(v4->newString(ToLocaleTimeString(t)));
993}
994
996{
997 ExecutionEngine *v4 = b->engine();
998 double t = getThisDate(v4, thisObject);
999 return Encode(t);
1000}
1001
1003{
1004 ExecutionEngine *v4 = b->engine();
1005 double t = getThisDate(v4, thisObject);
1006 return Encode(t);
1007}
1008
1010{
1011 ExecutionEngine *v4 = b->engine();
1012 double t = getThisDate(v4, thisObject);
1013 if (!std::isnan(t))
1014 t = YearFromTime(LocalTime(t, v4->localTZA)) - 1900;
1015 return Encode(t);
1016}
1017
1019{
1020 ExecutionEngine *v4 = b->engine();
1021 double t = getThisDate(v4, thisObject);
1022 if (!std::isnan(t))
1024 return Encode(t);
1025}
1026
1028{
1029 ExecutionEngine *v4 = b->engine();
1030 double t = getThisDate(v4, thisObject);
1031 if (!std::isnan(t))
1032 t = YearFromTime(t);
1033 return Encode(t);
1034}
1035
1037{
1038 ExecutionEngine *v4 = b->engine();
1039 double t = getThisDate(v4, thisObject);
1040 if (!std::isnan(t))
1042 return Encode(t);
1043}
1044
1046{
1047 ExecutionEngine *v4 = b->engine();
1048 double t = getThisDate(v4, thisObject);
1049 if (!std::isnan(t))
1050 t = MonthFromTime(t);
1051 return Encode(t);
1052}
1053
1055{
1056 ExecutionEngine *v4 = b->engine();
1057 double t = getThisDate(v4, thisObject);
1058 if (!std::isnan(t))
1060 return Encode(t);
1061}
1062
1064{
1065 ExecutionEngine *v4 = b->engine();
1066 double t = getThisDate(v4, thisObject);
1067 if (!std::isnan(t))
1068 t = DateFromTime(t);
1069 return Encode(t);
1070}
1071
1073{
1074 ExecutionEngine *v4 = b->engine();
1075 double t = getThisDate(v4, thisObject);
1076 if (!std::isnan(t))
1077 t = WeekDay(LocalTime(t, v4->localTZA));
1078 return Encode(t);
1079}
1080
1082{
1083 ExecutionEngine *v4 = b->engine();
1084 double t = getThisDate(v4, thisObject);
1085 if (!std::isnan(t))
1086 t = WeekDay(t);
1087 return Encode(t);
1088}
1089
1091{
1092 ExecutionEngine *v4 = b->engine();
1093 double t = getThisDate(v4, thisObject);
1094 if (!std::isnan(t))
1096 return Encode(t);
1097}
1098
1100{
1101 ExecutionEngine *v4 = b->engine();
1102 double t = getThisDate(v4, thisObject);
1103 if (!std::isnan(t))
1104 t = HourFromTime(t);
1105 return Encode(t);
1106}
1107
1109{
1110 ExecutionEngine *v4 = b->engine();
1111 double t = getThisDate(v4, thisObject);
1112 if (!std::isnan(t))
1113 t = MinFromTime(LocalTime(t, v4->localTZA));
1114 return Encode(t);
1115}
1116
1118{
1119 ExecutionEngine *v4 = b->engine();
1120 double t = getThisDate(v4, thisObject);
1121 if (!std::isnan(t))
1122 t = MinFromTime(t);
1123 return Encode(t);
1124}
1125
1127{
1128 ExecutionEngine *v4 = b->engine();
1129 double t = getThisDate(v4, thisObject);
1130 if (!std::isnan(t))
1131 t = SecFromTime(LocalTime(t, v4->localTZA));
1132 return Encode(t);
1133}
1134
1136{
1137 ExecutionEngine *v4 = b->engine();
1138 double t = getThisDate(v4, thisObject);
1139 if (!std::isnan(t))
1140 t = SecFromTime(t);
1141 return Encode(t);
1142}
1143
1145{
1146 ExecutionEngine *v4 = b->engine();
1147 double t = getThisDate(v4, thisObject);
1148 if (!std::isnan(t))
1149 t = msFromTime(LocalTime(t, v4->localTZA));
1150 return Encode(t);
1151}
1152
1154{
1155 ExecutionEngine *v4 = b->engine();
1156 double t = getThisDate(v4, thisObject);
1157 if (!std::isnan(t))
1158 t = msFromTime(t);
1159 return Encode(t);
1160}
1161
1163{
1164 ExecutionEngine *v4 = b->engine();
1165 double t = getThisDate(v4, thisObject);
1166 if (!std::isnan(t))
1167 t = (t - LocalTime(t, v4->localTZA)) / msPerMinute;
1168 return Encode(t);
1169}
1170
1171ReturnedValue DatePrototype::method_setTime(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
1172{
1173 ExecutionEngine *v4 = b->engine();
1174 DateObject *self = const_cast<DateObject *>(thisObject->as<DateObject>());
1175 if (!self)
1176 return v4->throwTypeError();
1177
1178 double t = argc ? argv[0].toNumber() : qt_qnan();
1179 if (v4->hasException)
1180 return QV4::Encode::undefined();
1181 self->setDate(t);
1182 return Encode(self->date());
1183}
1184
1185ReturnedValue DatePrototype::method_setMilliseconds(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
1186{
1187 ExecutionEngine *v4 = b->engine();
1188 DateObject *self = const_cast<DateObject *>(thisObject->as<DateObject>());
1189 if (!self)
1190 return v4->throwTypeError();
1191
1192 double t = LocalTime(self->date(), v4->localTZA);
1193 if (v4->hasException)
1194 return QV4::Encode::undefined();
1195 double ms = argc ? argv[0].toNumber() : qt_qnan();
1196 if (v4->hasException)
1197 return QV4::Encode::undefined();
1198 self->setDate(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), SecFromTime(t), ms)), v4->localTZA));
1199 return Encode(self->date());
1200}
1201
1203{
1204 ExecutionEngine *v4 = b->engine();
1205 DateObject *self = const_cast<DateObject *>(thisObject->as<DateObject>());
1206 if (!self)
1207 return v4->throwTypeError();
1208
1209 double t = self->date();
1210 if (v4->hasException)
1211 return QV4::Encode::undefined();
1212 double ms = argc ? argv[0].toNumber() : qt_qnan();
1213 if (v4->hasException)
1214 return QV4::Encode::undefined();
1215 self->setDate(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), SecFromTime(t), ms)));
1216 return Encode(self->date());
1217}
1218
1219ReturnedValue DatePrototype::method_setSeconds(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
1220{
1221 ExecutionEngine *v4 = b->engine();
1222 DateObject *self = const_cast<DateObject *>(thisObject->as<DateObject>());
1223 if (!self)
1224 return v4->throwTypeError();
1225
1226 double t = LocalTime(self->date(), v4->localTZA);
1227 if (v4->hasException)
1228 return QV4::Encode::undefined();
1229 double sec = argc ? argv[0].toNumber() : qt_qnan();
1230 if (v4->hasException)
1231 return QV4::Encode::undefined();
1232 double ms = (argc < 2) ? msFromTime(t) : argv[1].toNumber();
1233 if (v4->hasException)
1234 return QV4::Encode::undefined();
1235 t = UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), sec, ms)), v4->localTZA);
1236 self->setDate(t);
1237 return Encode(self->date());
1238}
1239
1240ReturnedValue DatePrototype::method_setUTCSeconds(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
1241{
1242 ExecutionEngine *v4 = b->engine();
1243 DateObject *self = const_cast<DateObject *>(thisObject->as<DateObject>());
1244 if (!self)
1245 return v4->throwTypeError();
1246
1247 double t = self->date();
1248 double sec = argc ? argv[0].toNumber() : qt_qnan();
1249 double ms = (argc < 2) ? msFromTime(t) : argv[1].toNumber();
1250 t = MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), sec, ms));
1251 self->setDate(t);
1252 return Encode(self->date());
1253}
1254
1255ReturnedValue DatePrototype::method_setMinutes(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
1256{
1257 ExecutionEngine *v4 = b->engine();
1258 DateObject *self = const_cast<DateObject *>(thisObject->as<DateObject>());
1259 if (!self)
1260 return v4->throwTypeError();
1261
1262 double t = LocalTime(self->date(), v4->localTZA);
1263 if (v4->hasException)
1264 return QV4::Encode::undefined();
1265 double min = argc ? argv[0].toNumber() : qt_qnan();
1266 if (v4->hasException)
1267 return QV4::Encode::undefined();
1268 double sec = (argc < 2) ? SecFromTime(t) : argv[1].toNumber();
1269 if (v4->hasException)
1270 return QV4::Encode::undefined();
1271 double ms = (argc < 3) ? msFromTime(t) : argv[2].toNumber();
1272 if (v4->hasException)
1273 return QV4::Encode::undefined();
1274 t = UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), min, sec, ms)), v4->localTZA);
1275 self->setDate(t);
1276 return Encode(self->date());
1277}
1278
1279ReturnedValue DatePrototype::method_setUTCMinutes(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
1280{
1281 ExecutionEngine *v4 = b->engine();
1282 DateObject *self = const_cast<DateObject *>(thisObject->as<DateObject>());
1283 if (!self)
1284 return v4->throwTypeError();
1285
1286 double t = self->date();
1287 double min = argc ? argv[0].toNumber() : qt_qnan();
1288 double sec = (argc < 2) ? SecFromTime(t) : argv[1].toNumber();
1289 double ms = (argc < 3) ? msFromTime(t) : argv[2].toNumber();
1290 t = MakeDate(Day(t), MakeTime(HourFromTime(t), min, sec, ms));
1291 self->setDate(t);
1292 return Encode(self->date());
1293}
1294
1295ReturnedValue DatePrototype::method_setHours(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
1296{
1297 ExecutionEngine *v4 = b->engine();
1298 DateObject *self = const_cast<DateObject *>(thisObject->as<DateObject>());
1299 if (!self)
1300 return v4->throwTypeError();
1301
1302 double t = LocalTime(self->date(), v4->localTZA);
1303 if (v4->hasException)
1304 return QV4::Encode::undefined();
1305 double hour = argc ? argv[0].toNumber() : qt_qnan();
1306 if (v4->hasException)
1307 return QV4::Encode::undefined();
1308 double min = (argc < 2) ? MinFromTime(t) : argv[1].toNumber();
1309 if (v4->hasException)
1310 return QV4::Encode::undefined();
1311 double sec = (argc < 3) ? SecFromTime(t) : argv[2].toNumber();
1312 if (v4->hasException)
1313 return QV4::Encode::undefined();
1314 double ms = (argc < 4) ? msFromTime(t) : argv[3].toNumber();
1315 if (v4->hasException)
1316 return QV4::Encode::undefined();
1317 t = UTC(MakeDate(Day(t), MakeTime(hour, min, sec, ms)), v4->localTZA);
1318 self->setDate(t);
1319 return Encode(self->date());
1320}
1321
1322ReturnedValue DatePrototype::method_setUTCHours(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
1323{
1324 ExecutionEngine *v4 = b->engine();
1325 DateObject *self = const_cast<DateObject *>(thisObject->as<DateObject>());
1326 if (!self)
1327 return v4->throwTypeError();
1328
1329 double t = self->date();
1330 double hour = argc ? argv[0].toNumber() : qt_qnan();
1331 double min = (argc < 2) ? MinFromTime(t) : argv[1].toNumber();
1332 double sec = (argc < 3) ? SecFromTime(t) : argv[2].toNumber();
1333 double ms = (argc < 4) ? msFromTime(t) : argv[3].toNumber();
1334 t = MakeDate(Day(t), MakeTime(hour, min, sec, ms));
1335 self->setDate(t);
1336 return Encode(self->date());
1337}
1338
1339ReturnedValue DatePrototype::method_setDate(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
1340{
1341 ExecutionEngine *v4 = b->engine();
1342 DateObject *self = const_cast<DateObject *>(thisObject->as<DateObject>());
1343 if (!self)
1344 return v4->throwTypeError();
1345
1346 double t = LocalTime(self->date(), v4->localTZA);
1347 if (v4->hasException)
1348 return QV4::Encode::undefined();
1349 double date = argc ? argv[0].toNumber() : qt_qnan();
1350 if (v4->hasException)
1351 return QV4::Encode::undefined();
1353 self->setDate(t);
1354 return Encode(self->date());
1355}
1356
1357ReturnedValue DatePrototype::method_setUTCDate(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
1358{
1359 ExecutionEngine *v4 = b->engine();
1360 DateObject *self = const_cast<DateObject *>(thisObject->as<DateObject>());
1361 if (!self)
1362 return v4->throwTypeError();
1363
1364 double t = self->date();
1365 if (v4->hasException)
1366 return QV4::Encode::undefined();
1367 double date = argc ? argv[0].toNumber() : qt_qnan();
1368 if (v4->hasException)
1369 return QV4::Encode::undefined();
1371 self->setDate(t);
1372 return Encode(self->date());
1373}
1374
1375ReturnedValue DatePrototype::method_setMonth(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
1376{
1377 ExecutionEngine *v4 = b->engine();
1378 DateObject *self = const_cast<DateObject *>(thisObject->as<DateObject>());
1379 if (!self)
1380 return v4->throwTypeError();
1381
1382 double t = LocalTime(self->date(), v4->localTZA);
1383 if (v4->hasException)
1384 return QV4::Encode::undefined();
1385 double month = argc ? argv[0].toNumber() : qt_qnan();
1386 if (v4->hasException)
1387 return QV4::Encode::undefined();
1388 double date = (argc < 2) ? DateFromTime(t) : argv[1].toNumber();
1389 if (v4->hasException)
1390 return QV4::Encode::undefined();
1392 self->setDate(t);
1393 return Encode(self->date());
1394}
1395
1396ReturnedValue DatePrototype::method_setUTCMonth(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
1397{
1398 ExecutionEngine *v4 = b->engine();
1399 DateObject *self = const_cast<DateObject *>(thisObject->as<DateObject>());
1400 if (!self)
1401 return v4->throwTypeError();
1402
1403 double t = self->date();
1404 double month = argc ? argv[0].toNumber() : qt_qnan();
1405 double date = (argc < 2) ? DateFromTime(t) : argv[1].toNumber();
1407 self->setDate(t);
1408 return Encode(self->date());
1409}
1410
1411ReturnedValue DatePrototype::method_setYear(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
1412{
1413 ExecutionEngine *v4 = b->engine();
1414 DateObject *self = const_cast<DateObject *>(thisObject->as<DateObject>());
1415 if (!self)
1416 return v4->throwTypeError();
1417
1418 double t = self->date();
1419 if (std::isnan(t))
1420 t = 0;
1421 else
1422 t = LocalTime(t, v4->localTZA);
1423 double year = argc ? argv[0].toNumber() : qt_qnan();
1424 double r;
1425 if (std::isnan(year)) {
1426 r = qt_qnan();
1427 } else {
1428 if ((QV4::Value::toInteger(year) >= 0) && (QV4::Value::toInteger(year) <= 99))
1429 year += 1900;
1430 r = MakeDay(year, MonthFromTime(t), DateFromTime(t));
1431 r = UTC(MakeDate(r, TimeWithinDay(t)), v4->localTZA);
1432 }
1433 self->setDate(r);
1434 return Encode(self->date());
1435}
1436
1437ReturnedValue DatePrototype::method_setUTCFullYear(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
1438{
1439 ExecutionEngine *v4 = b->engine();
1440 DateObject *self = const_cast<DateObject *>(thisObject->as<DateObject>());
1441 if (!self)
1442 return v4->throwTypeError();
1443
1444 double t = self->date();
1445 double year = argc ? argv[0].toNumber() : qt_qnan();
1446 double month = (argc < 2) ? MonthFromTime(t) : argv[1].toNumber();
1447 double date = (argc < 3) ? DateFromTime(t) : argv[2].toNumber();
1448 t = MakeDate(MakeDay(year, month, date), TimeWithinDay(t));
1449 self->setDate(t);
1450 return Encode(self->date());
1451}
1452
1453ReturnedValue DatePrototype::method_setFullYear(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
1454{
1455 ExecutionEngine *v4 = b->engine();
1456 DateObject *self = const_cast<DateObject *>(thisObject->as<DateObject>());
1457 if (!self)
1458 return v4->throwTypeError();
1459
1460 double t = LocalTime(self->date(), v4->localTZA);
1461 if (v4->hasException)
1462 return QV4::Encode::undefined();
1463 if (std::isnan(t))
1464 t = 0;
1465 double year = argc ? argv[0].toNumber() : qt_qnan();
1466 if (v4->hasException)
1467 return QV4::Encode::undefined();
1468 double month = (argc < 2) ? MonthFromTime(t) : argv[1].toNumber();
1469 if (v4->hasException)
1470 return QV4::Encode::undefined();
1471 double date = (argc < 3) ? DateFromTime(t) : argv[2].toNumber();
1472 if (v4->hasException)
1473 return QV4::Encode::undefined();
1474 t = UTC(MakeDate(MakeDay(year, month, date), TimeWithinDay(t)), v4->localTZA);
1475 self->setDate(t);
1476 return Encode(self->date());
1477}
1478
1480{
1481 ExecutionEngine *v4 = b->engine();
1482 DateObject *self = const_cast<DateObject *>(thisObject->as<DateObject>());
1483 if (!self)
1484 return v4->throwTypeError();
1485
1486 double t = self->date();
1487 return Encode(v4->newString(ToUTCString(t)));
1488}
1489
1490static void addZeroPrefixedInt(QString &str, int num, int nDigits)
1491{
1492 str.resize(str.size() + nDigits);
1493
1494 QChar *c = str.data() + str.size() - 1;
1495 while (nDigits) {
1496 *c = QChar(num % 10 + '0');
1497 num /= 10;
1498 --c;
1499 --nDigits;
1500 }
1501}
1502
1504{
1505 ExecutionEngine *v4 = b->engine();
1506 DateObject *self = const_cast<DateObject *>(thisObject->as<DateObject>());
1507 if (!self)
1508 return v4->throwTypeError();
1509
1510 double t = self->date();
1511 if (!std::isfinite(t))
1512 RETURN_RESULT(v4->throwRangeError(*thisObject));
1513
1515 int year = (int)YearFromTime(t);
1516 if (year < 0 || year > 9999) {
1517 if (qAbs(year) >= 1000000)
1518 RETURN_RESULT(v4->throwRangeError(*thisObject));
1519 result += year < 0 ? QLatin1Char('-') : QLatin1Char('+');
1520 year = qAbs(year);
1521 addZeroPrefixedInt(result, year, 6);
1522 } else {
1523 addZeroPrefixedInt(result, year, 4);
1524 }
1525 result += QLatin1Char('-');
1527 result += QLatin1Char('-');
1529 result += QLatin1Char('T');
1531 result += QLatin1Char(':');
1533 result += QLatin1Char(':');
1535 result += QLatin1Char('.');
1537 result += QLatin1Char('Z');
1538
1539 return Encode(v4->newString(result));
1540}
1541
1543{
1544 ExecutionEngine *v4 = b->engine();
1545 Scope scope(v4);
1546 ScopedObject O(scope, thisObject->toObject(v4));
1547 if (v4->hasException)
1548 return QV4::Encode::undefined();
1549
1551
1552 if (tv->isNumber() && !std::isfinite(tv->toNumber()))
1553 return Encode::null();
1554
1555 ScopedString s(scope, v4->newString(QStringLiteral("toISOString")));
1556 ScopedValue v(scope, O->get(s));
1557 FunctionObject *toIso = v->as<FunctionObject>();
1558
1559 if (!toIso)
1560 return v4->throwTypeError();
1561
1562 return checkedResult(v4, toIso->call(O, nullptr, 0));
1563}
1564
1565ReturnedValue DatePrototype::method_symbolToPrimitive(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc)
1566{
1567 ExecutionEngine *e = f->engine();
1568 if (!thisObject->isObject() || !argc || !argv->isString())
1569 return e->throwTypeError();
1570
1571 String *hint = argv->stringValue();
1572 PropertyKey id = hint->toPropertyKey();
1573 if (id == e->id_default()->propertyKey())
1574 hint = e->id_string();
1575 else if (id != e->id_string()->propertyKey() && id != e->id_number()->propertyKey())
1576 return e->throwTypeError();
1577
1578 return RuntimeHelpers::ordinaryToPrimitive(e, static_cast<const Object *>(thisObject), hint);
1579}
1580
\inmodule QtCore
\inmodule QtCore\reentrant
Definition qdatetime.h:283
qint64 toMSecsSinceEpoch() const
static QDateTime fromMSecsSinceEpoch(qint64 msecs, const QTimeZone &timeZone)
QDateTime toTimeZone(const QTimeZone &toZone) const
QDateTime toUTC() const
Returns a copy of this datetime converted to UTC.
QTime time() const
Returns the time part of the datetime.
bool isValid() const
Returns true if this datetime represents a definite moment, otherwise false.
static QDateTime currentDateTimeUtc()
QDate date() const
Returns the date part of the datetime.
\inmodule QtCore \reentrant
Definition qdatetime.h:29
QDateTime startOfDay(const QTimeZone &zone) const
@ ShortFormat
Definition qlocale.h:875
QString toString(qlonglong i) const
Returns a localized string representation of i.
Definition qlocale.cpp:2052
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
qsizetype size() const noexcept
Returns the number of characters in this string.
Definition qstring.h:186
QChar * data()
Returns a pointer to the data stored in the QString.
Definition qstring.h:1240
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:8084
QString & append(QChar c)
Definition qstring.cpp:3252
void resize(qsizetype size)
Sets the size of the string to size characters.
Definition qstring.cpp:2668
\inmodule QtCore
Definition qtimezone.h:26
\inmodule QtCore \reentrant
Definition qdatetime.h:215
int hour() const
Returns the hour part (0 to 23) of the time.
int minute() const
Returns the minute part (0 to 59) of the time.
bool isValid() const
Returns true if the time is valid; otherwise returns false.
int msec() const
Returns the millisecond part (0 to 999) of the time.
int second() const
Returns the second part (0 to 59) of the time.
\inmodule QtCore
Definition qvariant.h:65
Format
Definition ddsheader.h:14
QString str
[2]
QDate date
[1]
EGLint EGLint * formats
int getCurrentStandardUtcOffset()
int getUtcOffset(qint64 atMSecsSinceEpoch)
@ PREFERREDTYPE_HINT
@ NUMBER_HINT
Scoped< FunctionObject > ScopedFunctionObject
quint64 ReturnedValue
ReturnedValue checkedResult(QV4::ExecutionEngine *v4, ReturnedValue result)
Scoped< String > ScopedString
@ Attr_ReadOnly_ButConfigurable
@ RFC2822Date
@ ISODate
@ TextDate
DBusConnection const char DBusError * error
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
bool qIsFinite(qfloat16 f) noexcept
Definition qfloat16.h:285
bool qIsNaN(qfloat16 f) noexcept
Definition qfloat16.h:284
#define qWarning
Definition qlogging.h:166
constexpr T qAbs(const T &t)
Definition qnumeric.h:328
Q_CORE_EXPORT Q_DECL_CONST_FUNCTION double qQNaN()
constexpr static Q_DECL_CONST_FUNCTION double qt_qnan() noexcept
Definition qnumeric_p.h:100
static Q_DECL_CONST_FUNCTION bool qt_is_finite(double d)
Definition qnumeric_p.h:117
GLboolean GLboolean GLboolean b
GLsizei const GLfloat * v
[13]
GLint GLint GLint GLint GLint x
[0]
const GLfloat * m
GLboolean r
[2]
GLuint GLuint end
GLfloat GLfloat f
GLenum GLuint GLintptr offset
GLint first
GLint GLsizei GLsizei GLenum format
GLint y
GLhandleARB obj
[2]
GLdouble s
[6]
Definition qopenglext.h:235
const GLubyte * c
GLdouble GLdouble t
Definition qopenglext.h:243
GLuint64EXT * result
[6]
GLuint num
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
SSL_CTX int void * arg
QLatin1StringView QLatin1String
Definition qstringfwd.h:31
#define QStringLiteral(str)
static QT_BEGIN_NAMESPACE QVariant hint(QPlatformIntegration::StyleHint h)
#define t2
unsigned long long quint64
Definition qtypes.h:61
unsigned int uint
Definition qtypes.h:34
long long qint64
Definition qtypes.h:60
#define encode(x)
static const double msPerHour
static const double msPerDay
static bool InLeapYear(double t)
static double DayFromYear(double y)
static QString ToString(double t, double localTZA)
static double UTC(double t, double localTZA)
static double ParseString(const QString &s, double localTZA)
static QString ToUTCString(double t)
static const double MinutesPerHour
static int msFromTime(double t)
static double DaysInYear(double y)
static const double msPerSecond
static QString ToLocaleTimeString(double t)
static double YearFromTime(double t)
static QDateTime ToDateTime(double t, QTimeZone zone)
static QString ToTimeString(double t)
static const double msPerMinute
static double getLocalTZA()
static double TimeWithinDay(double t)
static double TimeFromYear(double y)
static QString ToLocaleDateString(double t)
static double DayFromMonth(double month, double leap)
static double WeekDay(double t)
static double MakeDate(double day, double time)
static double MakeDay(double year, double month, double day)
static double DaylightSavingTA(double t, double localTZA)
static QString ToLocaleString(double t)
static double DayWithinYear(double t)
static void addZeroPrefixedInt(QString &str, int num, int nDigits)
static double MonthFromTime(double t)
static int HourFromTime(double t)
static int SecFromTime(double t)
static double Day(double t)
static double TimeClip(double t)
static int MinFromTime(double t)
static QString ToDateString(double t)
static double MakeTime(double hour, double min, double sec, double ms)
static const double SecondsPerMinute
static double DateFromTime(double t)
static double LocalTime(double t, double localTZA)
static const double HoursPerDay
static double currentTime()
#define RETURN_RESULT(r)
#define DEFINE_OBJECT_VTABLE(classname)
QDateTime dateTime
[12]
QJSEngine engine
[0]
\inmodule QtCore \reentrant
Definition qchar.h:18
static QDate dateTimeToDate(const QDateTime &dateTime)
static QString dateTimeToString(const QDateTime &dateTime, ExecutionEngine *engine)
static QDateTime timestampToDateTime(double timestamp, QTimeZone zone=QTimeZone::LocalTime)
static QDateTime stringToDateTime(const QString &string, ExecutionEngine *engine)
static double dateTimeToNumber(const QDateTime &dateTime)
QString toString() const
Q_QML_EXPORT QDateTime toQDateTime() const
double date() const
static double componentsToTimestamp(double year, double month, double day, double hours, double mins, double secs, double ms, ExecutionEngine *v4)
static ReturnedValue method_setMilliseconds(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_getMonth(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_UTC(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_setMinutes(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_getUTCMilliseconds(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_toTimeString(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_getYear(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_setUTCHours(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_setUTCMonth(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_setFullYear(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_getUTCSeconds(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_getTimezoneOffset(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_toString(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_toLocaleDateString(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_setMonth(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_setUTCSeconds(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_getDay(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_toLocaleTimeString(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_getUTCDay(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_getSeconds(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_setTime(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_toISOString(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_getUTCHours(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_setUTCMilliseconds(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static void timezoneUpdated(ExecutionEngine *e)
static ReturnedValue method_setUTCFullYear(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_toDateString(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_getUTCMinutes(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_setHours(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_getUTCMonth(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_symbolToPrimitive(const FunctionObject *f, const Value *thisObject, const Value *, int)
static ReturnedValue method_getTime(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
void init(ExecutionEngine *engine, Object *ctor)
static ReturnedValue method_valueOf(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_setDate(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_parse(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_toJSON(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_toUTCString(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_toLocaleString(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_getUTCDate(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_setUTCDate(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_getDate(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_setYear(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_getUTCFullYear(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_getMinutes(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_getFullYear(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_now(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_getMilliseconds(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_getHours(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_setUTCMinutes(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static double getThisDate(ExecutionEngine *v4, const Value *thisObject)
static ReturnedValue method_setSeconds(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
QDate toQDate() const
QVariant toVariant() const
static constexpr quint64 MaxDateVal
QTime toQTime() const
QDateTime toQDateTime() const
static constexpr ReturnedValue undefined()
static constexpr ReturnedValue null()
Heap::DateObject * newDateObject(double dateTime)
ReturnedValue throwRangeError(const Value &value)
String * id_string() const
Heap::String * newString(char16_t c)
String * id_default() const
String * id_number() const
ReturnedValue throwTypeError()
static Heap::FunctionObject * createBuiltinFunction(ExecutionEngine *engine, StringOrSymbol *nameOrSymbol, VTable::Call code, int argumentCount)
ReturnedValue asReturnedValue() const
Definition qv4value_p.h:342
void init(QV4::ExecutionEngine *engine)
ExecutionEngine * engine() const
static ReturnedValue ordinaryToPrimitive(ExecutionEngine *engine, const Object *object, String *typeHint)
static ReturnedValue toPrimitive(const Value &value, TypeHint typeHint)
static constexpr VTable::CallAsConstructor virtualCallAsConstructor
static constexpr VTable::Call virtualCall
static constexpr Value fromInt32(int i)
Definition qv4value_p.h:187
bool isString() const
Definition qv4value_p.h:284
QML_NEARLY_ALWAYS_INLINE String * stringValue() const
Definition qv4value_p.h:55
double toNumber() const
Definition qv4value_p.h:323
const T * as() const
Definition qv4value_p.h:132
double toInteger() const
Definition qv4value_p.h:394
Heap::Object * toObject(ExecutionEngine *e) const
Definition qv4value_p.h:122
bool isObject() const
Definition qv4value_p.h:302