1425bb815Sopenharmony_ci/* Copyright JS Foundation and other contributors, http://js.foundation 2425bb815Sopenharmony_ci * 3425bb815Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4425bb815Sopenharmony_ci * you may not use this file except in compliance with the License. 5425bb815Sopenharmony_ci * You may obtain a copy of the License at 6425bb815Sopenharmony_ci * 7425bb815Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8425bb815Sopenharmony_ci * 9425bb815Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10425bb815Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS 11425bb815Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12425bb815Sopenharmony_ci * See the License for the specific language governing permissions and 13425bb815Sopenharmony_ci * limitations under the License. 14425bb815Sopenharmony_ci */ 15425bb815Sopenharmony_ci 16425bb815Sopenharmony_ci#include <math.h> 17425bb815Sopenharmony_ci 18425bb815Sopenharmony_ci#include "jcontext.h" 19425bb815Sopenharmony_ci#include "ecma-function-object.h" 20425bb815Sopenharmony_ci#include "ecma-alloc.h" 21425bb815Sopenharmony_ci#include "ecma-builtin-helpers.h" 22425bb815Sopenharmony_ci#include "ecma-conversion.h" 23425bb815Sopenharmony_ci#include "ecma-exceptions.h" 24425bb815Sopenharmony_ci#include "ecma-gc.h" 25425bb815Sopenharmony_ci#include "ecma-globals.h" 26425bb815Sopenharmony_ci#include "ecma-helpers.h" 27425bb815Sopenharmony_ci#include "ecma-try-catch-macro.h" 28425bb815Sopenharmony_ci#include "lit-char-helpers.h" 29425bb815Sopenharmony_ci 30425bb815Sopenharmony_ci#if ENABLED (JERRY_BUILTIN_DATE) 31425bb815Sopenharmony_ci 32425bb815Sopenharmony_ci#define ECMA_BUILTINS_INTERNAL 33425bb815Sopenharmony_ci#include "ecma-builtins-internal.h" 34425bb815Sopenharmony_ci 35425bb815Sopenharmony_ci#define BUILTIN_INC_HEADER_NAME "ecma-builtin-date.inc.h" 36425bb815Sopenharmony_ci#define BUILTIN_UNDERSCORED_ID date 37425bb815Sopenharmony_ci#include "ecma-builtin-internal-routines-template.inc.h" 38425bb815Sopenharmony_ci 39425bb815Sopenharmony_ci/** \addtogroup ecma ECMA 40425bb815Sopenharmony_ci * @{ 41425bb815Sopenharmony_ci * 42425bb815Sopenharmony_ci * \addtogroup ecmabuiltins 43425bb815Sopenharmony_ci * @{ 44425bb815Sopenharmony_ci * 45425bb815Sopenharmony_ci * \addtogroup date ECMA Date object built-in 46425bb815Sopenharmony_ci * @{ 47425bb815Sopenharmony_ci */ 48425bb815Sopenharmony_ci 49425bb815Sopenharmony_ci/** 50425bb815Sopenharmony_ci * Helper function to try to parse a part of a date string 51425bb815Sopenharmony_ci * 52425bb815Sopenharmony_ci * @return NaN if cannot read from string, ToNumber() otherwise 53425bb815Sopenharmony_ci */ 54425bb815Sopenharmony_cistatic ecma_number_t 55425bb815Sopenharmony_ciecma_date_parse_date_chars (const lit_utf8_byte_t **str_p, /**< pointer to the cesu8 string */ 56425bb815Sopenharmony_ci const lit_utf8_byte_t *str_end_p, /**< pointer to the end of the string */ 57425bb815Sopenharmony_ci uint32_t num_of_chars, /**< number of characters to read and convert */ 58425bb815Sopenharmony_ci uint32_t min, /**< minimum valid value */ 59425bb815Sopenharmony_ci uint32_t max) /**< maximum valid value */ 60425bb815Sopenharmony_ci{ 61425bb815Sopenharmony_ci JERRY_ASSERT (num_of_chars > 0); 62425bb815Sopenharmony_ci const lit_utf8_byte_t *str_start_p = *str_p; 63425bb815Sopenharmony_ci 64425bb815Sopenharmony_ci while (num_of_chars--) 65425bb815Sopenharmony_ci { 66425bb815Sopenharmony_ci if (*str_p >= str_end_p || !lit_char_is_decimal_digit (lit_cesu8_read_next (str_p))) 67425bb815Sopenharmony_ci { 68425bb815Sopenharmony_ci return ecma_number_make_nan (); 69425bb815Sopenharmony_ci } 70425bb815Sopenharmony_ci } 71425bb815Sopenharmony_ci 72425bb815Sopenharmony_ci ecma_number_t parsed_number = ecma_utf8_string_to_number (str_start_p, (lit_utf8_size_t) (*str_p - str_start_p)); 73425bb815Sopenharmony_ci 74425bb815Sopenharmony_ci if (parsed_number < min || parsed_number > max) 75425bb815Sopenharmony_ci { 76425bb815Sopenharmony_ci return ecma_number_make_nan (); 77425bb815Sopenharmony_ci } 78425bb815Sopenharmony_ci 79425bb815Sopenharmony_ci return parsed_number; 80425bb815Sopenharmony_ci} /* ecma_date_parse_date_chars */ 81425bb815Sopenharmony_ci 82425bb815Sopenharmony_ci/** 83425bb815Sopenharmony_ci * Helper function to try to parse a special chracter (+,-,T,Z,:,.) in a date string 84425bb815Sopenharmony_ci * 85425bb815Sopenharmony_ci * @return true if the first character is same as the expected, false otherwise 86425bb815Sopenharmony_ci */ 87425bb815Sopenharmony_cistatic bool 88425bb815Sopenharmony_ciecma_date_parse_special_char (const lit_utf8_byte_t **str_p, /**< pointer to the cesu8 string */ 89425bb815Sopenharmony_ci const lit_utf8_byte_t *str_end_p, /**< pointer to the end of the string */ 90425bb815Sopenharmony_ci const lit_utf8_byte_t expected_char) /**< expected character */ 91425bb815Sopenharmony_ci{ 92425bb815Sopenharmony_ci if ((*str_p < str_end_p) && (**str_p == expected_char)) 93425bb815Sopenharmony_ci { 94425bb815Sopenharmony_ci (*str_p)++; 95425bb815Sopenharmony_ci return true; 96425bb815Sopenharmony_ci } 97425bb815Sopenharmony_ci 98425bb815Sopenharmony_ci return false; 99425bb815Sopenharmony_ci} /* ecma_date_parse_special_char */ 100425bb815Sopenharmony_ci 101425bb815Sopenharmony_ci/** 102425bb815Sopenharmony_ci * Helper function to try to parse a 4-5-6 digit year with optional negative sign in a date string 103425bb815Sopenharmony_ci * 104425bb815Sopenharmony_ci * Date.prototype.toString() and Date.prototype.toUTCString() emits year 105425bb815Sopenharmony_ci * in this format and Date.parse() should parse this format too. 106425bb815Sopenharmony_ci * 107425bb815Sopenharmony_ci * @return the parsed year or NaN. 108425bb815Sopenharmony_ci */ 109425bb815Sopenharmony_cistatic ecma_number_t 110425bb815Sopenharmony_ciecma_date_parse_year (const lit_utf8_byte_t **str_p, /**< pointer to the cesu8 string */ 111425bb815Sopenharmony_ci const lit_utf8_byte_t *str_end_p) /**< pointer to the end of the string */ 112425bb815Sopenharmony_ci{ 113425bb815Sopenharmony_ci bool is_year_sign_negative = ecma_date_parse_special_char (str_p, str_end_p, '-'); 114425bb815Sopenharmony_ci const lit_utf8_byte_t *str_start_p = *str_p; 115425bb815Sopenharmony_ci int32_t parsed_year = 0; 116425bb815Sopenharmony_ci 117425bb815Sopenharmony_ci while ((str_start_p - *str_p < 6) && (str_start_p < str_end_p) && lit_char_is_decimal_digit (*str_start_p)) 118425bb815Sopenharmony_ci { 119425bb815Sopenharmony_ci parsed_year = 10 * parsed_year + *str_start_p - LIT_CHAR_0; 120425bb815Sopenharmony_ci str_start_p++; 121425bb815Sopenharmony_ci } 122425bb815Sopenharmony_ci 123425bb815Sopenharmony_ci if (str_start_p - *str_p >=4) 124425bb815Sopenharmony_ci { 125425bb815Sopenharmony_ci *str_p = str_start_p; 126425bb815Sopenharmony_ci if (is_year_sign_negative) 127425bb815Sopenharmony_ci { 128425bb815Sopenharmony_ci return -parsed_year; 129425bb815Sopenharmony_ci } 130425bb815Sopenharmony_ci return parsed_year; 131425bb815Sopenharmony_ci } 132425bb815Sopenharmony_ci 133425bb815Sopenharmony_ci return ecma_number_make_nan (); 134425bb815Sopenharmony_ci} /* ecma_date_parse_year */ 135425bb815Sopenharmony_ci 136425bb815Sopenharmony_ci/** 137425bb815Sopenharmony_ci * Helper function to try to parse a day name in a date string 138425bb815Sopenharmony_ci * Valid day names: Sun, Mon, Tue, Wed, Thu, Fri, Sat 139425bb815Sopenharmony_ci * See also: 140425bb815Sopenharmony_ci * ECMA-262 v9, 20.3.4.41.2 Table 46 141425bb815Sopenharmony_ci * 142425bb815Sopenharmony_ci * @return true if the string starts with a valid day name, false otherwise 143425bb815Sopenharmony_ci */ 144425bb815Sopenharmony_cistatic bool 145425bb815Sopenharmony_ciecma_date_parse_day_name (const lit_utf8_byte_t **str_p, /**< pointer to the cesu8 string */ 146425bb815Sopenharmony_ci const lit_utf8_byte_t *str_end_p) /**< pointer to the end of the string */ 147425bb815Sopenharmony_ci{ 148425bb815Sopenharmony_ci if (*str_p + 3 < str_end_p) 149425bb815Sopenharmony_ci { 150425bb815Sopenharmony_ci for (uint32_t i = 0; i < 7; i++) 151425bb815Sopenharmony_ci { 152425bb815Sopenharmony_ci if (!memcmp (day_names_p[i], *str_p, 3)) 153425bb815Sopenharmony_ci { 154425bb815Sopenharmony_ci (*str_p) += 3; 155425bb815Sopenharmony_ci return true; 156425bb815Sopenharmony_ci } 157425bb815Sopenharmony_ci } 158425bb815Sopenharmony_ci } 159425bb815Sopenharmony_ci return false; 160425bb815Sopenharmony_ci} /* ecma_date_parse_day_name */ 161425bb815Sopenharmony_ci 162425bb815Sopenharmony_ci/** 163425bb815Sopenharmony_ci * Helper function to try to parse a month name in a date string 164425bb815Sopenharmony_ci * Valid month names: Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec 165425bb815Sopenharmony_ci * See also: 166425bb815Sopenharmony_ci * ECMA-262 v9, 20.3.4.41.2 Table 47 167425bb815Sopenharmony_ci * 168425bb815Sopenharmony_ci * @return number of the month if the string starts with a valid month name, 0 otherwise 169425bb815Sopenharmony_ci */ 170425bb815Sopenharmony_cistatic uint32_t 171425bb815Sopenharmony_ciecma_date_parse_month_name (const lit_utf8_byte_t **str_p, /**< pointer to the cesu8 string */ 172425bb815Sopenharmony_ci const lit_utf8_byte_t *str_end_p) /**< pointer to the end of the string */ 173425bb815Sopenharmony_ci{ 174425bb815Sopenharmony_ci if (*str_p + 3 < str_end_p) 175425bb815Sopenharmony_ci { 176425bb815Sopenharmony_ci for (uint32_t i = 0; i < 12; i++) 177425bb815Sopenharmony_ci { 178425bb815Sopenharmony_ci if (!memcmp (month_names_p[i], *str_p, 3)) 179425bb815Sopenharmony_ci { 180425bb815Sopenharmony_ci (*str_p) += 3; 181425bb815Sopenharmony_ci return (i+1); 182425bb815Sopenharmony_ci } 183425bb815Sopenharmony_ci } 184425bb815Sopenharmony_ci } 185425bb815Sopenharmony_ci return 0; 186425bb815Sopenharmony_ci} /* ecma_date_parse_month_name */ 187425bb815Sopenharmony_ci 188425bb815Sopenharmony_ci/** 189425bb815Sopenharmony_ci * Calculate MakeDate(MakeDay(yr, m, dt), MakeTime(h, min, s, milli)) for Date constructor and UTC 190425bb815Sopenharmony_ci * 191425bb815Sopenharmony_ci * See also: 192425bb815Sopenharmony_ci * ECMA-262 v5, 15.9.3.1 193425bb815Sopenharmony_ci * ECMA-262 v5, 15.9.4.3 194425bb815Sopenharmony_ci * 195425bb815Sopenharmony_ci * @return result of MakeDate(MakeDay(yr, m, dt), MakeTime(h, min, s, milli)) 196425bb815Sopenharmony_ci */ 197425bb815Sopenharmony_cistatic ecma_value_t 198425bb815Sopenharmony_ciecma_date_construct_helper (const ecma_value_t *args, /**< arguments passed to the Date constructor */ 199425bb815Sopenharmony_ci ecma_length_t args_len) /**< number of arguments */ 200425bb815Sopenharmony_ci{ 201425bb815Sopenharmony_ci ecma_value_t ret_value = ECMA_VALUE_EMPTY; 202425bb815Sopenharmony_ci ecma_number_t prim_value = ecma_number_make_nan (); 203425bb815Sopenharmony_ci 204425bb815Sopenharmony_ci ECMA_TRY_CATCH (year_value, ecma_op_to_number (args[0]), ret_value); 205425bb815Sopenharmony_ci ECMA_TRY_CATCH (month_value, ecma_op_to_number (args[1]), ret_value); 206425bb815Sopenharmony_ci 207425bb815Sopenharmony_ci ecma_number_t year = ecma_get_number_from_value (year_value); 208425bb815Sopenharmony_ci ecma_number_t month = ecma_get_number_from_value (month_value); 209425bb815Sopenharmony_ci ecma_number_t date = ECMA_NUMBER_ONE; 210425bb815Sopenharmony_ci ecma_number_t hours = ECMA_NUMBER_ZERO; 211425bb815Sopenharmony_ci ecma_number_t minutes = ECMA_NUMBER_ZERO; 212425bb815Sopenharmony_ci ecma_number_t seconds = ECMA_NUMBER_ZERO; 213425bb815Sopenharmony_ci ecma_number_t milliseconds = ECMA_NUMBER_ZERO; 214425bb815Sopenharmony_ci 215425bb815Sopenharmony_ci /* 3. */ 216425bb815Sopenharmony_ci if (args_len >= 3 && ecma_is_value_empty (ret_value)) 217425bb815Sopenharmony_ci { 218425bb815Sopenharmony_ci ECMA_TRY_CATCH (date_value, ecma_op_to_number (args[2]), ret_value); 219425bb815Sopenharmony_ci date = ecma_get_number_from_value (date_value); 220425bb815Sopenharmony_ci ECMA_FINALIZE (date_value); 221425bb815Sopenharmony_ci } 222425bb815Sopenharmony_ci 223425bb815Sopenharmony_ci /* 4. */ 224425bb815Sopenharmony_ci if (args_len >= 4 && ecma_is_value_empty (ret_value)) 225425bb815Sopenharmony_ci { 226425bb815Sopenharmony_ci ECMA_TRY_CATCH (hours_value, ecma_op_to_number (args[3]), ret_value); 227425bb815Sopenharmony_ci hours = ecma_get_number_from_value (hours_value); 228425bb815Sopenharmony_ci ECMA_FINALIZE (hours_value); 229425bb815Sopenharmony_ci } 230425bb815Sopenharmony_ci 231425bb815Sopenharmony_ci /* 5. */ 232425bb815Sopenharmony_ci if (args_len >= 5 && ecma_is_value_empty (ret_value)) 233425bb815Sopenharmony_ci { 234425bb815Sopenharmony_ci ECMA_TRY_CATCH (minutes_value, ecma_op_to_number (args[4]), ret_value); 235425bb815Sopenharmony_ci minutes = ecma_get_number_from_value (minutes_value); 236425bb815Sopenharmony_ci ECMA_FINALIZE (minutes_value); 237425bb815Sopenharmony_ci } 238425bb815Sopenharmony_ci 239425bb815Sopenharmony_ci /* 6. */ 240425bb815Sopenharmony_ci if (args_len >= 6 && ecma_is_value_empty (ret_value)) 241425bb815Sopenharmony_ci { 242425bb815Sopenharmony_ci ECMA_TRY_CATCH (seconds_value, ecma_op_to_number (args[5]), ret_value); 243425bb815Sopenharmony_ci seconds = ecma_get_number_from_value (seconds_value); 244425bb815Sopenharmony_ci ECMA_FINALIZE (seconds_value); 245425bb815Sopenharmony_ci } 246425bb815Sopenharmony_ci 247425bb815Sopenharmony_ci /* 7. */ 248425bb815Sopenharmony_ci if (args_len >= 7 && ecma_is_value_empty (ret_value)) 249425bb815Sopenharmony_ci { 250425bb815Sopenharmony_ci ECMA_TRY_CATCH (milliseconds_value, ecma_op_to_number (args[6]), ret_value); 251425bb815Sopenharmony_ci milliseconds = ecma_get_number_from_value (milliseconds_value); 252425bb815Sopenharmony_ci ECMA_FINALIZE (milliseconds_value); 253425bb815Sopenharmony_ci } 254425bb815Sopenharmony_ci 255425bb815Sopenharmony_ci if (ecma_is_value_empty (ret_value)) 256425bb815Sopenharmony_ci { 257425bb815Sopenharmony_ci if (!ecma_number_is_nan (year)) 258425bb815Sopenharmony_ci { 259425bb815Sopenharmony_ci /* 8. */ 260425bb815Sopenharmony_ci ecma_number_t y = ecma_number_trunc (year); 261425bb815Sopenharmony_ci 262425bb815Sopenharmony_ci if (y >= 0 && y <= 99) 263425bb815Sopenharmony_ci { 264425bb815Sopenharmony_ci year = 1900 + y; 265425bb815Sopenharmony_ci } 266425bb815Sopenharmony_ci } 267425bb815Sopenharmony_ci 268425bb815Sopenharmony_ci prim_value = ecma_date_make_date (ecma_date_make_day (year, 269425bb815Sopenharmony_ci month, 270425bb815Sopenharmony_ci date), 271425bb815Sopenharmony_ci ecma_date_make_time (hours, 272425bb815Sopenharmony_ci minutes, 273425bb815Sopenharmony_ci seconds, 274425bb815Sopenharmony_ci milliseconds)); 275425bb815Sopenharmony_ci } 276425bb815Sopenharmony_ci 277425bb815Sopenharmony_ci ECMA_FINALIZE (month_value); 278425bb815Sopenharmony_ci ECMA_FINALIZE (year_value); 279425bb815Sopenharmony_ci 280425bb815Sopenharmony_ci if (ecma_is_value_empty (ret_value)) 281425bb815Sopenharmony_ci { 282425bb815Sopenharmony_ci ret_value = ecma_make_number_value (prim_value); 283425bb815Sopenharmony_ci } 284425bb815Sopenharmony_ci 285425bb815Sopenharmony_ci return ret_value; 286425bb815Sopenharmony_ci} /* ecma_date_construct_helper */ 287425bb815Sopenharmony_ci 288425bb815Sopenharmony_ci/** 289425bb815Sopenharmony_ci * Helper function used by ecma_builtin_date_parse 290425bb815Sopenharmony_ci * 291425bb815Sopenharmony_ci * See also: 292425bb815Sopenharmony_ci * ECMA-262 v5, 15.9.4.2 Date.parse (string) 293425bb815Sopenharmony_ci * ECMA-262 v5, 15.9.1.15 Date Time String Format 294425bb815Sopenharmony_ci * 295425bb815Sopenharmony_ci * @return the parsed date as ecma_number_t or NaN otherwise 296425bb815Sopenharmony_ci */ 297425bb815Sopenharmony_cistatic ecma_number_t 298425bb815Sopenharmony_ciecma_builtin_date_parse_ISO_string_format (const lit_utf8_byte_t *date_str_curr_p, 299425bb815Sopenharmony_ci const lit_utf8_byte_t *date_str_end_p) 300425bb815Sopenharmony_ci{ 301425bb815Sopenharmony_ci /* 1. read year */ 302425bb815Sopenharmony_ci 303425bb815Sopenharmony_ci uint32_t year_digits = 4; 304425bb815Sopenharmony_ci 305425bb815Sopenharmony_ci bool is_year_sign_negative = ecma_date_parse_special_char (&date_str_curr_p, date_str_end_p, '-'); 306425bb815Sopenharmony_ci if (is_year_sign_negative || ecma_date_parse_special_char (&date_str_curr_p, date_str_end_p, '+')) 307425bb815Sopenharmony_ci { 308425bb815Sopenharmony_ci year_digits = 6; 309425bb815Sopenharmony_ci } 310425bb815Sopenharmony_ci 311425bb815Sopenharmony_ci ecma_number_t year = ecma_date_parse_date_chars (&date_str_curr_p, date_str_end_p, year_digits, 312425bb815Sopenharmony_ci 0, (year_digits == 4) ? 9999 : 999999); 313425bb815Sopenharmony_ci if (is_year_sign_negative) 314425bb815Sopenharmony_ci { 315425bb815Sopenharmony_ci year = -year; 316425bb815Sopenharmony_ci } 317425bb815Sopenharmony_ci 318425bb815Sopenharmony_ci if (!ecma_number_is_nan (year)) 319425bb815Sopenharmony_ci { 320425bb815Sopenharmony_ci ecma_number_t month = ECMA_NUMBER_ONE; 321425bb815Sopenharmony_ci ecma_number_t day = ECMA_NUMBER_ONE; 322425bb815Sopenharmony_ci ecma_number_t time = ECMA_NUMBER_ZERO; 323425bb815Sopenharmony_ci 324425bb815Sopenharmony_ci /* 2. read month if any */ 325425bb815Sopenharmony_ci if (ecma_date_parse_special_char (&date_str_curr_p, date_str_end_p, '-')) 326425bb815Sopenharmony_ci { 327425bb815Sopenharmony_ci month = ecma_date_parse_date_chars (&date_str_curr_p, date_str_end_p, 2, 1, 12); 328425bb815Sopenharmony_ci } 329425bb815Sopenharmony_ci 330425bb815Sopenharmony_ci /* 3. read day if any */ 331425bb815Sopenharmony_ci if (ecma_date_parse_special_char (&date_str_curr_p, date_str_end_p, '-')) 332425bb815Sopenharmony_ci { 333425bb815Sopenharmony_ci day = ecma_date_parse_date_chars (&date_str_curr_p, date_str_end_p, 2, 1, 31); 334425bb815Sopenharmony_ci } 335425bb815Sopenharmony_ci 336425bb815Sopenharmony_ci /* 4. read time if any */ 337425bb815Sopenharmony_ci if (ecma_date_parse_special_char (&date_str_curr_p, date_str_end_p, 'T')) 338425bb815Sopenharmony_ci { 339425bb815Sopenharmony_ci ecma_number_t hours = ECMA_NUMBER_ZERO; 340425bb815Sopenharmony_ci ecma_number_t minutes = ECMA_NUMBER_ZERO; 341425bb815Sopenharmony_ci ecma_number_t seconds = ECMA_NUMBER_ZERO; 342425bb815Sopenharmony_ci ecma_number_t milliseconds = ECMA_NUMBER_ZERO; 343425bb815Sopenharmony_ci 344425bb815Sopenharmony_ci ecma_length_t remaining_length = lit_utf8_string_length (date_str_curr_p, 345425bb815Sopenharmony_ci (lit_utf8_size_t) (date_str_end_p - date_str_curr_p)); 346425bb815Sopenharmony_ci 347425bb815Sopenharmony_ci if (remaining_length >= 5) 348425bb815Sopenharmony_ci { 349425bb815Sopenharmony_ci /* 4.1 read hours and minutes */ 350425bb815Sopenharmony_ci hours = ecma_date_parse_date_chars (&date_str_curr_p, date_str_end_p, 2, 0, 24); 351425bb815Sopenharmony_ci 352425bb815Sopenharmony_ci if (ecma_date_parse_special_char (&date_str_curr_p, date_str_end_p, ':')) 353425bb815Sopenharmony_ci { 354425bb815Sopenharmony_ci minutes = ecma_date_parse_date_chars (&date_str_curr_p, date_str_end_p, 2, 0, 59); 355425bb815Sopenharmony_ci 356425bb815Sopenharmony_ci /* 4.2 read seconds if any */ 357425bb815Sopenharmony_ci if (ecma_date_parse_special_char (&date_str_curr_p, date_str_end_p, ':')) 358425bb815Sopenharmony_ci { 359425bb815Sopenharmony_ci seconds = ecma_date_parse_date_chars (&date_str_curr_p, date_str_end_p, 2, 0, 59); 360425bb815Sopenharmony_ci 361425bb815Sopenharmony_ci /* 4.3 read milliseconds if any */ 362425bb815Sopenharmony_ci if (ecma_date_parse_special_char (&date_str_curr_p, date_str_end_p, '.')) 363425bb815Sopenharmony_ci { 364425bb815Sopenharmony_ci milliseconds = ecma_date_parse_date_chars (&date_str_curr_p, date_str_end_p, 3, 0, 999); 365425bb815Sopenharmony_ci } 366425bb815Sopenharmony_ci } 367425bb815Sopenharmony_ci } 368425bb815Sopenharmony_ci else 369425bb815Sopenharmony_ci { 370425bb815Sopenharmony_ci minutes = ecma_number_make_nan (); 371425bb815Sopenharmony_ci } 372425bb815Sopenharmony_ci 373425bb815Sopenharmony_ci if (hours == 24 && (minutes != 0 || seconds != 0 || milliseconds != 0)) 374425bb815Sopenharmony_ci { 375425bb815Sopenharmony_ci hours = ecma_number_make_nan (); 376425bb815Sopenharmony_ci } 377425bb815Sopenharmony_ci 378425bb815Sopenharmony_ci time = ecma_date_make_time (hours, minutes, seconds, milliseconds); 379425bb815Sopenharmony_ci } 380425bb815Sopenharmony_ci else 381425bb815Sopenharmony_ci { 382425bb815Sopenharmony_ci time = ecma_number_make_nan (); 383425bb815Sopenharmony_ci } 384425bb815Sopenharmony_ci 385425bb815Sopenharmony_ci /* 4.4 read timezone if any */ 386425bb815Sopenharmony_ci if (ecma_date_parse_special_char (&date_str_curr_p, date_str_end_p, 'Z') && !ecma_number_is_nan (time)) 387425bb815Sopenharmony_ci { 388425bb815Sopenharmony_ci time = ecma_date_make_time (hours, minutes, seconds, milliseconds); 389425bb815Sopenharmony_ci } 390425bb815Sopenharmony_ci else 391425bb815Sopenharmony_ci { 392425bb815Sopenharmony_ci bool is_timezone_sign_negative; 393425bb815Sopenharmony_ci if ((lit_utf8_string_length (date_str_curr_p, (lit_utf8_size_t) (date_str_end_p - date_str_curr_p)) == 6) 394425bb815Sopenharmony_ci && ((is_timezone_sign_negative = ecma_date_parse_special_char (&date_str_curr_p, date_str_end_p, '-')) 395425bb815Sopenharmony_ci || ecma_date_parse_special_char (&date_str_curr_p, date_str_end_p, '+'))) 396425bb815Sopenharmony_ci { 397425bb815Sopenharmony_ci /* read hours and minutes */ 398425bb815Sopenharmony_ci hours = ecma_date_parse_date_chars (&date_str_curr_p, date_str_end_p, 2, 0, 24); 399425bb815Sopenharmony_ci 400425bb815Sopenharmony_ci if (hours == 24) 401425bb815Sopenharmony_ci { 402425bb815Sopenharmony_ci hours = ECMA_NUMBER_ZERO; 403425bb815Sopenharmony_ci } 404425bb815Sopenharmony_ci 405425bb815Sopenharmony_ci ecma_date_parse_special_char (&date_str_curr_p, date_str_end_p, ':'); 406425bb815Sopenharmony_ci minutes = ecma_date_parse_date_chars (&date_str_curr_p, date_str_end_p, 2, 0, 59); 407425bb815Sopenharmony_ci ecma_number_t timezone_offset = ecma_date_make_time (hours, minutes, ECMA_NUMBER_ZERO, ECMA_NUMBER_ZERO); 408425bb815Sopenharmony_ci time += is_timezone_sign_negative ? timezone_offset : -timezone_offset; 409425bb815Sopenharmony_ci } 410425bb815Sopenharmony_ci } 411425bb815Sopenharmony_ci } 412425bb815Sopenharmony_ci 413425bb815Sopenharmony_ci if (date_str_curr_p >= date_str_end_p) 414425bb815Sopenharmony_ci { 415425bb815Sopenharmony_ci ecma_number_t date = ecma_date_make_day (year, month - 1, day); 416425bb815Sopenharmony_ci return ecma_date_make_date (date, time); 417425bb815Sopenharmony_ci } 418425bb815Sopenharmony_ci } 419425bb815Sopenharmony_ci return ecma_number_make_nan (); 420425bb815Sopenharmony_ci} /* ecma_builtin_date_parse_ISO_string_format */ 421425bb815Sopenharmony_ci 422425bb815Sopenharmony_ci/** 423425bb815Sopenharmony_ci * Helper function used by ecma_builtin_date_parse 424425bb815Sopenharmony_ci * 425425bb815Sopenharmony_ci * See also: 426425bb815Sopenharmony_ci * ECMA-262 v5, 15.9.4.2 Date.parse (string) 427425bb815Sopenharmony_ci * ECMA-262 v9, 20.3.4.41 Date.prototype.toString () 428425bb815Sopenharmony_ci * ECMA-262 v9, 20.3.4.43 Date.prototype.toUTCString () 429425bb815Sopenharmony_ci * 430425bb815Sopenharmony_ci * Used by: ecma_builtin_date_parse 431425bb815Sopenharmony_ci * 432425bb815Sopenharmony_ci * @return the parsed date as ecma_number_t or NaN otherwise 433425bb815Sopenharmony_ci */ 434425bb815Sopenharmony_cistatic ecma_number_t 435425bb815Sopenharmony_ciecma_builtin_date_parse_toString_formats (const lit_utf8_byte_t *date_str_curr_p, 436425bb815Sopenharmony_ci const lit_utf8_byte_t *date_str_end_p) 437425bb815Sopenharmony_ci{ 438425bb815Sopenharmony_ci const ecma_number_t nan = ecma_number_make_nan (); 439425bb815Sopenharmony_ci 440425bb815Sopenharmony_ci if (!ecma_date_parse_day_name (&date_str_curr_p, date_str_end_p)) 441425bb815Sopenharmony_ci { 442425bb815Sopenharmony_ci return nan; 443425bb815Sopenharmony_ci } 444425bb815Sopenharmony_ci 445425bb815Sopenharmony_ci const bool is_toUTCString_format = ecma_date_parse_special_char (&date_str_curr_p, date_str_end_p, ','); 446425bb815Sopenharmony_ci 447425bb815Sopenharmony_ci if (!ecma_date_parse_special_char (&date_str_curr_p, date_str_end_p, ' ')) 448425bb815Sopenharmony_ci { 449425bb815Sopenharmony_ci return nan; 450425bb815Sopenharmony_ci } 451425bb815Sopenharmony_ci 452425bb815Sopenharmony_ci ecma_number_t month = 0; 453425bb815Sopenharmony_ci ecma_number_t day = 0; 454425bb815Sopenharmony_ci if (is_toUTCString_format) 455425bb815Sopenharmony_ci { 456425bb815Sopenharmony_ci day = ecma_date_parse_date_chars (&date_str_curr_p, date_str_end_p, 2, 0, 31); 457425bb815Sopenharmony_ci if (ecma_number_is_nan (day)) 458425bb815Sopenharmony_ci { 459425bb815Sopenharmony_ci return nan; 460425bb815Sopenharmony_ci } 461425bb815Sopenharmony_ci 462425bb815Sopenharmony_ci if (!ecma_date_parse_special_char (&date_str_curr_p, date_str_end_p, ' ')) 463425bb815Sopenharmony_ci { 464425bb815Sopenharmony_ci return nan; 465425bb815Sopenharmony_ci } 466425bb815Sopenharmony_ci 467425bb815Sopenharmony_ci month = ecma_date_parse_month_name (&date_str_curr_p, date_str_end_p); 468425bb815Sopenharmony_ci if (!(int) month) 469425bb815Sopenharmony_ci { 470425bb815Sopenharmony_ci return nan; 471425bb815Sopenharmony_ci } 472425bb815Sopenharmony_ci } 473425bb815Sopenharmony_ci else 474425bb815Sopenharmony_ci { 475425bb815Sopenharmony_ci month = ecma_date_parse_month_name (&date_str_curr_p, date_str_end_p); 476425bb815Sopenharmony_ci if (!(int) month) 477425bb815Sopenharmony_ci { 478425bb815Sopenharmony_ci return nan; 479425bb815Sopenharmony_ci } 480425bb815Sopenharmony_ci 481425bb815Sopenharmony_ci if (!ecma_date_parse_special_char (&date_str_curr_p, date_str_end_p, ' ')) 482425bb815Sopenharmony_ci { 483425bb815Sopenharmony_ci return nan; 484425bb815Sopenharmony_ci } 485425bb815Sopenharmony_ci 486425bb815Sopenharmony_ci day = ecma_date_parse_date_chars (&date_str_curr_p, date_str_end_p, 2, 0, 31); 487425bb815Sopenharmony_ci if (ecma_number_is_nan (day)) 488425bb815Sopenharmony_ci { 489425bb815Sopenharmony_ci return nan; 490425bb815Sopenharmony_ci } 491425bb815Sopenharmony_ci } 492425bb815Sopenharmony_ci 493425bb815Sopenharmony_ci if (!ecma_date_parse_special_char (&date_str_curr_p, date_str_end_p, ' ')) 494425bb815Sopenharmony_ci { 495425bb815Sopenharmony_ci return nan; 496425bb815Sopenharmony_ci } 497425bb815Sopenharmony_ci 498425bb815Sopenharmony_ci ecma_number_t year = ecma_date_parse_year (&date_str_curr_p, date_str_end_p); 499425bb815Sopenharmony_ci if (ecma_number_is_nan (year)) 500425bb815Sopenharmony_ci { 501425bb815Sopenharmony_ci return nan; 502425bb815Sopenharmony_ci } 503425bb815Sopenharmony_ci 504425bb815Sopenharmony_ci if (!ecma_date_parse_special_char (&date_str_curr_p, date_str_end_p, ' ')) 505425bb815Sopenharmony_ci { 506425bb815Sopenharmony_ci return nan; 507425bb815Sopenharmony_ci } 508425bb815Sopenharmony_ci 509425bb815Sopenharmony_ci ecma_number_t hours = ecma_date_parse_date_chars (&date_str_curr_p, date_str_end_p, 2, 0, 24); 510425bb815Sopenharmony_ci if (ecma_number_is_nan (hours)) 511425bb815Sopenharmony_ci { 512425bb815Sopenharmony_ci return nan; 513425bb815Sopenharmony_ci } 514425bb815Sopenharmony_ci 515425bb815Sopenharmony_ci if (!ecma_date_parse_special_char (&date_str_curr_p, date_str_end_p, ':')) 516425bb815Sopenharmony_ci { 517425bb815Sopenharmony_ci return nan; 518425bb815Sopenharmony_ci } 519425bb815Sopenharmony_ci 520425bb815Sopenharmony_ci ecma_number_t minutes = ecma_date_parse_date_chars (&date_str_curr_p, date_str_end_p, 2, 0, 59); 521425bb815Sopenharmony_ci if (ecma_number_is_nan (minutes)) 522425bb815Sopenharmony_ci { 523425bb815Sopenharmony_ci return nan; 524425bb815Sopenharmony_ci } 525425bb815Sopenharmony_ci 526425bb815Sopenharmony_ci if (!ecma_date_parse_special_char (&date_str_curr_p, date_str_end_p, ':')) 527425bb815Sopenharmony_ci { 528425bb815Sopenharmony_ci return nan; 529425bb815Sopenharmony_ci } 530425bb815Sopenharmony_ci 531425bb815Sopenharmony_ci ecma_number_t seconds = ecma_date_parse_date_chars (&date_str_curr_p, date_str_end_p, 2, 0, 59); 532425bb815Sopenharmony_ci if (ecma_number_is_nan (seconds)) 533425bb815Sopenharmony_ci { 534425bb815Sopenharmony_ci return nan; 535425bb815Sopenharmony_ci } 536425bb815Sopenharmony_ci 537425bb815Sopenharmony_ci if (hours == 24 && (minutes != 0 || seconds != 0)) 538425bb815Sopenharmony_ci { 539425bb815Sopenharmony_ci return nan; 540425bb815Sopenharmony_ci } 541425bb815Sopenharmony_ci 542425bb815Sopenharmony_ci if (!ecma_date_parse_special_char (&date_str_curr_p, date_str_end_p, ' ')) 543425bb815Sopenharmony_ci { 544425bb815Sopenharmony_ci return nan; 545425bb815Sopenharmony_ci } 546425bb815Sopenharmony_ci 547425bb815Sopenharmony_ci if (!ecma_date_parse_special_char (&date_str_curr_p, date_str_end_p, 'G')) 548425bb815Sopenharmony_ci { 549425bb815Sopenharmony_ci return nan; 550425bb815Sopenharmony_ci } 551425bb815Sopenharmony_ci 552425bb815Sopenharmony_ci if (!ecma_date_parse_special_char (&date_str_curr_p, date_str_end_p, 'M')) 553425bb815Sopenharmony_ci { 554425bb815Sopenharmony_ci return nan; 555425bb815Sopenharmony_ci } 556425bb815Sopenharmony_ci 557425bb815Sopenharmony_ci if (!ecma_date_parse_special_char (&date_str_curr_p, date_str_end_p, 'T')) 558425bb815Sopenharmony_ci { 559425bb815Sopenharmony_ci return nan; 560425bb815Sopenharmony_ci } 561425bb815Sopenharmony_ci 562425bb815Sopenharmony_ci ecma_number_t time = ecma_date_make_time (hours, minutes, seconds, 0); 563425bb815Sopenharmony_ci 564425bb815Sopenharmony_ci if (!is_toUTCString_format) 565425bb815Sopenharmony_ci { 566425bb815Sopenharmony_ci bool is_timezone_sign_negative = ecma_date_parse_special_char (&date_str_curr_p, date_str_end_p, '-'); 567425bb815Sopenharmony_ci if (!is_timezone_sign_negative && !ecma_date_parse_special_char (&date_str_curr_p, date_str_end_p, '+')) 568425bb815Sopenharmony_ci { 569425bb815Sopenharmony_ci return nan; 570425bb815Sopenharmony_ci } 571425bb815Sopenharmony_ci 572425bb815Sopenharmony_ci hours = ecma_date_parse_date_chars (&date_str_curr_p, date_str_end_p, 2, 0, 24); 573425bb815Sopenharmony_ci if (ecma_number_is_nan (hours)) 574425bb815Sopenharmony_ci { 575425bb815Sopenharmony_ci return nan; 576425bb815Sopenharmony_ci } 577425bb815Sopenharmony_ci if (hours == 24) 578425bb815Sopenharmony_ci { 579425bb815Sopenharmony_ci hours = ECMA_NUMBER_ZERO; 580425bb815Sopenharmony_ci } 581425bb815Sopenharmony_ci 582425bb815Sopenharmony_ci minutes = ecma_date_parse_date_chars (&date_str_curr_p, date_str_end_p, 2, 0, 59); 583425bb815Sopenharmony_ci if (ecma_number_is_nan (minutes)) 584425bb815Sopenharmony_ci { 585425bb815Sopenharmony_ci return nan; 586425bb815Sopenharmony_ci } 587425bb815Sopenharmony_ci 588425bb815Sopenharmony_ci ecma_number_t timezone_offset = ecma_date_make_time (hours, minutes, ECMA_NUMBER_ZERO, ECMA_NUMBER_ZERO); 589425bb815Sopenharmony_ci time += is_timezone_sign_negative ? timezone_offset : -timezone_offset; 590425bb815Sopenharmony_ci } 591425bb815Sopenharmony_ci 592425bb815Sopenharmony_ci if (date_str_curr_p >= date_str_end_p) 593425bb815Sopenharmony_ci { 594425bb815Sopenharmony_ci ecma_number_t date = ecma_date_make_day (year, month - 1, day); 595425bb815Sopenharmony_ci return ecma_date_make_date (date, time); 596425bb815Sopenharmony_ci } 597425bb815Sopenharmony_ci 598425bb815Sopenharmony_ci return nan; 599425bb815Sopenharmony_ci} /* ecma_builtin_date_parse_toString_formats */ 600425bb815Sopenharmony_ci 601425bb815Sopenharmony_ci/** 602425bb815Sopenharmony_ci * The Date object's 'parse' routine 603425bb815Sopenharmony_ci * 604425bb815Sopenharmony_ci * See also: 605425bb815Sopenharmony_ci * ECMA-262 v5, 15.9.4.2 Date.parse (string) 606425bb815Sopenharmony_ci * ECMA-262 v5, 15.9.1.15 Date Time String Format 607425bb815Sopenharmony_ci * ECMA-262 v9, 20.3.4.41 Date.prototype.toString () 608425bb815Sopenharmony_ci * ECMA-262 v9, 20.3.4.43 Date.prototype.toUTCString () 609425bb815Sopenharmony_ci * 610425bb815Sopenharmony_ci * @return ecma value 611425bb815Sopenharmony_ci * Returned value must be freed with ecma_free_value. 612425bb815Sopenharmony_ci */ 613425bb815Sopenharmony_cistatic ecma_value_t 614425bb815Sopenharmony_ciecma_builtin_date_parse (ecma_value_t this_arg, /**< this argument */ 615425bb815Sopenharmony_ci ecma_value_t arg) /**< string */ 616425bb815Sopenharmony_ci{ 617425bb815Sopenharmony_ci JERRY_UNUSED (this_arg); 618425bb815Sopenharmony_ci 619425bb815Sopenharmony_ci /* Date Time String fromat (ECMA-262 v5, 15.9.1.15) */ 620425bb815Sopenharmony_ci ecma_string_t *date_str_p = ecma_op_to_string (arg); 621425bb815Sopenharmony_ci if (JERRY_UNLIKELY (date_str_p == NULL)) 622425bb815Sopenharmony_ci { 623425bb815Sopenharmony_ci return ECMA_VALUE_ERROR; 624425bb815Sopenharmony_ci } 625425bb815Sopenharmony_ci 626425bb815Sopenharmony_ci ECMA_STRING_TO_UTF8_STRING (date_str_p, date_start_p, date_start_size); 627425bb815Sopenharmony_ci const lit_utf8_byte_t *date_str_curr_p = date_start_p; 628425bb815Sopenharmony_ci const lit_utf8_byte_t *date_str_end_p = date_start_p + date_start_size; 629425bb815Sopenharmony_ci 630425bb815Sopenharmony_ci // try to parse date string as ISO string - ECMA-262 v5, 15.9.1.15 631425bb815Sopenharmony_ci ecma_number_t ret_value = ecma_builtin_date_parse_ISO_string_format (date_str_curr_p, date_str_end_p); 632425bb815Sopenharmony_ci 633425bb815Sopenharmony_ci if (ecma_number_is_nan (ret_value)) 634425bb815Sopenharmony_ci { 635425bb815Sopenharmony_ci // try to parse date string in Date.prototype.toString() or toUTCString() format 636425bb815Sopenharmony_ci ret_value = ecma_builtin_date_parse_toString_formats (date_str_curr_p, date_str_end_p); 637425bb815Sopenharmony_ci } 638425bb815Sopenharmony_ci 639425bb815Sopenharmony_ci ECMA_FINALIZE_UTF8_STRING (date_start_p, date_start_size); 640425bb815Sopenharmony_ci ecma_deref_ecma_string (date_str_p); 641425bb815Sopenharmony_ci return ecma_make_number_value (ret_value); 642425bb815Sopenharmony_ci} /* ecma_builtin_date_parse */ 643425bb815Sopenharmony_ci 644425bb815Sopenharmony_ci/** 645425bb815Sopenharmony_ci * The Date object's 'UTC' routine 646425bb815Sopenharmony_ci * 647425bb815Sopenharmony_ci * See also: 648425bb815Sopenharmony_ci * ECMA-262 v5, 15.9.4.3 649425bb815Sopenharmony_ci * 650425bb815Sopenharmony_ci * @return ecma value 651425bb815Sopenharmony_ci * Returned value must be freed with ecma_free_value. 652425bb815Sopenharmony_ci */ 653425bb815Sopenharmony_cistatic ecma_value_t 654425bb815Sopenharmony_ciecma_builtin_date_utc (ecma_value_t this_arg, /**< this argument */ 655425bb815Sopenharmony_ci const ecma_value_t args[], /**< arguments list */ 656425bb815Sopenharmony_ci ecma_length_t args_number) /**< number of arguments */ 657425bb815Sopenharmony_ci{ 658425bb815Sopenharmony_ci JERRY_UNUSED (this_arg); 659425bb815Sopenharmony_ci ecma_value_t ret_value = ECMA_VALUE_EMPTY; 660425bb815Sopenharmony_ci 661425bb815Sopenharmony_ci if (args_number < 2) 662425bb815Sopenharmony_ci { 663425bb815Sopenharmony_ci /* Note: 664425bb815Sopenharmony_ci * When the UTC function is called with fewer than two arguments, 665425bb815Sopenharmony_ci * the behaviour is implementation-dependent, so just return NaN. 666425bb815Sopenharmony_ci */ 667425bb815Sopenharmony_ci return ecma_make_number_value (ecma_number_make_nan ()); 668425bb815Sopenharmony_ci } 669425bb815Sopenharmony_ci 670425bb815Sopenharmony_ci ECMA_TRY_CATCH (time_value, ecma_date_construct_helper (args, args_number), ret_value); 671425bb815Sopenharmony_ci 672425bb815Sopenharmony_ci ecma_number_t time = ecma_get_number_from_value (time_value); 673425bb815Sopenharmony_ci ret_value = ecma_make_number_value (ecma_date_time_clip (time)); 674425bb815Sopenharmony_ci 675425bb815Sopenharmony_ci ECMA_FINALIZE (time_value); 676425bb815Sopenharmony_ci 677425bb815Sopenharmony_ci return ret_value; 678425bb815Sopenharmony_ci} /* ecma_builtin_date_utc */ 679425bb815Sopenharmony_ci 680425bb815Sopenharmony_ci/** 681425bb815Sopenharmony_ci * The Date object's 'now' routine 682425bb815Sopenharmony_ci * 683425bb815Sopenharmony_ci * See also: 684425bb815Sopenharmony_ci * ECMA-262 v5, 15.9.4.4 685425bb815Sopenharmony_ci * 686425bb815Sopenharmony_ci * @return ecma value 687425bb815Sopenharmony_ci * Returned value must be freed with ecma_free_value. 688425bb815Sopenharmony_ci */ 689425bb815Sopenharmony_cistatic ecma_value_t 690425bb815Sopenharmony_ciecma_builtin_date_now (ecma_value_t this_arg) /**< this argument */ 691425bb815Sopenharmony_ci{ 692425bb815Sopenharmony_ci JERRY_UNUSED (this_arg); 693425bb815Sopenharmony_ci return ecma_make_number_value (floor (DOUBLE_TO_ECMA_NUMBER_T (jerry_port_get_current_time ()))); 694425bb815Sopenharmony_ci} /* ecma_builtin_date_now */ 695425bb815Sopenharmony_ci 696425bb815Sopenharmony_ci/** 697425bb815Sopenharmony_ci * Handle calling [[Call]] of built-in Date object 698425bb815Sopenharmony_ci * 699425bb815Sopenharmony_ci * See also: 700425bb815Sopenharmony_ci * ECMA-262 v5, 15.9.2.1 701425bb815Sopenharmony_ci * 702425bb815Sopenharmony_ci * @return ecma value 703425bb815Sopenharmony_ci */ 704425bb815Sopenharmony_ciecma_value_t 705425bb815Sopenharmony_ciecma_builtin_date_dispatch_call (const ecma_value_t *arguments_list_p, /**< arguments list */ 706425bb815Sopenharmony_ci ecma_length_t arguments_list_len) /**< number of arguments */ 707425bb815Sopenharmony_ci{ 708425bb815Sopenharmony_ci JERRY_UNUSED (arguments_list_p); 709425bb815Sopenharmony_ci JERRY_UNUSED (arguments_list_len); 710425bb815Sopenharmony_ci ecma_value_t ret_value = ECMA_VALUE_EMPTY; 711425bb815Sopenharmony_ci 712425bb815Sopenharmony_ci ECMA_TRY_CATCH (now_val, 713425bb815Sopenharmony_ci ecma_builtin_date_now (ECMA_VALUE_UNDEFINED), 714425bb815Sopenharmony_ci ret_value); 715425bb815Sopenharmony_ci 716425bb815Sopenharmony_ci ret_value = ecma_date_value_to_string (ecma_get_number_from_value (now_val)); 717425bb815Sopenharmony_ci 718425bb815Sopenharmony_ci ECMA_FINALIZE (now_val); 719425bb815Sopenharmony_ci 720425bb815Sopenharmony_ci return ret_value; 721425bb815Sopenharmony_ci} /* ecma_builtin_date_dispatch_call */ 722425bb815Sopenharmony_ci 723425bb815Sopenharmony_ci/** 724425bb815Sopenharmony_ci * Handle calling [[Construct]] of built-in Date object 725425bb815Sopenharmony_ci * 726425bb815Sopenharmony_ci * See also: 727425bb815Sopenharmony_ci * ECMA-262 v5, 15.9.3.1 728425bb815Sopenharmony_ci * 729425bb815Sopenharmony_ci * @return ecma value 730425bb815Sopenharmony_ci */ 731425bb815Sopenharmony_ciecma_value_t 732425bb815Sopenharmony_ciecma_builtin_date_dispatch_construct (const ecma_value_t *arguments_list_p, /**< arguments list */ 733425bb815Sopenharmony_ci ecma_length_t arguments_list_len) /**< number of arguments */ 734425bb815Sopenharmony_ci{ 735425bb815Sopenharmony_ci ecma_value_t ret_value = ECMA_VALUE_EMPTY; 736425bb815Sopenharmony_ci ecma_number_t prim_value_num = ECMA_NUMBER_ZERO; 737425bb815Sopenharmony_ci 738425bb815Sopenharmony_ci ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_DATE_PROTOTYPE); 739425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 740425bb815Sopenharmony_ci if (JERRY_CONTEXT (current_new_target)) 741425bb815Sopenharmony_ci { 742425bb815Sopenharmony_ci prototype_obj_p = ecma_op_get_prototype_from_constructor (JERRY_CONTEXT (current_new_target), 743425bb815Sopenharmony_ci ECMA_BUILTIN_ID_DATE_PROTOTYPE); 744425bb815Sopenharmony_ci if (JERRY_UNLIKELY (prototype_obj_p == NULL)) 745425bb815Sopenharmony_ci { 746425bb815Sopenharmony_ci return ECMA_VALUE_ERROR; 747425bb815Sopenharmony_ci } 748425bb815Sopenharmony_ci } 749425bb815Sopenharmony_ci#endif /* !(ENABLED (JERRY_ES2015) */ 750425bb815Sopenharmony_ci ecma_object_t *obj_p = ecma_create_object (prototype_obj_p, 751425bb815Sopenharmony_ci sizeof (ecma_extended_object_t), 752425bb815Sopenharmony_ci ECMA_OBJECT_TYPE_CLASS); 753425bb815Sopenharmony_ci 754425bb815Sopenharmony_ci ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) obj_p; 755425bb815Sopenharmony_ci ext_object_p->u.class_prop.class_id = LIT_MAGIC_STRING_UNDEFINED; 756425bb815Sopenharmony_ci 757425bb815Sopenharmony_ci if (arguments_list_len == 0) 758425bb815Sopenharmony_ci { 759425bb815Sopenharmony_ci ECMA_TRY_CATCH (parse_res_value, 760425bb815Sopenharmony_ci ecma_builtin_date_now (ecma_make_object_value (obj_p)), 761425bb815Sopenharmony_ci ret_value); 762425bb815Sopenharmony_ci 763425bb815Sopenharmony_ci prim_value_num = ecma_get_number_from_value (parse_res_value); 764425bb815Sopenharmony_ci 765425bb815Sopenharmony_ci ECMA_FINALIZE (parse_res_value) 766425bb815Sopenharmony_ci } 767425bb815Sopenharmony_ci else if (arguments_list_len == 1) 768425bb815Sopenharmony_ci { 769425bb815Sopenharmony_ci ECMA_TRY_CATCH (prim_comp_value, 770425bb815Sopenharmony_ci ecma_op_to_primitive (arguments_list_p[0], ECMA_PREFERRED_TYPE_NUMBER), 771425bb815Sopenharmony_ci ret_value); 772425bb815Sopenharmony_ci 773425bb815Sopenharmony_ci if (ecma_is_value_string (prim_comp_value)) 774425bb815Sopenharmony_ci { 775425bb815Sopenharmony_ci ECMA_TRY_CATCH (parse_res_value, 776425bb815Sopenharmony_ci ecma_builtin_date_parse (ecma_make_object_value (obj_p), prim_comp_value), 777425bb815Sopenharmony_ci ret_value); 778425bb815Sopenharmony_ci 779425bb815Sopenharmony_ci prim_value_num = ecma_get_number_from_value (parse_res_value); 780425bb815Sopenharmony_ci 781425bb815Sopenharmony_ci ECMA_FINALIZE (parse_res_value); 782425bb815Sopenharmony_ci } 783425bb815Sopenharmony_ci else 784425bb815Sopenharmony_ci { 785425bb815Sopenharmony_ci ECMA_TRY_CATCH (prim_value, ecma_op_to_number (arguments_list_p[0]), ret_value); 786425bb815Sopenharmony_ci 787425bb815Sopenharmony_ci prim_value_num = ecma_date_time_clip (ecma_get_number_from_value (prim_value)); 788425bb815Sopenharmony_ci 789425bb815Sopenharmony_ci ECMA_FINALIZE (prim_value); 790425bb815Sopenharmony_ci } 791425bb815Sopenharmony_ci 792425bb815Sopenharmony_ci ECMA_FINALIZE (prim_comp_value); 793425bb815Sopenharmony_ci } 794425bb815Sopenharmony_ci else 795425bb815Sopenharmony_ci { 796425bb815Sopenharmony_ci ECMA_TRY_CATCH (time_value, 797425bb815Sopenharmony_ci ecma_date_construct_helper (arguments_list_p, arguments_list_len), 798425bb815Sopenharmony_ci ret_value); 799425bb815Sopenharmony_ci 800425bb815Sopenharmony_ci ecma_number_t time = ecma_get_number_from_value (time_value); 801425bb815Sopenharmony_ci prim_value_num = ecma_date_time_clip (ecma_date_utc (time)); 802425bb815Sopenharmony_ci 803425bb815Sopenharmony_ci ECMA_FINALIZE (time_value); 804425bb815Sopenharmony_ci } 805425bb815Sopenharmony_ci 806425bb815Sopenharmony_ci if (ecma_is_value_empty (ret_value)) 807425bb815Sopenharmony_ci { 808425bb815Sopenharmony_ci if (!ecma_number_is_nan (prim_value_num) && ecma_number_is_infinity (prim_value_num)) 809425bb815Sopenharmony_ci { 810425bb815Sopenharmony_ci prim_value_num = ecma_number_make_nan (); 811425bb815Sopenharmony_ci } 812425bb815Sopenharmony_ci 813425bb815Sopenharmony_ci ext_object_p->u.class_prop.class_id = LIT_MAGIC_STRING_DATE_UL; 814425bb815Sopenharmony_ci 815425bb815Sopenharmony_ci ecma_number_t *date_num_p = ecma_alloc_number (); 816425bb815Sopenharmony_ci *date_num_p = prim_value_num; 817425bb815Sopenharmony_ci ECMA_SET_INTERNAL_VALUE_POINTER (ext_object_p->u.class_prop.u.value, date_num_p); 818425bb815Sopenharmony_ci 819425bb815Sopenharmony_ci ret_value = ecma_make_object_value (obj_p); 820425bb815Sopenharmony_ci } 821425bb815Sopenharmony_ci else 822425bb815Sopenharmony_ci { 823425bb815Sopenharmony_ci JERRY_ASSERT (ECMA_IS_VALUE_ERROR (ret_value)); 824425bb815Sopenharmony_ci ecma_deref_object (obj_p); 825425bb815Sopenharmony_ci } 826425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015) 827425bb815Sopenharmony_ci if (JERRY_CONTEXT (current_new_target)) 828425bb815Sopenharmony_ci { 829425bb815Sopenharmony_ci ecma_deref_object (prototype_obj_p); 830425bb815Sopenharmony_ci } 831425bb815Sopenharmony_ci#endif /* !(ENABLED (JERRY_ES2015) */ 832425bb815Sopenharmony_ci return ret_value; 833425bb815Sopenharmony_ci} /* ecma_builtin_date_dispatch_construct */ 834425bb815Sopenharmony_ci 835425bb815Sopenharmony_ci/** 836425bb815Sopenharmony_ci * @} 837425bb815Sopenharmony_ci * @} 838425bb815Sopenharmony_ci * @} 839425bb815Sopenharmony_ci */ 840425bb815Sopenharmony_ci 841425bb815Sopenharmony_ci#undef BREAK_IF_FALSE 842425bb815Sopenharmony_ci#undef BREAK_IF_NAN 843425bb815Sopenharmony_ci 844425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_BUILTIN_DATE) */ 845