Skip to content

Commit e1b9fb6

Browse files
committed
Implement Date.prototype.toDateString and Date.prototype.toTimeString
JerryScript-DCO-1.0-Signed-off-by: László Langó llango.u-szeged@partner.samsung.com
1 parent 74a5a14 commit e1b9fb6

File tree

2 files changed

+141
-7
lines changed

2 files changed

+141
-7
lines changed

jerry-core/ecma/builtin-objects/ecma-builtin-date-prototype.cpp

Lines changed: 97 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,9 +105,10 @@ ecma_builtin_date_prototype_to_string (ecma_value_t this_arg) /**< this argument
105105
{
106106
ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();
107107

108-
if (ecma_object_get_class_name (ecma_get_object_from_value (this_arg)) != LIT_MAGIC_STRING_DATE_UL)
108+
if (!ecma_is_value_object (this_arg)
109+
|| ecma_object_get_class_name (ecma_get_object_from_value (this_arg)) != LIT_MAGIC_STRING_DATE_UL)
109110
{
110-
ret_value = ecma_raise_type_error ("Incomplete Date type");
111+
ret_value = ecma_raise_type_error ("Incompatible type");
111112
}
112113
else
113114
{
@@ -176,7 +177,54 @@ ecma_builtin_date_prototype_to_string (ecma_value_t this_arg) /**< this argument
176177
static ecma_completion_value_t
177178
ecma_builtin_date_prototype_to_date_string (ecma_value_t this_arg) /**< this argument */
178179
{
179-
ECMA_BUILTIN_CP_UNIMPLEMENTED (this_arg);
180+
ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();
181+
182+
if (!ecma_is_value_object (this_arg)
183+
|| ecma_object_get_class_name (ecma_get_object_from_value (this_arg)) != LIT_MAGIC_STRING_DATE_UL)
184+
{
185+
ret_value = ecma_raise_type_error ("Incompatible type");
186+
}
187+
else
188+
{
189+
ECMA_TRY_CATCH (obj_this,
190+
ecma_op_to_object (this_arg),
191+
ret_value);
192+
193+
ecma_object_t *obj_p = ecma_get_object_from_value (obj_this);
194+
ecma_property_t *prim_value_prop_p;
195+
prim_value_prop_p = ecma_get_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_PRIMITIVE_NUMBER_VALUE);
196+
ecma_number_t *prim_value_num_p = ECMA_GET_NON_NULL_POINTER (ecma_number_t,
197+
prim_value_prop_p->u.internal_property.value);
198+
199+
if (ecma_number_is_nan (*prim_value_num_p))
200+
{
201+
ecma_string_t *magic_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_INVALID_DATE_UL);
202+
ret_value = ecma_make_normal_completion_value (ecma_make_string_value (magic_str_p));
203+
}
204+
else
205+
{
206+
ecma_number_t day = ecma_date_date_from_time (*prim_value_num_p);
207+
ecma_string_t *output_str_p = ecma_new_ecma_string_from_number (day);
208+
ecma_date_insert_leading_zeros (&output_str_p, day, 2);
209+
210+
/*
211+
* Note:
212+
* 'ecma_date_month_from_time' (ECMA 262 v5, 15.9.1.4) returns a number from 0 to 11,
213+
* but we have to print the month from 1 to 12 for ISO 8601 standard (ECMA 262 v5, 15.9.1.15).
214+
*/
215+
ecma_number_t month = ecma_date_month_from_time (*prim_value_num_p) + 1;
216+
ecma_date_insert_num_with_sep (&output_str_p, month, LIT_MAGIC_STRING_MINUS_CHAR, 2);
217+
218+
ecma_number_t year = ecma_date_year_from_time (*prim_value_num_p);
219+
ecma_date_insert_num_with_sep (&output_str_p, year, LIT_MAGIC_STRING_MINUS_CHAR, 4);
220+
221+
ret_value = ecma_make_normal_completion_value (ecma_make_string_value (output_str_p));
222+
}
223+
224+
ECMA_FINALIZE (obj_this);
225+
}
226+
227+
return ret_value;
180228
} /* ecma_builtin_date_prototype_to_date_string */
181229

