14514f5e3Sopenharmony_ci/* 24514f5e3Sopenharmony_ci * Copyright (c) 2021-2024 Huawei Device Co., Ltd. 34514f5e3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 44514f5e3Sopenharmony_ci * you may not use this file except in compliance with the License. 54514f5e3Sopenharmony_ci * You may obtain a copy of the License at 64514f5e3Sopenharmony_ci * 74514f5e3Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 84514f5e3Sopenharmony_ci * 94514f5e3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 104514f5e3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 114514f5e3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 124514f5e3Sopenharmony_ci * See the License for the specific language governing permissions and 134514f5e3Sopenharmony_ci * limitations under the License. 144514f5e3Sopenharmony_ci */ 154514f5e3Sopenharmony_ci 164514f5e3Sopenharmony_ci#include "builtins_date_time_format.h" 174514f5e3Sopenharmony_ci 184514f5e3Sopenharmony_ci#include "ecmascript/intl/locale_helper.h" 194514f5e3Sopenharmony_ci#include "ecmascript/global_env.h" 204514f5e3Sopenharmony_ci#include "ecmascript/js_date.h" 214514f5e3Sopenharmony_ci#include "ecmascript/js_date_time_format.h" 224514f5e3Sopenharmony_ci#include "ecmascript/js_function.h" 234514f5e3Sopenharmony_ci#include "ecmascript/js_intl.h" 244514f5e3Sopenharmony_ci 254514f5e3Sopenharmony_cinamespace panda::ecmascript::builtins { 264514f5e3Sopenharmony_ci// 13.2.1 Intl.DateTimeFormat ( [ locales [ , options ] ] ) 274514f5e3Sopenharmony_ciJSTaggedValue BuiltinsDateTimeFormat::DateTimeFormatConstructor(EcmaRuntimeCallInfo *argv) 284514f5e3Sopenharmony_ci{ 294514f5e3Sopenharmony_ci JSThread *thread = argv->GetThread(); 304514f5e3Sopenharmony_ci BUILTINS_API_TRACE(thread, DateTimeFormat, Constructor); 314514f5e3Sopenharmony_ci [[maybe_unused]] EcmaHandleScope scope(thread); 324514f5e3Sopenharmony_ci EcmaVM *ecmaVm = thread->GetEcmaVM(); 334514f5e3Sopenharmony_ci JSHandle<GlobalEnv> env = ecmaVm->GetGlobalEnv(); 344514f5e3Sopenharmony_ci ObjectFactory *factory = ecmaVm->GetFactory(); 354514f5e3Sopenharmony_ci 364514f5e3Sopenharmony_ci // 1. If NewTarget is undefined, let newTarget be the active function object, else let newTarget be NewTarget. 374514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> constructor = GetConstructor(argv); 384514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> newTarget = GetNewTarget(argv); 394514f5e3Sopenharmony_ci if (newTarget->IsUndefined()) { 404514f5e3Sopenharmony_ci newTarget = constructor; 414514f5e3Sopenharmony_ci } 424514f5e3Sopenharmony_ci 434514f5e3Sopenharmony_ci // 2. Let dateTimeFormat be ? OrdinaryCreateFromConstructor(newTarget, "%DateTimeFormatPrototype%", « 444514f5e3Sopenharmony_ci // [[InitializedDateTimeFormat]], [[Locale]], [[Calendar]], [[NumberingSystem]], [[TimeZone]], [[Weekday]], 454514f5e3Sopenharmony_ci // [[Era]], [[Year]], [[Month]], [[Day]], [[Hour]], [[Minute]], [[Second]], [[TimeZoneName]], [[HourCycle]], 464514f5e3Sopenharmony_ci // [[Pattern]], [[BoundFormat]] »). 474514f5e3Sopenharmony_ci JSHandle<JSObject> newObject = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(constructor), newTarget); 484514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 494514f5e3Sopenharmony_ci JSHandle<JSDateTimeFormat> dateTimeFormat = JSHandle<JSDateTimeFormat>::Cast(newObject); 504514f5e3Sopenharmony_ci 514514f5e3Sopenharmony_ci // 3. Perform ? InitializeDateTimeFormat(dateTimeFormat, locales, options). 524514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> locales = GetCallArg(argv, 0); 534514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> options = GetCallArg(argv, 1); 544514f5e3Sopenharmony_ci JSHandle<JSDateTimeFormat> dtf = 554514f5e3Sopenharmony_ci JSDateTimeFormat::InitializeDateTimeFormat(thread, dateTimeFormat, locales, options); 564514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 574514f5e3Sopenharmony_ci 584514f5e3Sopenharmony_ci // 4. Let this be the this value. 594514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> thisValue = GetThis(argv); 604514f5e3Sopenharmony_ci 614514f5e3Sopenharmony_ci // 5. If NewTarget is undefined and Type(this) is Object and ? InstanceofOperator(this, %DateTimeFormat%) is true, 624514f5e3Sopenharmony_ci // then 634514f5e3Sopenharmony_ci // a. Perform ? DefinePropertyOrThrow(this, %Intl%.[[FallbackSymbol]], PropertyDescriptor{ [[Value]]: 644514f5e3Sopenharmony_ci // dateTimeFormat, [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }). 654514f5e3Sopenharmony_ci // b. Return this. 664514f5e3Sopenharmony_ci if (GetNewTarget(argv)->IsUndefined() && thisValue->IsJSObject()) { 674514f5e3Sopenharmony_ci bool isInstanceOf = JSFunction::OrdinaryHasInstance(thread, env->GetDateTimeFormatFunction(), thisValue); 684514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 694514f5e3Sopenharmony_ci if (isInstanceOf) { 704514f5e3Sopenharmony_ci PropertyDescriptor descriptor(thread, JSHandle<JSTaggedValue>::Cast(dtf), false, false, false); 714514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> key(thread, JSHandle<JSIntl>::Cast(env->GetIntlFunction())->GetFallbackSymbol()); 724514f5e3Sopenharmony_ci JSTaggedValue::DefinePropertyOrThrow(thread, thisValue, key, descriptor); 734514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 744514f5e3Sopenharmony_ci return thisValue.GetTaggedValue(); 754514f5e3Sopenharmony_ci } 764514f5e3Sopenharmony_ci } 774514f5e3Sopenharmony_ci 784514f5e3Sopenharmony_ci // 6. Return dateTimeFormat. 794514f5e3Sopenharmony_ci return dtf.GetTaggedValue(); 804514f5e3Sopenharmony_ci} 814514f5e3Sopenharmony_ci 824514f5e3Sopenharmony_ci// 13.3.2 Intl.DateTimeFormat.supportedLocalesOf ( locales [ , options ] ) 834514f5e3Sopenharmony_ciJSTaggedValue BuiltinsDateTimeFormat::SupportedLocalesOf(EcmaRuntimeCallInfo *argv) 844514f5e3Sopenharmony_ci{ 854514f5e3Sopenharmony_ci JSThread *thread = argv->GetThread(); 864514f5e3Sopenharmony_ci BUILTINS_API_TRACE(thread, DateTimeFormat, SupportedLocalesOf); 874514f5e3Sopenharmony_ci [[maybe_unused]] EcmaHandleScope scope(thread); 884514f5e3Sopenharmony_ci // 1. Let availableLocales be %DateTimeFormat%.[[AvailableLocales]]. 894514f5e3Sopenharmony_ci JSHandle<TaggedArray> availableLocales = JSDateTimeFormat::GainAvailableLocales(thread); 904514f5e3Sopenharmony_ci 914514f5e3Sopenharmony_ci // 2. Let requestedLocales be ? CanonicalizeLocaleList(locales). 924514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> locales = GetCallArg(argv, 0); 934514f5e3Sopenharmony_ci JSHandle<TaggedArray> requestedLocales = intl::LocaleHelper::CanonicalizeLocaleList(thread, locales); 944514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 954514f5e3Sopenharmony_ci 964514f5e3Sopenharmony_ci // 3. Return ? SupportedLocales(availableLocales, requestedLocales, options). 974514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> options = GetCallArg(argv, 1); 984514f5e3Sopenharmony_ci JSHandle<JSArray> result = JSLocale::SupportedLocales(thread, availableLocales, requestedLocales, options); 994514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 1004514f5e3Sopenharmony_ci return result.GetTaggedValue(); 1014514f5e3Sopenharmony_ci} 1024514f5e3Sopenharmony_ci 1034514f5e3Sopenharmony_ci// 13.4.3 get Intl.DateTimeFormat.prototype.format 1044514f5e3Sopenharmony_ciJSTaggedValue BuiltinsDateTimeFormat::Format(EcmaRuntimeCallInfo *argv) 1054514f5e3Sopenharmony_ci{ 1064514f5e3Sopenharmony_ci JSThread *thread = argv->GetThread(); 1074514f5e3Sopenharmony_ci BUILTINS_API_TRACE(thread, DateTimeFormat, Format); 1084514f5e3Sopenharmony_ci [[maybe_unused]] EcmaHandleScope scope(thread); 1094514f5e3Sopenharmony_ci 1104514f5e3Sopenharmony_ci // 1. Let dtf be this value. 1114514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> thisValue = GetThis(argv); 1124514f5e3Sopenharmony_ci 1134514f5e3Sopenharmony_ci // 2. If Type(dtf) is not Object, throw a TypeError exception. 1144514f5e3Sopenharmony_ci if (!thisValue->IsJSObject()) { 1154514f5e3Sopenharmony_ci THROW_TYPE_ERROR_AND_RETURN(thread, "dtf is not object", JSTaggedValue::Exception()); 1164514f5e3Sopenharmony_ci } 1174514f5e3Sopenharmony_ci 1184514f5e3Sopenharmony_ci // 3. Let dtf be ? UnwrapDateTimeFormat(dtf). 1194514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> dtfValue = JSDateTimeFormat::UnwrapDateTimeFormat(thread, thisValue); 1204514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 1214514f5e3Sopenharmony_ci if (dtfValue->IsUndefined()) { 1224514f5e3Sopenharmony_ci THROW_TYPE_ERROR_AND_RETURN(thread, "dtfValue is not object", JSTaggedValue::Exception()); 1234514f5e3Sopenharmony_ci } 1244514f5e3Sopenharmony_ci 1254514f5e3Sopenharmony_ci // 4. If dtf.[[BoundFormat]] is undefined, then 1264514f5e3Sopenharmony_ci // a. Let F be a new built-in function object as defined in DateTime Format Functions (13.1.5). 1274514f5e3Sopenharmony_ci // b. Set F.[[DateTimeFormat]] to dtf. 1284514f5e3Sopenharmony_ci // c. Set dtf.[[BoundFormat]] to F. 1294514f5e3Sopenharmony_ci // 5. Return dtf.[[BoundFormat]]. 1304514f5e3Sopenharmony_ci JSHandle<JSDateTimeFormat> dtf = JSHandle<JSDateTimeFormat>::Cast(dtfValue); 1314514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> boundFormat(thread, dtf->GetBoundFormat()); 1324514f5e3Sopenharmony_ci if (boundFormat->IsUndefined()) { 1334514f5e3Sopenharmony_ci ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 1344514f5e3Sopenharmony_ci JSHandle<JSIntlBoundFunction> intlBoundFunc = factory->NewJSIntlBoundFunction( 1354514f5e3Sopenharmony_ci MethodIndex::BUILTINS_DATE_TIME_FORMAT_ANONYMOUS_DATE_TIME_FORMAT); 1364514f5e3Sopenharmony_ci intlBoundFunc->SetDateTimeFormat(thread, dtf); 1374514f5e3Sopenharmony_ci dtf->SetBoundFormat(thread, intlBoundFunc); 1384514f5e3Sopenharmony_ci } 1394514f5e3Sopenharmony_ci return dtf->GetBoundFormat(); 1404514f5e3Sopenharmony_ci} 1414514f5e3Sopenharmony_ci 1424514f5e3Sopenharmony_ci// 13.1.5 DateTime Format Functions 1434514f5e3Sopenharmony_ciJSTaggedValue BuiltinsDateTimeFormat::AnonymousDateTimeFormat(EcmaRuntimeCallInfo *argv) 1444514f5e3Sopenharmony_ci{ 1454514f5e3Sopenharmony_ci // A DateTime format function is an anonymous built-in function that has a [[DateTimeFormat]] internal slot. 1464514f5e3Sopenharmony_ci // When a DateTime format function F is called with optional argument date, the following steps are taken: 1474514f5e3Sopenharmony_ci JSThread *thread = argv->GetThread(); 1484514f5e3Sopenharmony_ci BUILTINS_API_TRACE(thread, DateTimeFormat, AnonymousDateTimeFormat); 1494514f5e3Sopenharmony_ci [[maybe_unused]] EcmaHandleScope scope(thread); 1504514f5e3Sopenharmony_ci JSHandle<JSIntlBoundFunction> intlBoundFunc = JSHandle<JSIntlBoundFunction>::Cast(GetConstructor(argv)); 1514514f5e3Sopenharmony_ci 1524514f5e3Sopenharmony_ci // 1. Let dtf be F.[[DateTimeFormat]]. 1534514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> dtf(thread, intlBoundFunc->GetDateTimeFormat()); 1544514f5e3Sopenharmony_ci 1554514f5e3Sopenharmony_ci // 2. Assert: Type(dtf) is Object and dtf has an [[InitializedDateTimeFormat]] internal slot. 1564514f5e3Sopenharmony_ci ASSERT_PRINT(dtf->IsJSObject() && dtf->IsJSDateTimeFormat(), "dtf is not object or JSDateTimeFormat"); 1574514f5e3Sopenharmony_ci 1584514f5e3Sopenharmony_ci // 3. If date is not provided or is undefined, then 1594514f5e3Sopenharmony_ci // a. Let x be Call(%Date_now%, undefined). 1604514f5e3Sopenharmony_ci // 4. Else, 1614514f5e3Sopenharmony_ci // a. Let x be ? ToNumber(date). 1624514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> date = GetCallArg(argv, 0); 1634514f5e3Sopenharmony_ci double x = 0.0; 1644514f5e3Sopenharmony_ci if (date->IsUndefined()) { 1654514f5e3Sopenharmony_ci x = JSDate::Now().GetNumber(); 1664514f5e3Sopenharmony_ci } else { 1674514f5e3Sopenharmony_ci JSTaggedNumber xNumber = JSTaggedValue::ToNumber(thread, date); 1684514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 1694514f5e3Sopenharmony_ci x = xNumber.GetNumber(); 1704514f5e3Sopenharmony_ci } 1714514f5e3Sopenharmony_ci 1724514f5e3Sopenharmony_ci // 5. Return ? FormatDateTime(dtf, x). 1734514f5e3Sopenharmony_ci JSHandle<EcmaString> result = JSDateTimeFormat::FormatDateTime(thread, JSHandle<JSDateTimeFormat>::Cast(dtf), x); 1744514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 1754514f5e3Sopenharmony_ci return result.GetTaggedValue(); 1764514f5e3Sopenharmony_ci} 1774514f5e3Sopenharmony_ci 1784514f5e3Sopenharmony_ci// 13.4.4 Intl.DateTimeFormat.prototype.formatToParts ( date ) 1794514f5e3Sopenharmony_ciJSTaggedValue BuiltinsDateTimeFormat::FormatToParts(EcmaRuntimeCallInfo *argv) 1804514f5e3Sopenharmony_ci{ 1814514f5e3Sopenharmony_ci JSThread *thread = argv->GetThread(); 1824514f5e3Sopenharmony_ci BUILTINS_API_TRACE(thread, DateTimeFormat, FormatToParts); 1834514f5e3Sopenharmony_ci [[maybe_unused]] EcmaHandleScope scope(thread); 1844514f5e3Sopenharmony_ci // 1. Let dtf be this value. 1854514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> dtf = GetThis(argv); 1864514f5e3Sopenharmony_ci // 2. Perform ? RequireInternalSlot(dtf, [[InitializedDateTimeFormat]]). 1874514f5e3Sopenharmony_ci if (!dtf->IsJSDateTimeFormat()) { 1884514f5e3Sopenharmony_ci THROW_TYPE_ERROR_AND_RETURN(thread, "is not JSDateTimeFormat", JSTaggedValue::Exception()); 1894514f5e3Sopenharmony_ci } 1904514f5e3Sopenharmony_ci 1914514f5e3Sopenharmony_ci // 3. If date is undefined, then 1924514f5e3Sopenharmony_ci // a. Let x be Call(%Date_now%, undefined). 1934514f5e3Sopenharmony_ci // 4. Else, 1944514f5e3Sopenharmony_ci // a. Let x be ? ToNumber(date). 1954514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> date = GetCallArg(argv, 0); 1964514f5e3Sopenharmony_ci double x = 0.0; 1974514f5e3Sopenharmony_ci if (date->IsUndefined()) { 1984514f5e3Sopenharmony_ci x = JSDate::Now().GetNumber(); 1994514f5e3Sopenharmony_ci } else { 2004514f5e3Sopenharmony_ci JSTaggedNumber xNumber = JSTaggedValue::ToNumber(thread, date); 2014514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 2024514f5e3Sopenharmony_ci x = xNumber.GetNumber(); 2034514f5e3Sopenharmony_ci } 2044514f5e3Sopenharmony_ci 2054514f5e3Sopenharmony_ci double xValue = JSDate::TimeClip(x); 2064514f5e3Sopenharmony_ci if (std::isnan(xValue)) { 2074514f5e3Sopenharmony_ci THROW_RANGE_ERROR_AND_RETURN(thread, "Invalid time value", JSTaggedValue::Exception()); 2084514f5e3Sopenharmony_ci } 2094514f5e3Sopenharmony_ci 2104514f5e3Sopenharmony_ci // 5. Return ? FormatDateTimeToParts(dtf, x). 2114514f5e3Sopenharmony_ci JSHandle<JSArray> result = 2124514f5e3Sopenharmony_ci JSDateTimeFormat::FormatDateTimeToParts(thread, JSHandle<JSDateTimeFormat>::Cast(dtf), xValue); 2134514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 2144514f5e3Sopenharmony_ci return result.GetTaggedValue(); 2154514f5e3Sopenharmony_ci} 2164514f5e3Sopenharmony_ci 2174514f5e3Sopenharmony_ci// 13.4.5 Intl.DateTimeFormat.prototype.resolvedOptions () 2184514f5e3Sopenharmony_ciJSTaggedValue BuiltinsDateTimeFormat::ResolvedOptions(EcmaRuntimeCallInfo *argv) 2194514f5e3Sopenharmony_ci{ 2204514f5e3Sopenharmony_ci JSThread *thread = argv->GetThread(); 2214514f5e3Sopenharmony_ci BUILTINS_API_TRACE(thread, DateTimeFormat, ResolvedOptions); 2224514f5e3Sopenharmony_ci [[maybe_unused]] EcmaHandleScope scope(thread); 2234514f5e3Sopenharmony_ci // 1. Let dtf be this value. 2244514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> thisValue = GetThis(argv); 2254514f5e3Sopenharmony_ci // 2. If Type(dtf) is not Object, throw a TypeError exception. 2264514f5e3Sopenharmony_ci if (!thisValue->IsJSObject()) { 2274514f5e3Sopenharmony_ci THROW_TYPE_ERROR_AND_RETURN(thread, "this is not object", JSTaggedValue::Exception()); 2284514f5e3Sopenharmony_ci } 2294514f5e3Sopenharmony_ci // 3. Let dtf be ? UnwrapDateTimeFormat(dtf). 2304514f5e3Sopenharmony_ci thisValue = JSDateTimeFormat::UnwrapDateTimeFormat(thread, thisValue); 2314514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 2324514f5e3Sopenharmony_ci 2334514f5e3Sopenharmony_ci // Perform ? RequireInternalSlot(dtf, [[InitializedDateTimeFormat]]). 2344514f5e3Sopenharmony_ci if (!thisValue->IsJSDateTimeFormat()) { 2354514f5e3Sopenharmony_ci THROW_TYPE_ERROR_AND_RETURN(thread, "dtf is not JSDateTimeFormat", JSTaggedValue::Exception()); 2364514f5e3Sopenharmony_ci } 2374514f5e3Sopenharmony_ci 2384514f5e3Sopenharmony_ci auto ecmaVm = thread->GetEcmaVM(); 2394514f5e3Sopenharmony_ci JSHandle<GlobalEnv> env = ecmaVm->GetGlobalEnv(); 2404514f5e3Sopenharmony_ci ObjectFactory *factory = ecmaVm->GetFactory(); 2414514f5e3Sopenharmony_ci JSHandle<JSFunction> ctor(env->GetObjectFunction()); 2424514f5e3Sopenharmony_ci JSHandle<JSObject> options(factory->NewJSObjectByConstructor(ctor)); 2434514f5e3Sopenharmony_ci JSDateTimeFormat::ResolvedOptions(thread, JSHandle<JSDateTimeFormat>::Cast(thisValue), options); 2444514f5e3Sopenharmony_ci // 6. Return options. 2454514f5e3Sopenharmony_ci return options.GetTaggedValue(); 2464514f5e3Sopenharmony_ci} 2474514f5e3Sopenharmony_ci 2484514f5e3Sopenharmony_ci// Intl.DateTimeFormat.prototype.formatRange 2494514f5e3Sopenharmony_ciJSTaggedValue BuiltinsDateTimeFormat::FormatRange(EcmaRuntimeCallInfo *argv) 2504514f5e3Sopenharmony_ci{ 2514514f5e3Sopenharmony_ci JSThread *thread = argv->GetThread(); 2524514f5e3Sopenharmony_ci BUILTINS_API_TRACE(thread, DateTimeFormat, FormatRange); 2534514f5e3Sopenharmony_ci [[maybe_unused]] EcmaHandleScope scope(thread); 2544514f5e3Sopenharmony_ci 2554514f5e3Sopenharmony_ci // 1. Let dtf be this value. 2564514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> thisValue = GetThis(argv); 2574514f5e3Sopenharmony_ci // 2. If Type(dtf) is not Object, throw a TypeError exception. 2584514f5e3Sopenharmony_ci if (!thisValue->IsJSObject()) { 2594514f5e3Sopenharmony_ci THROW_TYPE_ERROR_AND_RETURN(thread, "this is not object", JSTaggedValue::Exception()); 2604514f5e3Sopenharmony_ci } 2614514f5e3Sopenharmony_ci 2624514f5e3Sopenharmony_ci // 3. If dtf does not have an [[InitializedDateTimeFormat]] internal slot, throw a TypeError exception. 2634514f5e3Sopenharmony_ci if (!thisValue->IsJSDateTimeFormat()) { 2644514f5e3Sopenharmony_ci THROW_TYPE_ERROR_AND_RETURN(thread, "this is not JSDateTimeFormat", JSTaggedValue::Exception()); 2654514f5e3Sopenharmony_ci } 2664514f5e3Sopenharmony_ci 2674514f5e3Sopenharmony_ci // 4. If startDate is undefined or endDate is undefined, throw a TypeError exception. 2684514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> startDate = GetCallArg(argv, 0); 2694514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> endDate = GetCallArg(argv, 1); 2704514f5e3Sopenharmony_ci if (startDate->IsUndefined() || endDate->IsUndefined()) { 2714514f5e3Sopenharmony_ci THROW_TYPE_ERROR_AND_RETURN(thread, "startDate or endDate is undefined", JSTaggedValue::Exception()); 2724514f5e3Sopenharmony_ci } 2734514f5e3Sopenharmony_ci 2744514f5e3Sopenharmony_ci // 5. Let x be ? ToNumber(startDate). 2754514f5e3Sopenharmony_ci JSTaggedNumber valueX = JSTaggedValue::ToNumber(thread, startDate); 2764514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 2774514f5e3Sopenharmony_ci double x = valueX.GetNumber(); 2784514f5e3Sopenharmony_ci 2794514f5e3Sopenharmony_ci // 6. Let y be ? ToNumber(endDate). 2804514f5e3Sopenharmony_ci JSTaggedNumber valueY = JSTaggedValue::ToNumber(thread, endDate); 2814514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 2824514f5e3Sopenharmony_ci double y = valueY.GetNumber(); 2834514f5e3Sopenharmony_ci 2844514f5e3Sopenharmony_ci // 8. Return ? FormatDateTimeRange(dtf, x, y) 2854514f5e3Sopenharmony_ci JSHandle<JSDateTimeFormat> dtf = JSHandle<JSDateTimeFormat>::Cast(thisValue); 2864514f5e3Sopenharmony_ci JSHandle<EcmaString> result = JSDateTimeFormat::NormDateTimeRange(thread, dtf, x, y); 2874514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 2884514f5e3Sopenharmony_ci return result.GetTaggedValue(); 2894514f5e3Sopenharmony_ci} 2904514f5e3Sopenharmony_ci 2914514f5e3Sopenharmony_ci// Intl.DateTimeFormat.prototype.formatRangeToParts 2924514f5e3Sopenharmony_ciJSTaggedValue BuiltinsDateTimeFormat::FormatRangeToParts(EcmaRuntimeCallInfo *argv) 2934514f5e3Sopenharmony_ci{ 2944514f5e3Sopenharmony_ci JSThread *thread = argv->GetThread(); 2954514f5e3Sopenharmony_ci BUILTINS_API_TRACE(thread, DateTimeFormat, FormatRangeToParts); 2964514f5e3Sopenharmony_ci [[maybe_unused]] EcmaHandleScope scope(thread); 2974514f5e3Sopenharmony_ci // 1. Let dtf be this value. 2984514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> thisValue = GetThis(argv); 2994514f5e3Sopenharmony_ci // 2. If Type(dtf) is not Object, throw a TypeError exception. 3004514f5e3Sopenharmony_ci if (!thisValue->IsJSObject()) { 3014514f5e3Sopenharmony_ci THROW_TYPE_ERROR_AND_RETURN(thread, "this is not object", JSTaggedValue::Exception()); 3024514f5e3Sopenharmony_ci } 3034514f5e3Sopenharmony_ci 3044514f5e3Sopenharmony_ci // 3. If dtf does not have an [[InitializedDateTimeFormat]] internal slot, 3054514f5e3Sopenharmony_ci // throw a TypeError exception. 3064514f5e3Sopenharmony_ci if (!thisValue->IsJSDateTimeFormat()) { 3074514f5e3Sopenharmony_ci THROW_TYPE_ERROR_AND_RETURN(thread, "this is not JSDateTimeFormat", JSTaggedValue::Exception()); 3084514f5e3Sopenharmony_ci } 3094514f5e3Sopenharmony_ci 3104514f5e3Sopenharmony_ci // 4. If startDate is undefined or endDate is undefined, throw a TypeError exception. 3114514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> startDate = GetCallArg(argv, 0); 3124514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> endDate = GetCallArg(argv, 1); 3134514f5e3Sopenharmony_ci if (startDate->IsUndefined() || endDate->IsUndefined()) { 3144514f5e3Sopenharmony_ci THROW_TYPE_ERROR_AND_RETURN(thread, "startDate or endDate is undefined", JSTaggedValue::Exception()); 3154514f5e3Sopenharmony_ci } 3164514f5e3Sopenharmony_ci 3174514f5e3Sopenharmony_ci // 5. Let x be ? ToNumber(startDate). 3184514f5e3Sopenharmony_ci JSTaggedNumber valueX = JSTaggedValue::ToNumber(thread, startDate); 3194514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 3204514f5e3Sopenharmony_ci double x = valueX.GetNumber(); 3214514f5e3Sopenharmony_ci 3224514f5e3Sopenharmony_ci // 6. Let y be ? ToNumber(endDate). 3234514f5e3Sopenharmony_ci JSTaggedNumber valueY = JSTaggedValue::ToNumber(thread, endDate); 3244514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 3254514f5e3Sopenharmony_ci double y = valueY.GetNumber(); 3264514f5e3Sopenharmony_ci 3274514f5e3Sopenharmony_ci // 8. Return ? FormatDateTimeRangeToParts(dtf, x, y) 3284514f5e3Sopenharmony_ci JSHandle<JSDateTimeFormat> dtf = JSHandle<JSDateTimeFormat>::Cast(thisValue); 3294514f5e3Sopenharmony_ci JSHandle<JSArray> result = JSDateTimeFormat::NormDateTimeRangeToParts(thread, dtf, x, y); 3304514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 3314514f5e3Sopenharmony_ci return result.GetTaggedValue(); 3324514f5e3Sopenharmony_ci} 3334514f5e3Sopenharmony_ci} // namespace panda::ecmascript::builtins