From a997364083d12f8e74d140fd2d266ce3f43807aa Mon Sep 17 00:00:00 2001 From: Hyunjee Kim Date: Wed, 19 Oct 2016 15:15:56 +0900 Subject: [PATCH] [Base-utils][Utmscale] Module implementation added. Change-Id: Ic4395ebd185079ea7fd5e647d6692225246b7996 Signed-off-by: Hyunjee Kim --- packaging/capi-base-utils.spec | 2 +- src/CMakeLists.txt | 2 + src/include/utils_i18n.h | 22 ++- src/include/utils_i18n_types.h | 44 +++++ src/include/utils_i18n_utmscale.h | 259 ++++++++++++++++++++++++++++++ src/utils_i18n_utmscale.c | 59 +++++++ 6 files changed, 386 insertions(+), 2 deletions(-) create mode 100644 src/include/utils_i18n_utmscale.h create mode 100644 src/utils_i18n_utmscale.c diff --git a/packaging/capi-base-utils.spec b/packaging/capi-base-utils.spec index 4a1a85c..0b8277e 100755 --- a/packaging/capi-base-utils.spec +++ b/packaging/capi-base-utils.spec @@ -1,6 +1,6 @@ Name: capi-base-utils Summary: Base Utils -Version: 1.2.6 +Version: 1.2.7 Release: 2 Group: Base License: Apache-2.0 and ICU diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index afbefb5..7374727 100755 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -36,6 +36,7 @@ SET(BASEUTILS_SRCS utils_i18n_field_position.cpp utils_i18n_parse_position.cpp utils_i18n_ushape.c + utils_i18n_utmscale.c ) ADD_LIBRARY(${target_name} SHARED ${BASEUTILS_SRCS} @@ -82,5 +83,6 @@ INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${INC_DIR}/utils_i18n_measure_format.h INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${INC_DIR}/utils_i18n_field_position.h DESTINATION ${INCLUDE_INSTALL_DIR}/base) INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${INC_DIR}/utils_i18n_parse_position.h DESTINATION ${INCLUDE_INSTALL_DIR}/base) INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${INC_DIR}/utils_i18n_ushape.h DESTINATION ${INCLUDE_INSTALL_DIR}/base) +INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${INC_DIR}/utils_i18n_utmscale.h DESTINATION ${INCLUDE_INSTALL_DIR}/base) INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${INC_DIR}/utils_i18n.h DESTINATION ${INCLUDE_INSTALL_DIR}/base) INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${pc_name}.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig) diff --git a/src/include/utils_i18n.h b/src/include/utils_i18n.h index f9ad4cc..eb6d380 100644 --- a/src/include/utils_i18n.h +++ b/src/include/utils_i18n.h @@ -41,6 +41,7 @@ #include #include #include +#include /** * @file utils_i18n.h @@ -55,7 +56,7 @@ extern "C" { /** * @ingroup CAPI_BASE_UTILS_MODULE * @defgroup CAPI_BASE_UTILS_I18N_MODULE i18n - * @brief The i18n module contains uchar, ucollator, unormalization, usearch, ustring, ucalendar, udate, udatepg, ulocale, unumber, alpha_idx, formattable, measure unit, measure, format, measure format, field position, parse position and ushape. + * @brief The i18n module contains uchar, ucollator, unormalization, usearch, ustring, ucalendar, udate, udatepg, ulocale, unumber, alpha_idx, formattable, measure unit, measure, format, measure format, field position, parse position, ushape and utmscale. * This module provides flexible generation of number or date format patterns and helps you format and parse dates/number for any locale. * The i18n module provides various features based on data from ICU. The following table shows the version of ICU used in each Tizen platform. * @@ -173,6 +174,10 @@ extern "C" { * * * + * + * + * + * *
@ref CAPI_BASE_UTILS_I18N_USHAPE_MODULEUshape module provides Arabic shaping functionality.
@ref CAPI_BASE_UTILS_I18N_UTMSCALE_MODULEThe Universal Time Scale
* * @section CAPI_BASE_UTILS_I18N_MODULE_MAPPING_TABLE Mapping Table @@ -2918,6 +2923,21 @@ extern "C" { * #i18n_ushape_shape_arabic * u_shapeArabic * + * + * @ref CAPI_BASE_UTILS_I18N_UTMSCALE_MODULE + * #i18n_utmscale_get_time_scale_value + * utmscale_getTimeScaleValue + * + * + * @ref CAPI_BASE_UTILS_I18N_UTMSCALE_MODULE + * #i18n_utmscale_from_int64 + * utmscale_fromInt64 + * + * + * @ref CAPI_BASE_UTILS_I18N_UTMSCALE_MODULE + * #i18n_utmscale_to_int64 + * utmscale_toInt64 + * * */ diff --git a/src/include/utils_i18n_types.h b/src/include/utils_i18n_types.h index 1be6c1e..bf016a1 100644 --- a/src/include/utils_i18n_types.h +++ b/src/include/utils_i18n_types.h @@ -3468,6 +3468,50 @@ typedef void *i18n_parse_position_h; */ #define I18N_USHAPE_TAIL_TYPE_MASK 0x8000000 +/** + * @} + */ + +/** + * @addtogroup CAPI_BASE_UTILS_I18N_UTMSCALE_MODULE + * @{ + */ + +/** + * @brief Enumeration for the values used to specify the time scale used for conversion into or out of the universal time scale. + * @since_tizen 3.0 + */ +typedef enum { + I18N_UTMSCALE_JAVA_TIME = 0, /**< Used in the JDK. Data is a Java long (int64_t). Value is milliseconds since January 1, 1970.*/ + I18N_UTMSCALE_UNIX_TIME, /**< Used on Unix systems. Data is an int32_t or int64_t. Value is seconds since January 1, 1970.*/ + I18N_UTMSCALE_ICU4C_TIME, /**< Used in ICU4C. Data is a double. Value is milliseconds since January 1, 1970.*/ + I18N_UTMSCALE_WINDOWS_FILE_TIME, /**< Used in Windows for file times. Data is an int64_t. Value is ticks (1 tick == 100 nanoseconds) since January 1, 1601.*/ + I18N_UTMSCALE_DOTNET_DATE_TIME, /**< Used in the .NET framework's System.DateTime structure. Data is an int64_t. Value is ticks (1 tick == 100 nanoseconds) since January 1, 0001.*/ + I18N_UTMSCALE_MAC_OLD_TIME, /**< Used in older Macintosh systems. Data is an int32_t or int64_t. Value is seconds since January 1, 1904.*/ + I18N_UTMSCALE_MAC_TIME, /**< Used in newer Macintosh systems. Data is a double. Value is seconds since January 1, 2001.*/ + I18N_UTMSCALE_EXCEL_TIME, /**< Used in Excel. Value is days since December 31, 1899.*/ + I18N_UTMSCALE_DB2_TIME, /**< Used in DB2. Value is days since December 31, 1899.*/ + I18N_UTMSCALE_UNIX_MICROSECONDS_TIME, /**< Data is a long. Value is microseconds since January 1, 1970. Similar to Unix time (linear value from 1970) and struct timeval (microseconds resolution).*/ + I18N_UTMSCALE_MAX_SCALE /**< The first unused time scale value. The limit of this enum */ +} i18n_utmscale_scale_e; + + +/** + * @brief Enumeration for the values used to specify the time scale values to i18n_utmscale_get_time_scale_value(). + * @since_tizen 3.0 + * + * @see i18n_utmscale_get_time_scale_value() + */ +typedef enum { + I18N_UTMSCALE_VALUE_UNITS = 0, /**< The constant used to select the units value for a time scale. */ + I18N_UTMSCALE_VALUE_EPOCH_OFFSET = 1, /**< The constant used to select the epoch offset value for a time scale. */ + I18N_UTMSCALE_VALUE_FROM_MIN = 2, /**< The constant used to select the minimum from value for a time scale. */ + I18N_UTMSCALE_VALUE_FROM_MAX = 3, /**< The constant used to select the maximum from value for a time scale. */ + I18N_UTMSCALE_VALUE_TO_MIN = 4, /**< The constant used to select the minimum to value for a time scale. */ + I18N_UTMSCALE_VALUE_TO_MAX = 5, /**< The constant used to select the maximum to value for a time scale. */ + I18N_UTMSCALE_VALUE_MAX /**< The number of time scale values, in other words limit of this enum.*/ +} i18n_utmscale_value_e; + /** * @} */ diff --git a/src/include/utils_i18n_utmscale.h b/src/include/utils_i18n_utmscale.h new file mode 100644 index 0000000..14d72bd --- /dev/null +++ b/src/include/utils_i18n_utmscale.h @@ -0,0 +1,259 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __UTILS_I18N_UTMSCALE_H__ +#define __UTILS_I18N_UTMSCALE_H__ + +#include + +/** + * @file utils_i18n_utmscale.h + * @version 0.1 + * @brief utils_i18n_utmscale + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @ingroup CAPI_BASE_UTILS_I18N_MODULE + * @defgroup CAPI_BASE_UTILS_I18N_UTMSCALE_MODULE Utmscale + * @brief Universal Time Scale + * @section CAPI_BASE_UTILS_I18N_UTMSCALE_MODULE_HEADER Required Header + * \#include + * + * @section CAPI_BASE_UTILS_I18N_UTMSCALE_MODULE_OVERVIEW Overview + * @details There are quite a few different conventions for binary datetime, + * depending on different platforms and protocols. Some of these have severe drawbacks. + * For example, people using Unix time (seconds since Jan 1, 1970) think that they are safe until near the year 2038. + * But cases can and do arise where arithmetic manipulations causes serious problems. + * Consider the computation of the average of two datetimes, + * for example: if one calculates them with average_time = (time1 + time2)/2, + * there will be overflow even with dates around the present. + * Moreover, even if these problems don't occur, there is the issue of conversion back and forth between different systems. + * + *

+ * Binary datetimes differ in a number of ways: the datatype, the unit, + * and the epoch (origin). ICU refers to these as time scales. For example: + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Table 1: Binary Time Scales
SourceDatatypeUnitEpoch
UDTS_JAVA_TIMEint64_tmillisecondsJan 1, 1970
UDTS_UNIX_TIMEint32_t or int64_tsecondsJan 1, 1970
UDTS_ICU4C_TIMEdoublemillisecondsJan 1, 1970
UDTS_WINDOWS_FILE_TIMEint64_tticks (100 nanoseconds)Jan 1, 1601
UDTS_DOTNET_DATE_TIMEint64_tticks (100 nanoseconds)Jan 1, 0001
UDTS_MAC_OLD_TIMEint32_t or int64_tsecondsJan 1, 1904
UDTS_MAC_TIMEdoublesecondsJan 1, 2001
UDTS_EXCEL_TIME?daysDec 31, 1899
UDTS_DB2_TIME?daysDec 31, 1899
UDTS_UNIX_MICROSECONDS_TIMEint64_tmicrosecondsJan 1, 1970
+ * + *

+ * All of the epochs start at 00:00 am (the earliest possible time on the day in question), + * and are assumed to be UTC. + * + *

+ * The ranges for different datatypes are given in the following table (all values in years). + * The range of years includes the entire range expressible with positive and negative + * values of the datatype. The range of years for double is the range that would be allowed + * without losing precision to the corresponding unit. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Unitsint64_tdoubleint32_t
1 sec5.84542x1011285,420,920.94136.10
1 millisecond584,542,046.09285,420.920.14
1 microsecond584,542.05285.420.00
100 nanoseconds (tick)58,454.2028.540.00
1 nanosecond584.54204610.28540.00
+ * + *

+ * These functions implement a universal time scale which can be used as a 'pivot', + * and provide conversion functions to and from all other major time scales. + * This datetimes to be converted to the pivot time, safely manipulated, + * and converted back to any other datetime time scale. + * + *

+ * So what to use for this pivot? Java time has plenty of range, but cannot represent + * .NET System.DateTime values without severe loss of precision. ICU4C time addresses this by using a + * double that is otherwise equivalent to the Java time. However, there are disadvantages + * with doubles. They provide for much more graceful degradation in arithmetic operations. + * But they only have 53 bits of accuracy, which means that they will lose precision when + * converting back and forth to ticks. What would really be nice would be a + * long double (80 bits -- 64 bit mantissa), but that is not supported on most systems. + * + *

+ * The Unix extended time uses a structure with two components: time in seconds and a + * fractional field (microseconds). However, this is clumsy, slow, and + * prone to error (you always have to keep track of overflow and underflow in the + * fractional field). BigDecimal would allow for arbitrary precision and arbitrary range, + * but the ICU team did not want to use this as the normal type, because it is slow and does not + * have a fixed size. + * + *

+ * Because of these issues, the ICU team ended up concluding that the .NET framework's + * System.DateTime would be the best pivot. However, ICU uses the full range + * allowed by the datatype, allowing for datetimes back to 29,000 BC and up to 29,000 AD. + * This time scale is very fine grained, does not lose precision, and covers a range that + * will meet almost all requirements. It will not handle the range that Java times do, + * but frankly, being able to handle dates before 29,000 BC or after 29,000 AD is of very limited interest. + */ + +/** + * @addtogroup CAPI_BASE_UTILS_I18N_UTMSCALE_MODULE + * @{ + */ + +/** + * @brief Gets a value associated with a particular time scale. + * @since_tizen 3.0 + * + * @param[in] time_scale The time scale + * @param[in] utmscale_val A constant representing the value to get + * @param[out] value The obtained value + * + * @return @c 0 on success, otherwise a negative error value + * @retval #I18N_ERROR_NONE Successful + * @retval #I18N_ERROR_INVALID_PARAMETER Invalid function parameter + */ +int i18n_utmscale_get_time_scale_value(i18n_utmscale_scale_e time_scale, i18n_utmscale_value_e utmscale_val, int64_t *value); + +/** + * @brief Converts the time given as an int64_t to Universal Time Scale + * @since_tizen 3.0 + * + * @param[in] other_time The int64_t datetime + * @param[in] time_scale The time scale to convert from + * @param[out] universal_time The datetime converted to the universal time scale + * + * @return @c 0 on success, otherwise a negative error value + * @retval #I18N_ERROR_NONE Successful + * @retval #I18N_ERROR_INVALID_PARAMETER The conversion is out of range. + */ +int i18n_utmscale_from_int64(int64_t other_time, i18n_utmscale_scale_e time_scale, int64_t *universal_time); + +/** + * @brief Converts the time given as Universal Time Scale to an int64_t. + * @since_tizen 3.0 + * + * @param[in] universal_time The datetime in the Universal Time Scale + * @param[in] time_scale The time scale to convert to + * @param[out] other_time The datetime converted to the given time scale + * + * @return @c 0 on success, otherwise a negative error value + * @retval #I18N_ERROR_NONE Successful + * @retval #I18N_ERROR_INVALID_PARAMETER The conversion is out of range. + */ +int i18n_utmscale_to_int64(int64_t universal_time, i18n_utmscale_scale_e time_scale, int64_t *other_time); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __UTILS_I18N_UTMSCALE_H__ */ diff --git a/src/utils_i18n_utmscale.c b/src/utils_i18n_utmscale.c new file mode 100644 index 0000000..5d828f6 --- /dev/null +++ b/src/utils_i18n_utmscale.c @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include +#include + +int i18n_utmscale_get_time_scale_value(i18n_utmscale_scale_e time_scale, i18n_utmscale_value_e utmscale_val, int64_t *value) +{ + retv_if(value == NULL, I18N_ERROR_INVALID_PARAMETER); + UErrorCode icu_error = U_ZERO_ERROR; + i18n_error_code_e i18n_error; + + *value = utmscale_getTimeScaleValue(time_scale, utmscale_val, &icu_error); + ERR_MAPPING(icu_error, i18n_error); + I18N_ERR(i18n_error); + + return i18n_error; +} + +int i18n_utmscale_from_int64(int64_t other_time, i18n_utmscale_scale_e time_scale, int64_t *universal_time) +{ + retv_if(universal_time == NULL, I18N_ERROR_INVALID_PARAMETER); + UErrorCode icu_error = U_ZERO_ERROR; + i18n_error_code_e i18n_error; + + *universal_time = utmscale_fromInt64(other_time, time_scale, &icu_error); + ERR_MAPPING(icu_error, i18n_error); + I18N_ERR(i18n_error); + + return i18n_error; +} + +int i18n_utmscale_to_int64(int64_t universal_time, i18n_utmscale_scale_e time_scale, int64_t *other_time) +{ + retv_if(other_time == NULL, I18N_ERROR_INVALID_PARAMETER); + UErrorCode icu_error = U_ZERO_ERROR; + i18n_error_code_e i18n_error; + + *other_time = utmscale_toInt64(universal_time, time_scale, &icu_error); + ERR_MAPPING(icu_error, i18n_error); + I18N_ERR(i18n_error); + + return i18n_error; +} -- 2.34.1