182230
/**
@@ -191,7 +239,52 @@ ecma_builtin_date_prototype_to_date_string (ecma_value_t this_arg) /**< this arg
191239
static ecma_completion_value_t
192240
ecma_builtin_date_prototype_to_time_string (ecma_value_t this_arg) /**< this argument */
193241
{
194-
ECMA_BUILTIN_CP_UNIMPLEMENTED (this_arg);
242+
ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();
243+
244+
if (!ecma_is_value_object (this_arg)
245+
|| ecma_object_get_class_name (ecma_get_object_from_value (this_arg)) != LIT_MAGIC_STRING_DATE_UL)
246+
{
247+
ret_value = ecma_raise_type_error ("Incompatible type");
248+
}
249+
else
250+
{
251+
ECMA_TRY_CATCH (obj_this,
252+
ecma_op_to_object (this_arg),
253+
ret_value);
254+
255+
ecma_object_t *obj_p = ecma_get_object_from_value (obj_this);
256+
ecma_property_t *prim_value_prop_p;
257+
prim_value_prop_p = ecma_get_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_PRIMITIVE_NUMBER_VALUE);
258+
ecma_number_t *prim_value_num_p = ECMA_GET_NON_NULL_POINTER (ecma_number_t,
259+
prim_value_prop_p->u.internal_property.value);
260+
261+
if (ecma_number_is_nan (*prim_value_num_p))
262+
{
263+
ecma_string_t *magic_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_INVALID_DATE_UL);
264+
ret_value = ecma_make_normal_completion_value (ecma_make_string_value (magic_str_p));
265+
}
266+
else
267+
{
268+
ecma_number_t milliseconds = ecma_date_ms_from_time (*prim_value_num_p);
269+
ecma_string_t *output_str_p = ecma_new_ecma_string_from_number (milliseconds);
270+
ecma_date_insert_leading_zeros (&output_str_p, milliseconds, 3);
271+
272+
ecma_number_t seconds = ecma_date_sec_from_time (*prim_value_num_p);
273+
ecma_date_insert_num_with_sep (&output_str_p, seconds, LIT_MAGIC_STRING_DOT_CHAR, 2);
274+
275+
ecma_number_t minutes = ecma_date_min_from_time (*prim_value_num_p);
276+
ecma_date_insert_num_with_sep (&output_str_p, minutes, LIT_MAGIC_STRING_COLON_CHAR, 2);
277+
278+
ecma_number_t hours = ecma_date_hour_from_time (*prim_value_num_p);
279+
ecma_date_insert_num_with_sep (&output_str_p, hours, LIT_MAGIC_STRING_COLON_CHAR, 2);
280+
281+
ret_value = ecma_make_normal_completion_value (ecma_make_string_value (output_str_p));
282+
}
283+
284+
ECMA_FINALIZE (obj_this);
285+
}
286+
287+
return ret_value;
195288
} /* ecma_builtin_date_prototype_to_time_string */
196289

197290
/**

tests/jerry/date-tostring.js

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,47 @@
1313
// See the License for the specific language governing permissions and
1414
// limitations under the License.
1515

16-
assert (new Date(NaN) == "Invalid Date");
17-
assert (new Date("2015-02-13") == "2015-02-13T00:00:00.000");
18-
assert (new Date("2015-07-08T11:29:05.023") == "2015-07-08T11:29:05.023");
16+
assert (new Date (NaN) == "Invalid Date");
17+
assert (new Date ("2015-02-13") == "2015-02-13T00:00:00.000");
18+
assert (new Date ("2015-07-08T11:29:05.023") == "2015-07-08T11:29:05.023");
19+
20+
try
21+
{
22+
Date.prototype.toString.call(-1);
23+
assert (false);
24+
}
25+
catch (e)
26+
{
27+
assert (e instanceof TypeError);
28+
assert (e.message === "Incompatible type");
29+
}
30+
31+
assert (new Date (NaN).toDateString () == "Invalid Date");
32+
assert (new Date ("2015-02-13").toDateString () == "2015-02-13");
33+
assert (new Date ("2015-07-08T11:29:05.023").toDateString () == "2015-07-08");
34+
35+
try
36+
{
37+
Date.prototype.toDateString.call(-1);
38+
assert (false);
39+
}
40+
catch (e)
41+
{
42+
assert (e instanceof TypeError);
43+
assert (e.message === "Incompatible type");
44+
}
45+
46+
assert (new Date (NaN).toTimeString () == "Invalid Date");
47+
assert (new Date ("2015-02-13").toTimeString () == "00:00:00.000");
48+
assert (new Date ("2015-07-08T11:29:05.023").toTimeString () == "11:29:05.023");
49+
50+
try
51+
{
52+
Date.prototype.toTimeString.call(-1);
53+
assert (false);
54+
}
55+
catch (e)
56+
{
57+
assert (e instanceof TypeError);
58+
assert (e.message === "Incompatible type");
59+
}

0 commit comments

Comments
 (0)