Date toString methods follow the date format used by other JS engines:
new Date(0).toString () == "Thu Jan 01 1970 00:00:00 GMT+0000" new Date(0).toUTCString () == "Thu, 01 Jan 1970 00:00:00 GMT" new Date(0).toISOString () == "1970-01-01T00:00:00.000Z" Fixes S15.5.4.7_A1_T11.js test case. JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg@inf.u-szeged.hu
This commit is contained in:
@@ -22,6 +22,7 @@
|
||||
#include "ecma-objects.h"
|
||||
#include "ecma-try-catch-macro.h"
|
||||
#include "fdlibm-math.h"
|
||||
#include "lit-char-helpers.h"
|
||||
|
||||
#ifndef CONFIG_ECMA_COMPACT_PROFILE_DISABLE_DATE_BUILTIN
|
||||
|
||||
@@ -912,38 +913,230 @@ ecma_date_insert_num_with_sep (ecma_string_t **str_p, /**< input/output string *
|
||||
ecma_date_insert_leading_zeros (str_p, num, length);
|
||||
} /* ecma_date_insert_num_with_sep */
|
||||
|
||||
/**
|
||||
* Common function to copy utf8 characters.
|
||||
*
|
||||
* @return next destination buffer position
|
||||
*/
|
||||
static lit_utf8_byte_t *
|
||||
ecma_date_value_copy_utf8_bytes (lit_utf8_byte_t *dest_p, /**< destination buffer */
|
||||
const char *source_p) /**< source buffer */
|
||||
{
|
||||
while (*source_p != LIT_CHAR_NULL)
|
||||
{
|
||||
*dest_p++ = (lit_utf8_byte_t) *source_p++;
|
||||
}
|
||||
return dest_p;
|
||||
} /* ecma_date_value_copy_utf8_bytes */
|
||||
|
||||
/**
|
||||
* Common function to generate fixed width, right aligned decimal numbers.
|
||||
*
|
||||
* @return next destination buffer position
|
||||
*/
|
||||
static lit_utf8_byte_t *
|
||||
ecma_date_value_number_to_bytes (lit_utf8_byte_t *dest_p, /**< destination buffer */
|
||||
int32_t number, /**< number */
|
||||
int32_t width) /**< width */
|
||||
{
|
||||
dest_p += width;
|
||||
lit_utf8_byte_t *result_p = dest_p;
|
||||
|
||||
do
|
||||
{
|
||||
dest_p--;
|
||||
*dest_p = (lit_utf8_byte_t) ((number % 10) + (int32_t) LIT_CHAR_0);
|
||||
number /= 10;
|
||||
}
|
||||
while (--width > 0);
|
||||
|
||||
return result_p;
|
||||
} /* ecma_date_value_number_to_bytes */
|
||||
|
||||
/**
|
||||
* Common function to get the 3 character abbreviation of a week day.
|
||||
*
|
||||
* @return next destination buffer position
|
||||
*/
|
||||
static lit_utf8_byte_t *
|
||||
ecma_date_value_week_day_to_abbreviation (lit_utf8_byte_t *dest_p, /**< destination buffer */
|
||||
ecma_number_t datetime_number) /**< datetime */
|
||||
{
|
||||
const char *abbreviations_p[8] =
|
||||
{
|
||||
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "---"
|
||||
};
|
||||
|
||||
int32_t day = (int32_t) ecma_date_week_day (datetime_number);
|
||||
|
||||
if (day < 0 || day > 6)
|
||||
{
|
||||
/* Just for safety, it should never happen. */
|
||||
day = 7;
|
||||
}
|
||||
|
||||
return ecma_date_value_copy_utf8_bytes (dest_p, abbreviations_p[day]);
|
||||
} /* ecma_date_value_week_day_to_abbreviation */
|
||||
|
||||
/**
|
||||
* Common function to get the 3 character abbreviation of a month.
|
||||
*
|
||||
* @return next destination buffer position
|
||||
*/
|
||||
static lit_utf8_byte_t *
|
||||
ecma_date_value_month_to_abbreviation (lit_utf8_byte_t *dest_p, /**< destination buffer */
|
||||
ecma_number_t datetime_number) /**< datetime */
|
||||
{
|
||||
const char *abbreviations_p[13] =
|
||||
{
|
||||
"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "---"
|
||||
};
|
||||
|
||||
int32_t month = (int32_t) ecma_date_month_from_time (datetime_number);
|
||||
|
||||
if (month < 0 || month > 11)
|
||||
{
|
||||
/* Just for safety, it should never happen. */
|
||||
month = 12;
|
||||
}
|
||||
|
||||
return ecma_date_value_copy_utf8_bytes (dest_p, abbreviations_p[(int) month]);
|
||||
} /* ecma_date_value_month_to_abbreviation */
|
||||
|
||||
/**
|
||||
* The common 17 character long part of ecma_date_value_to_string and ecma_date_value_to_utc_string.
|
||||
*
|
||||
* @return next destination buffer position
|
||||
*/
|
||||
static lit_utf8_byte_t *
|
||||
ecma_date_value_to_string_common (lit_utf8_byte_t *dest_p, /**< destination buffer */
|
||||
ecma_number_t datetime_number) /**< datetime */
|
||||
{
|
||||
ecma_number_t year = ecma_date_year_from_time (datetime_number);
|
||||
dest_p = ecma_date_value_number_to_bytes (dest_p, (int32_t) year, 4);
|
||||
*dest_p++ = LIT_CHAR_SP;
|
||||
|
||||
ecma_number_t hours = ecma_date_hour_from_time (datetime_number);
|
||||
dest_p = ecma_date_value_number_to_bytes (dest_p, (int32_t) hours, 2);
|
||||
*dest_p++ = LIT_CHAR_COLON;
|
||||
|
||||
ecma_number_t minutes = ecma_date_min_from_time (datetime_number);
|
||||
dest_p = ecma_date_value_number_to_bytes (dest_p, (int32_t) minutes, 2);
|
||||
*dest_p++ = LIT_CHAR_COLON;
|
||||
|
||||
ecma_number_t seconds = ecma_date_sec_from_time (datetime_number);
|
||||
dest_p = ecma_date_value_number_to_bytes (dest_p, (int32_t) seconds, 2);
|
||||
|
||||
return ecma_date_value_copy_utf8_bytes (dest_p, " GMT");
|
||||
} /* ecma_date_value_to_string_common */
|
||||
|
||||
/**
|
||||
* Length of string created by ecma_date_value_to_string
|
||||
*/
|
||||
#define ECMA_DATE_VALUE_TO_STRING_LENGTH 33
|
||||
|
||||
/**
|
||||
* Common function to create a time zone specific string from a numeric value.
|
||||
*
|
||||
* Used by:
|
||||
* - The Date routine.
|
||||
* - The Date.prototype.toString routine.
|
||||
* - The Date.prototype.toISOString routine.
|
||||
*
|
||||
* @return completion value
|
||||
* Returned value must be freed with ecma_free_completion_value.
|
||||
*/
|
||||
ecma_completion_value_t
|
||||
ecma_date_value_to_string (ecma_number_t datetime_number) /**< datetime */
|
||||
{
|
||||
lit_utf8_byte_t character_buffer[ECMA_DATE_VALUE_TO_STRING_LENGTH];
|
||||
lit_utf8_byte_t *dest_p = character_buffer;
|
||||
|
||||
datetime_number = ecma_date_local_time (datetime_number);
|
||||
|
||||
dest_p = ecma_date_value_week_day_to_abbreviation (dest_p, datetime_number);
|
||||
*dest_p++ = LIT_CHAR_SP;
|
||||
|
||||
dest_p = ecma_date_value_month_to_abbreviation (dest_p, datetime_number);
|
||||
*dest_p++ = LIT_CHAR_SP;
|
||||
|
||||
ecma_number_t day = ecma_date_date_from_time (datetime_number);
|
||||
dest_p = ecma_date_value_number_to_bytes (dest_p, (int32_t) day, 2);
|
||||
*dest_p++ = LIT_CHAR_SP;
|
||||
|
||||
dest_p = ecma_date_value_to_string_common (dest_p, datetime_number);
|
||||
|
||||
int32_t time_zone = (int32_t) (ecma_date_local_tza () + ecma_date_daylight_saving_ta (datetime_number));
|
||||
*dest_p++ = (time_zone >= 0) ? LIT_CHAR_PLUS : LIT_CHAR_MINUS;
|
||||
|
||||
dest_p = ecma_date_value_number_to_bytes (dest_p, time_zone / 60, 2);
|
||||
dest_p = ecma_date_value_number_to_bytes (dest_p, time_zone % 60, 2);
|
||||
|
||||
JERRY_ASSERT (dest_p - character_buffer == ECMA_DATE_VALUE_TO_STRING_LENGTH);
|
||||
|
||||
ecma_string_t *date_string_p = ecma_new_ecma_string_from_utf8 (character_buffer,
|
||||
ECMA_DATE_VALUE_TO_STRING_LENGTH);
|
||||
|
||||
return ecma_make_normal_completion_value (ecma_make_string_value (date_string_p));
|
||||
} /* ecma_date_value_to_string */
|
||||
|
||||
/**
|
||||
* Length of string created by ecma_date_value_to_utc_string
|
||||
*/
|
||||
#define ECMA_DATE_VALUE_TO_UTC_STRING_LENGTH 29
|
||||
|
||||
/**
|
||||
* Common function to create a time zone specific string from a numeric value.
|
||||
*
|
||||
* Used by:
|
||||
* - The Date.prototype.toUTCString routine.
|
||||
*
|
||||
* @return completion value
|
||||
* Returned value must be freed with ecma_free_completion_value.
|
||||
*/
|
||||
ecma_completion_value_t
|
||||
ecma_date_value_to_string (ecma_number_t datetime_num, /**<datetime */
|
||||
ecma_date_timezone_t timezone) /**< timezone */
|
||||
ecma_date_value_to_utc_string (ecma_number_t datetime_number) /**< datetime */
|
||||
{
|
||||
lit_utf8_byte_t character_buffer[ECMA_DATE_VALUE_TO_UTC_STRING_LENGTH];
|
||||
lit_utf8_byte_t *dest_p = character_buffer;
|
||||
|
||||
dest_p = ecma_date_value_week_day_to_abbreviation (dest_p, datetime_number);
|
||||
*dest_p++ = LIT_CHAR_COMMA;
|
||||
*dest_p++ = LIT_CHAR_SP;
|
||||
|
||||
ecma_number_t day = ecma_date_date_from_time (datetime_number);
|
||||
dest_p = ecma_date_value_number_to_bytes (dest_p, (int32_t) day, 2);
|
||||
*dest_p++ = LIT_CHAR_SP;
|
||||
|
||||
dest_p = ecma_date_value_month_to_abbreviation (dest_p, datetime_number);
|
||||
*dest_p++ = LIT_CHAR_SP;
|
||||
|
||||
dest_p = ecma_date_value_to_string_common (dest_p, datetime_number);
|
||||
|
||||
JERRY_ASSERT (dest_p - character_buffer == ECMA_DATE_VALUE_TO_UTC_STRING_LENGTH);
|
||||
|
||||
ecma_string_t *date_string_p = ecma_new_ecma_string_from_utf8 (character_buffer,
|
||||
ECMA_DATE_VALUE_TO_UTC_STRING_LENGTH);
|
||||
|
||||
return ecma_make_normal_completion_value (ecma_make_string_value (date_string_p));
|
||||
} /* ecma_date_value_to_utc_string */
|
||||
|
||||
/**
|
||||
* Common function to create a time zone specific string from a numeric value.
|
||||
*
|
||||
* Used by:
|
||||
* - The Date.prototype.toISOString routine.
|
||||
*
|
||||
* @return completion value
|
||||
* Returned value must be freed with ecma_free_completion_value.
|
||||
*/
|
||||
ecma_completion_value_t
|
||||
ecma_date_value_to_iso_string (ecma_number_t datetime_num) /**<datetime */
|
||||
{
|
||||
ecma_string_t *output_str_p;
|
||||
ecma_number_t milliseconds;
|
||||
|
||||
if (timezone == ECMA_DATE_LOCAL)
|
||||
{
|
||||
datetime_num = ecma_date_local_time (datetime_num);
|
||||
milliseconds = ecma_date_ms_from_time (datetime_num);
|
||||
output_str_p = ecma_new_ecma_string_from_number (milliseconds);
|
||||
ecma_date_insert_leading_zeros (&output_str_p, milliseconds, 3);
|
||||
}
|
||||
else /* ECMA_DATE_UTC */
|
||||
{
|
||||
milliseconds = ecma_date_ms_from_time (datetime_num);
|
||||
output_str_p = ecma_get_magic_string (LIT_MAGIC_STRING__EMPTY);
|
||||
ecma_date_insert_num_with_sep (&output_str_p, milliseconds, LIT_MAGIC_STRING_Z_CHAR, 3);
|
||||
}
|
||||
ecma_number_t milliseconds = ecma_date_ms_from_time (datetime_num);
|
||||
output_str_p = ecma_get_magic_string (LIT_MAGIC_STRING__EMPTY);
|
||||
ecma_date_insert_num_with_sep (&output_str_p, milliseconds, LIT_MAGIC_STRING_Z_CHAR, 3);
|
||||
|
||||
ecma_number_t seconds = ecma_date_sec_from_time (datetime_num);
|
||||
ecma_date_insert_num_with_sep (&output_str_p, seconds, LIT_MAGIC_STRING_DOT_CHAR, 2);
|
||||
@@ -969,7 +1162,7 @@ ecma_date_value_to_string (ecma_number_t datetime_num, /**<datetime */
|
||||
ecma_date_insert_num_with_sep (&output_str_p, year, LIT_MAGIC_STRING_MINUS_CHAR, 4);
|
||||
|
||||
return ecma_make_normal_completion_value (ecma_make_string_value (output_str_p));
|
||||
} /* ecma_date_value_to_string */
|
||||
} /* ecma_date_value_to_iso_string */
|
||||
|
||||
/**
|
||||
* Common function to get the primitive value of the Date object.
|
||||
|
||||
Reference in New Issue
Block a user