Compare commits
17
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c0d4065607 | ||
|
|
6700602974 | ||
|
|
c4fa504fec | ||
|
|
ff7cc3f1a8 | ||
|
|
a61c6ff23a | ||
|
|
6c9655060b | ||
|
|
9b9db682e1 | ||
|
|
1d3277bfc2 | ||
|
|
69d1a465dc | ||
|
|
692005d348 | ||
|
|
a84fdd0e90 | ||
|
|
a08ac00c67 | ||
|
|
9cb611d09f | ||
|
|
75e7e0bb08 | ||
|
|
309852e3df | ||
|
|
8caba0e6c9 | ||
|
|
54e7bace04 |
No files matched your search
+1
-1
@@ -66,7 +66,7 @@ for:
|
||||
- "%CYG_ROOT%\\bin\\sh -lc 'uname -a'"
|
||||
|
||||
build_script:
|
||||
- '%CYG_ROOT%\\bin\\bash -lc "cd $(cygpath ${APPVEYOR_BUILD_FOLDER}) && cd icu4c/source && ./runConfigureICU Cygwin && make -j2 check"'
|
||||
- '%CYG_ROOT%\\bin\\bash -lc "cd $(cygpath ${APPVEYOR_BUILD_FOLDER}) && cd icu4c/source && ./runConfigureICU Cygwin && make check"'
|
||||
|
||||
# -
|
||||
# matrix:
|
||||
|
||||
@@ -96,6 +96,22 @@ jobs:
|
||||
CC: clang
|
||||
CXX: clang++
|
||||
#-------------------------------------------------------------------------
|
||||
- job: ICU4C_GCC_Ubuntu_2004
|
||||
displayName: 'C: Linux GCC (Ubuntu 20.04)'
|
||||
timeoutInMinutes: 30
|
||||
pool:
|
||||
vmImage: 'ubuntu-20.04'
|
||||
steps:
|
||||
- checkout: self
|
||||
lfs: true
|
||||
fetchDepth: 10
|
||||
- script: |
|
||||
cd icu4c/source && ./runConfigureICU Linux && make -j2 check
|
||||
displayName: 'Build and Test'
|
||||
env:
|
||||
CC: gcc
|
||||
CXX: g++
|
||||
#-------------------------------------------------------------------------
|
||||
# VS 2019 Builds
|
||||
#-------------------------------------------------------------------------
|
||||
- job: ICU4C_MSVC_x64_Release_Distrelease
|
||||
|
||||
@@ -18,5 +18,6 @@
|
||||
initial bad system performance when a new build is launched.
|
||||
|
||||
NOTE:
|
||||
Run the [`./runConfigureICU` command](http://userguide.icu-project.org/icufaq)
|
||||
Run the
|
||||
[`./runConfigureICU` command](https://unicode-org.github.io/icu/userguide/icufaq)
|
||||
before building `icu4c` from VSCode.
|
||||
@@ -217,7 +217,7 @@ In the descriptions below, `<ICU>` is the full path name of the ICU directory (t
|
||||
environment variable to the out/ or the out/build/ directories, but
|
||||
this is generally discouraged because most people set it incorrectly.
|
||||
You can view the <a href=
|
||||
"http://userguide.icu-project.org/icudata">ICU Data
|
||||
"https://unicode-org.github.io/icu/userguide/icudata">ICU Data
|
||||
Management</a> section of the ICU User's Guide for details.</p>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -396,7 +396,7 @@ Depending on the platform and the type of installation, we recommend a small num
|
||||
Note: The ICU test suites _can_ be compiled with this setting.
|
||||
* **.dat file:** By default, the ICU data is built into a shared library (DLL). This is convenient because it requires no install-time or runtime configuration, but the library is platform-specific and cannot be modified. A .dat package file makes the opposite trade-off: Platform-portable (except for endianness and charset family, which can be changed with the icupkg tool) and modifiable (also with the icupkg tool). If a path is set, then single data files (e.g., .res files) can be copied to that location to provide new locale data or conversion tables etc.
|
||||
The only drawback with a .dat package file is that the application needs to provide ICU with the file system path to the package file (e.g., by calling `u_setDataDirectory()`) or with a pointer to the data (`udata_setCommonData()`) before other ICU API calls. This is usually easy if ICU is used from an application where `main()` takes care of such initialization. It may be hard if ICU is shipped with another shared library (such as the Xerces-C++ XML parser) which does not control `main()`.
|
||||
See the [User Guide ICU Data](http://userguide.icu-project.org/icudata) chapter for more details.
|
||||
See the [User Guide ICU Data](https://unicode-org.github.io/icu/userguide/icudata) chapter for more details.
|
||||
If possible, we recommend building the .dat package. Specify `--with-data-packaging=archive` on the configure command line, as in
|
||||
`runConfigureICU Linux --with-data-packaging=archive`
|
||||
(Read the configure script's output for further instructions. On Windows, the Visual Studio build generates both the .dat package and the data DLL.)
|
||||
@@ -416,7 +416,7 @@ Depending on the platform and the type of installation, we recommend a small num
|
||||
|
||||
#### ICU as a System-Level Library
|
||||
|
||||
If ICU is installed as a system-level library, there are further opportunities and restrictions to consider. For details, see the _Using ICU as an Operating System Level Library_ section of the [User Guide ICU Architectural Design](http://userguide.icu-project.org/design) chapter.
|
||||
If ICU is installed as a system-level library, there are further opportunities and restrictions to consider. For details, see the _Using ICU as an Operating System Level Library_ section of the [User Guide ICU Architectural Design](https://unicode-org.github.io/icu/userguide/design) chapter.
|
||||
|
||||
* **Data path:** For a system-level library, it is best to load ICU data from the .dat package file because the file system path to the .dat package file can be hardcoded. ICU will automatically set the path to the final install location using U_ICU_DATA_DEFAULT_DIR. Alternatively, you can set `-DICU_DATA_DIR=/path/to/icu/data` when building the ICU code. (Used by source/common/putil.c.)
|
||||
Consider also setting `-DICU_NO_USER_DATA_OVERRIDE` if you do not want the "ICU_DATA" environment variable to be used. (An application can still override the data path via `u_setDataDirectory()` or `udata_setCommonData()`.
|
||||
@@ -808,7 +808,7 @@ When changes have been made to the standard ICU distribution, it is recommended
|
||||
1. Add a suffix name to the library names. This can be done with the --with-library-suffix configure option.
|
||||
2. The installation script should install the ICU libraries into the application's directory.
|
||||
|
||||
Following these guidelines prevents other applications that use a standard ICU distribution from conflicting with any libraries that you need. On operating systems that do not have a standard C++ ABI (name mangling) for compilers, it is recommended to do this special packaging anyway. More details on customizing ICU are available in the [User's Guide](http://userguide.icu-project.org/). The [ICU Source Code Organization](#SourceCode) section of this readme.html gives a more complete description of the libraries.
|
||||
Following these guidelines prevents other applications that use a standard ICU distribution from conflicting with any libraries that you need. On operating systems that do not have a standard C++ ABI (name mangling) for compilers, it is recommended to do this special packaging anyway. More details on customizing ICU are available in the [User's Guide](https://unicode-org.github.io/icu/userguide/). The [ICU Source Code Organization](#SourceCode) section of this readme.html gives a more complete description of the libraries.
|
||||
|
||||
<table class="docTable" summary="ICU has several libraries for you to use."><caption>Here is an example of libraries that are frequently packaged.</caption>
|
||||
|
||||
@@ -834,7 +834,7 @@ Following these guidelines prevents other applications that use a standard ICU d
|
||||
|
||||
<td>libicudata.so._XY_._Z_</td>
|
||||
|
||||
<td>Data required by the Common and I18n libraries. There are many ways to package and [customize this data](http://userguide.icu-project.org/icudata), but by default this is all you need.</td>
|
||||
<td>Data required by the Common and I18n libraries. There are many ways to package and [customize this data](https://unicode-org.github.io/icu/userguide/icudata), but by default this is all you need.</td>
|
||||
|
||||
</tr>
|
||||
|
||||
@@ -982,7 +982,7 @@ If you are using ICU's Makefiles to build ICU on a new platform, there are a few
|
||||
|
||||
For some people, it may not be necessary for completely build ICU. Most of the makefiles and build targets are for tools that are used for building ICU's data, and an application's data (when an application uses ICU resource bundles for its data).
|
||||
|
||||
Data files can be built on a different platform when both platforms share the same endianness and the same charset family. This assertion does not include platform dependent DLLs/shared/static libraries. For details see the User Guide [ICU Data](http://userguide.icu-project.org/icudata) chapter.
|
||||
Data files can be built on a different platform when both platforms share the same endianness and the same charset family. This assertion does not include platform dependent DLLs/shared/static libraries. For details see the User Guide [ICU Data](https://unicode-org.github.io/icu/userguide/icudata) chapter.
|
||||
|
||||
ICU 3.6 removes the requirement that ICU be completely built in the native operating environment. It adds the icupkg tool which can be run on any platform to turn binary ICU data files from any one of the three formats into any one of the other data formats. This allows a application to use ICU data built anywhere to be used for any other target platform.
|
||||
|
||||
@@ -1027,4 +1027,4 @@ The platform dependencies have been mostly isolated into the following files in
|
||||
* * *
|
||||
|
||||
Copyright © 2016 and later: Unicode, Inc. and others. License & terms of use: [http://www.unicode.org/copyright.html](http://www.unicode.org/copyright.html)
|
||||
Copyright © 1997-2016 International Business Machines Corporation and others. All Rights Reserved.
|
||||
Copyright © 1997-2016 International Business Machines Corporation and others. All Rights Reserved.
|
||||
+547
-2009
File diff suppressed because it is too large.
Load diff
+322
-819
File diff suppressed because it is too large.
Load diff
+12
-11
@@ -47,7 +47,7 @@
|
||||
<p class="note only-rc">This is a release candidate version of ICU4C.
|
||||
It is not recommended for production use.</p>
|
||||
|
||||
<p>Last updated: 2020-Aug-27<br/>
|
||||
<p>Last updated: 2020-Oct-01<br/>
|
||||
Copyright © 2016 and later: Unicode, Inc. and others. License & terms of use:
|
||||
<a href="http://www.unicode.org/copyright.html">http://www.unicode.org/copyright.html</a><br/>
|
||||
Copyright © 1997-2016 International Business Machines Corporation and others.
|
||||
@@ -185,20 +185,21 @@
|
||||
<td>FAQ - Frequently Asked Questions about ICU</td>
|
||||
|
||||
<td><a href=
|
||||
"http://userguide.icu-project.org/icufaq">http://userguide.icu-project.org/icufaq</a></td>
|
||||
"https://unicode-org.github.io/icu/userguide/icufaq">https://unicode-org.github.io/icu/userguide/icufaq</a></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>ICU User's Guide</td>
|
||||
|
||||
<td><a href=
|
||||
"http://userguide.icu-project.org/">http://userguide.icu-project.org/</a></td>
|
||||
"https://unicode-org.github.io/icu/userguide/">https://unicode-org.github.io/icu/userguide/</a></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>How To Use ICU</td>
|
||||
|
||||
<td><a href="http://userguide.icu-project.org/howtouseicu">http://userguide.icu-project.org/howtouseicu</a></td>
|
||||
<td><a href=
|
||||
"https://unicode-org.github.io/icu/userguide/howtouseicu">https://unicode-org.github.io/icu/userguide/howtouseicu</a></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
@@ -284,7 +285,7 @@
|
||||
<p>In the descriptions below, <strong><i><ICU></i></strong> is the full
|
||||
path name of the ICU directory (the top level directory from the distribution
|
||||
archives) in your file system. You can also view the <a href=
|
||||
"http://userguide.icu-project.org/design">ICU Architectural
|
||||
"https://unicode-org.github.io/icu/userguide/design">ICU Architectural
|
||||
Design</a> section of the User's Guide to see which libraries you need for
|
||||
your software product. You need at least the data (<code>[lib]icudt</code>)
|
||||
and the common (<code>[lib]icuuc</code>) libraries in order to use ICU.</p>
|
||||
@@ -443,7 +444,7 @@
|
||||
environment variable to the out/ or the out/build/ directories, but
|
||||
this is generally discouraged because most people set it incorrectly.
|
||||
You can view the <a href=
|
||||
"http://userguide.icu-project.org/icudata">ICU Data
|
||||
"https://unicode-org.github.io/icu/userguide/icudata">ICU Data
|
||||
Management</a> section of the ICU User's Guide for details.</p>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -687,7 +688,7 @@
|
||||
It may be hard if ICU is shipped with
|
||||
another shared library (such as the Xerces-C++ XML parser)
|
||||
which does not control <code>main()</code>.<br />
|
||||
See the <a href="http://userguide.icu-project.org/icudata">User Guide ICU Data</a>
|
||||
See the <a href="https://unicode-org.github.io/icu/userguide/icudata">User Guide ICU Data</a>
|
||||
chapter for more details.<br />
|
||||
If possible, we recommend building the .dat package.
|
||||
Specify <code>--with-data-packaging=archive</code>
|
||||
@@ -723,7 +724,7 @@
|
||||
<p>If ICU is installed as a system-level library, there are further
|
||||
opportunities and restrictions to consider.
|
||||
For details, see the <em>Using ICU as an Operating System Level Library</em>
|
||||
section of the <a href="http://userguide.icu-project.org/design">User Guide ICU Architectural Design</a> chapter.</p>
|
||||
section of the <a href="https://unicode-org.github.io/icu/userguide/design">User Guide ICU Architectural Design</a> chapter.</p>
|
||||
<ul>
|
||||
<li><b>Data path:</b> For a system-level library, it is best to load
|
||||
ICU data from the .dat package file because the file system path
|
||||
@@ -1507,7 +1508,7 @@ gnumake</pre>
|
||||
operating systems that do not have a standard C++ ABI (name mangling) for
|
||||
compilers, it is recommended to do this special packaging anyway. More
|
||||
details on customizing ICU are available in the <a href=
|
||||
"http://userguide.icu-project.org/">User's Guide</a>. The <a href=
|
||||
"https://unicode-org.github.io/icu/userguide/">User's Guide</a>. The <a href=
|
||||
"#SourceCode">ICU Source Code Organization</a> section of this readme.html
|
||||
gives a more complete description of the libraries.</p>
|
||||
|
||||
@@ -1536,7 +1537,7 @@ gnumake</pre>
|
||||
|
||||
<td>Data required by the Common and I18n libraries. There are many ways
|
||||
to package and <a href=
|
||||
"http://userguide.icu-project.org/icudata">customize this
|
||||
"https://unicode-org.github.io/icu/userguide/icudata">customize this
|
||||
data</a>, but by default this is all you need.</td>
|
||||
</tr>
|
||||
|
||||
@@ -1790,7 +1791,7 @@ gnumake</pre>
|
||||
<p>Data files can be built on a different platform when both platforms share
|
||||
the same endianness and the same charset family. This assertion does not
|
||||
include platform dependent DLLs/shared/static libraries. For details see the
|
||||
User Guide <a href="http://userguide.icu-project.org/icudata">ICU
|
||||
User Guide <a href="https://unicode-org.github.io/icu/userguide/icudata">ICU
|
||||
Data</a> chapter.</p>
|
||||
|
||||
<p>ICU 3.6 removes the requirement that ICU be completely built in the native
|
||||
|
||||
Executable → Regular
File mode changed.
@@ -1252,11 +1252,11 @@ AliasReplacer::replaceLanguage(
|
||||
continue;
|
||||
}
|
||||
|
||||
const char* replacedLanguage;
|
||||
const char* replacedScript;
|
||||
const char* replacedRegion;
|
||||
const char* replacedVariant;
|
||||
const char* replacedExtensions;
|
||||
const char* replacedLanguage = nullptr;
|
||||
const char* replacedScript = nullptr;
|
||||
const char* replacedRegion = nullptr;
|
||||
const char* replacedVariant = nullptr;
|
||||
const char* replacedExtensions = nullptr;
|
||||
parseLanguageReplacement(replacement,
|
||||
replacedLanguage,
|
||||
replacedScript,
|
||||
@@ -1266,7 +1266,7 @@ AliasReplacer::replaceLanguage(
|
||||
toBeFreed,
|
||||
status);
|
||||
replacedLanguage =
|
||||
uprv_strcmp(replacedLanguage, "und") == 0 ?
|
||||
(replacedLanguage != nullptr && uprv_strcmp(replacedLanguage, "und") == 0) ?
|
||||
language : replacedLanguage;
|
||||
replacedScript = deleteOrReplace(script, nullptr, replacedScript);
|
||||
replacedRegion = deleteOrReplace(region, searchRegion, replacedRegion);
|
||||
|
||||
@@ -81,7 +81,7 @@
|
||||
#include <float.h>
|
||||
|
||||
#ifndef U_COMMON_IMPLEMENTATION
|
||||
#error U_COMMON_IMPLEMENTATION not set - must be set for all ICU source files in common/ - see http://userguide.icu-project.org/howtouseicu
|
||||
#error U_COMMON_IMPLEMENTATION not set - must be set for all ICU source files in common/ - see https://unicode-org.github.io/icu/userguide/howtouseicu
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -53,10 +53,10 @@
|
||||
*
|
||||
* <h2>Architecture (User's Guide)</h2>
|
||||
* <ul>
|
||||
* <li><a href="http://userguide.icu-project.org/">Introduction</a></li>
|
||||
* <li><a href="http://userguide.icu-project.org/i18n">Internationalization</a></li>
|
||||
* <li><a href="http://userguide.icu-project.org/design">Locale Model, Multithreading, Error Handling, etc.</a></li>
|
||||
* <li><a href="http://userguide.icu-project.org/conversion">Conversion</a></li>
|
||||
* <li><a href="https://unicode-org.github.io/icu/userguide/">Introduction</a></li>
|
||||
* <li><a href="https://unicode-org.github.io/icu/userguide/i18n">Internationalization</a></li>
|
||||
* <li><a href="https://unicode-org.github.io/icu/userguide/design">Locale Model, Multithreading, Error Handling, etc.</a></li>
|
||||
* <li><a href="https://unicode-org.github.io/icu/userguide/conversion">Conversion</a></li>
|
||||
* </ul>
|
||||
*
|
||||
* <hr>
|
||||
@@ -149,7 +149,7 @@
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>Number Range Formatting<br />(includes currency and unit ranges)</td>
|
||||
* <td>(no C API)</td>
|
||||
* <td>unumberrangeformatter.h</td>
|
||||
* <td>icu::number::NumberRangeFormatter</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
|
||||
@@ -306,7 +306,7 @@ udata_getInfo(UDataMemory *pData, UDataInfo *pInfo);
|
||||
* area in memory.
|
||||
*
|
||||
* ICU data must be at least 8-aligned, and should be 16-aligned.
|
||||
* See http://userguide.icu-project.org/icudata
|
||||
* See https://unicode-org.github.io/icu/userguide/icudata
|
||||
*
|
||||
* The format of this data is that of the icu common data file, as is
|
||||
* generated by the pkgdata tool with mode=common or mode=dll.
|
||||
@@ -353,7 +353,7 @@ udata_setCommonData(const void *data, UErrorCode *err);
|
||||
* pointer.
|
||||
*
|
||||
* ICU data must be at least 8-aligned, and should be 16-aligned.
|
||||
* See http://userguide.icu-project.org/icudata
|
||||
* See https://unicode-org.github.io/icu/userguide/icudata
|
||||
*
|
||||
* The format of this data is that of the icu common data file, like 'icudt26l.dat'
|
||||
* or the corresponding shared library (DLL) file.
|
||||
|
||||
@@ -227,7 +227,7 @@ class UnicodeStringAppendable; // unicode/appendable.h
|
||||
* The UnicodeString class is not suitable for subclassing.
|
||||
*
|
||||
* For an overview of Unicode strings in C and C++ see the
|
||||
* [User Guide Strings chapter](http://userguide.icu-project.org/strings#TOC-Strings-in-C-C-).
|
||||
* [User Guide Strings chapter](https://unicode-org.github.io/icu/userguide/strings#strings-in-cc).
|
||||
*
|
||||
* In ICU, a Unicode string consists of 16-bit Unicode *code units*.
|
||||
* A Unicode character may be stored with either one code unit
|
||||
@@ -285,7 +285,7 @@ class UnicodeStringAppendable; // unicode/appendable.h
|
||||
* significant performance improvements.
|
||||
* Also, the internal buffer is accessible via special functions.
|
||||
* For details see the
|
||||
* [User Guide Strings chapter](http://userguide.icu-project.org/strings#TOC-Maximizing-Performance-with-the-UnicodeString-Storage-Model).
|
||||
* [User Guide Strings chapter](https://unicode-org.github.io/icu/userguide/strings#maximizing-performance-with-the-unicodestring-storage-model).
|
||||
*
|
||||
* @see utf.h
|
||||
* @see CharacterIterator
|
||||
|
||||
@@ -103,7 +103,7 @@
|
||||
* code point values (0..U+10ffff). They are indicated with negative values instead.
|
||||
*
|
||||
* For more information see the ICU User Guide Strings chapter
|
||||
* (http://userguide.icu-project.org/strings).
|
||||
* (https://unicode-org.github.io/icu/userguide/strings).
|
||||
*
|
||||
* <em>Usage:</em>
|
||||
* ICU coding guidelines for if() statements should be followed when using these macros.
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
* This file defines macros to deal with 16-bit Unicode (UTF-16) code units and strings.
|
||||
*
|
||||
* For more information see utf.h and the ICU User Guide Strings chapter
|
||||
* (http://userguide.icu-project.org/strings).
|
||||
* (https://unicode-org.github.io/icu/userguide/strings).
|
||||
*
|
||||
* <em>Usage:</em>
|
||||
* ICU coding guidelines for if() statements should be followed when using these macros.
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
* This file defines macros to deal with 8-bit Unicode (UTF-8) code units (bytes) and strings.
|
||||
*
|
||||
* For more information see utf.h and the ICU User Guide Strings chapter
|
||||
* (http://userguide.icu-project.org/strings).
|
||||
* (https://unicode-org.github.io/icu/userguide/strings).
|
||||
*
|
||||
* <em>Usage:</em>
|
||||
* ICU coding guidelines for if() statements should be followed when using these macros.
|
||||
|
||||
@@ -148,7 +148,7 @@
|
||||
* Until ICU 4.8, this was the combination of the single-digit major and minor ICU version numbers
|
||||
* into one string without dots ("48").
|
||||
* Since ICU 49, it is the double-digit major ICU version number.
|
||||
* See http://userguide.icu-project.org/design#TOC-Version-Numbers-in-ICU
|
||||
* See https://unicode-org.github.io/icu/userguide/design#version-numbers-in-icu
|
||||
*
|
||||
* @stable ICU 2.6
|
||||
*/
|
||||
|
||||
@@ -98,7 +98,7 @@ usage()
|
||||
echo "Copyright (c) 2002-2013, International Business Machines Corporation and others. All Rights Reserved."
|
||||
echo
|
||||
echo "NOTE: Please consider using the pkg-config (.pc) files instead of icu-config."
|
||||
echo " See: <http://userguide.icu-project.org/howtouseicu#TOC-pkg-config> "
|
||||
echo " See: <https://unicode-org.github.io/icu/userguide/howtouseicu> "
|
||||
}
|
||||
|
||||
## Check the sanity of current variables
|
||||
|
||||
Vendored
+1
-1
@@ -1477,7 +1477,7 @@ Optional Packages:
|
||||
library shared library (.dll/.so/etc.)
|
||||
static static library (.a/.lib/etc.)
|
||||
auto build shared if possible (default)
|
||||
See http://userguide.icu-project.org/icudata for more info.
|
||||
See https://unicode-org.github.io/icu/userguide/icudata for more info.
|
||||
--with-library-suffix=suffix tag a suffix to the library names default=
|
||||
|
||||
Some influential environment variables:
|
||||
|
||||
@@ -1152,7 +1152,7 @@ AC_ARG_WITH(data-packaging,
|
||||
library shared library (.dll/.so/etc.)
|
||||
static static library (.a/.lib/etc.)
|
||||
auto build shared if possible (default)
|
||||
See http://userguide.icu-project.org/icudata for more info.],
|
||||
See https://unicode-org.github.io/icu/userguide/icudata for more info.],
|
||||
[case "${withval}" in
|
||||
files|archive|library) datapackaging=$withval ;;
|
||||
auto) datapackaging=$withval ;;
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
# Note that the entire block for the supplementary Unicode planes is
|
||||
# marked unassigned because they are handled algorithmically.
|
||||
# Similarly, some of the BMP mappings are marked as unassigned for the same reason.
|
||||
# See http://userguide.icu-project.org/conversion/data#TOC-State-table-syntax-in-.ucm-files
|
||||
# See https://unicode-org.github.io/icu/userguide/conversion/data#state-table-syntax-in-ucm-files
|
||||
|
||||
# States 0..2:
|
||||
# Mostly assigned sequences, with branches in the lead bytes
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#include "unicode/utypes.h"
|
||||
|
||||
#ifndef U_I18N_IMPLEMENTATION
|
||||
#error U_I18N_IMPLEMENTATION not set - must be set for all ICU source files in i18n/ - see http://userguide.icu-project.org/howtouseicu
|
||||
#error U_I18N_IMPLEMENTATION not set - must be set for all ICU source files in i18n/ - see https://unicode-org.github.io/icu/userguide/howtouseicu
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
||||
@@ -612,21 +612,7 @@ static const char * const gSubTypes[] = {
|
||||
"teaspoon"
|
||||
};
|
||||
|
||||
// Must be sorted by first value and then second value.
|
||||
static int32_t unitPerUnitToSingleUnit[][4] = {
|
||||
{374, 383, 12, 1},
|
||||
{374, 389, 12, 2},
|
||||
{379, 383, 12, 6},
|
||||
{379, 389, 12, 7},
|
||||
{390, 343, 19, 0},
|
||||
{392, 350, 19, 2},
|
||||
{394, 343, 19, 3},
|
||||
{394, 472, 4, 2},
|
||||
{394, 473, 4, 3},
|
||||
{416, 465, 3, 1},
|
||||
{419, 12, 18, 9},
|
||||
{476, 390, 4, 1}
|
||||
};
|
||||
// unitPerUnitToSingleUnit no longer in use! TODO: remove from code-generation code.
|
||||
|
||||
// Shortcuts to the base unit in order to make the default constructor fast
|
||||
static const int32_t kBaseTypeIdx = 16;
|
||||
@@ -2301,41 +2287,6 @@ bool MeasureUnit::findBySubType(StringPiece subType, MeasureUnit* output) {
|
||||
return false;
|
||||
}
|
||||
|
||||
MeasureUnit MeasureUnit::resolveUnitPerUnit(
|
||||
const MeasureUnit &unit, const MeasureUnit &perUnit, bool* isResolved) {
|
||||
int32_t unitOffset = unit.getOffset();
|
||||
int32_t perUnitOffset = perUnit.getOffset();
|
||||
if (unitOffset == -1 || perUnitOffset == -1) {
|
||||
*isResolved = false;
|
||||
return MeasureUnit();
|
||||
}
|
||||
|
||||
// binary search for (unitOffset, perUnitOffset)
|
||||
int32_t start = 0;
|
||||
int32_t end = UPRV_LENGTHOF(unitPerUnitToSingleUnit);
|
||||
while (start < end) {
|
||||
int32_t mid = (start + end) / 2;
|
||||
int32_t *midRow = unitPerUnitToSingleUnit[mid];
|
||||
if (unitOffset < midRow[0]) {
|
||||
end = mid;
|
||||
} else if (unitOffset > midRow[0]) {
|
||||
start = mid + 1;
|
||||
} else if (perUnitOffset < midRow[1]) {
|
||||
end = mid;
|
||||
} else if (perUnitOffset > midRow[1]) {
|
||||
start = mid + 1;
|
||||
} else {
|
||||
// We found a resolution for our unit / per-unit combo
|
||||
// return it.
|
||||
*isResolved = true;
|
||||
return MeasureUnit(midRow[2], midRow[3]);
|
||||
}
|
||||
}
|
||||
|
||||
*isResolved = false;
|
||||
return MeasureUnit();
|
||||
}
|
||||
|
||||
MeasureUnit *MeasureUnit::create(int typeId, int subTypeId, UErrorCode &status) {
|
||||
if (U_FAILURE(status)) {
|
||||
return NULL;
|
||||
|
||||
@@ -223,24 +223,16 @@ void LongNameHandler::forMeasureUnit(const Locale &loc, const MeasureUnit &unitR
|
||||
LongNameHandler *fillIn, UErrorCode &status) {
|
||||
// Not valid for mixed units that aren't built-in units, and there should
|
||||
// not be any built-in mixed units!
|
||||
U_ASSERT(uprv_strlen(unitRef.getType()) > 0 || unitRef.getComplexity(status) != UMEASURE_UNIT_MIXED);
|
||||
U_ASSERT(uprv_strcmp(unitRef.getType(), "") != 0 ||
|
||||
unitRef.getComplexity(status) != UMEASURE_UNIT_MIXED);
|
||||
U_ASSERT(fillIn != nullptr);
|
||||
if (uprv_strlen(unitRef.getType()) == 0 || uprv_strlen(perUnit.getType()) == 0) {
|
||||
// TODO(ICU-20941): Unsanctioned unit. Not yet fully supported. Set an
|
||||
// error code. Once we support not-built-in units here, unitRef may be
|
||||
// anything, but if not built-in, perUnit has to be "none".
|
||||
status = U_UNSUPPORTED_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
MeasureUnit unit = unitRef;
|
||||
if (uprv_strcmp(perUnit.getType(), "none") != 0) {
|
||||
// Compound unit: first try to simplify (e.g. "meter per second" is a
|
||||
// built-in unit).
|
||||
bool isResolved = false;
|
||||
MeasureUnit resolved = MeasureUnit::resolveUnitPerUnit(unit, perUnit, &isResolved);
|
||||
if (isResolved) {
|
||||
unit = resolved;
|
||||
// Compound unit: first try to simplify (e.g., meters per second is its own unit).
|
||||
MeasureUnit simplified = unit.product(perUnit.reciprocal(status), status);
|
||||
if (uprv_strcmp(simplified.getType(), "") != 0) {
|
||||
unit = simplified;
|
||||
} else {
|
||||
// No simplified form is available.
|
||||
forCompoundUnit(loc, unit, perUnit, width, rules, parent, fillIn, status);
|
||||
@@ -248,6 +240,14 @@ void LongNameHandler::forMeasureUnit(const Locale &loc, const MeasureUnit &unitR
|
||||
}
|
||||
}
|
||||
|
||||
if (uprv_strcmp(unit.getType(), "") == 0) {
|
||||
// TODO(ICU-20941): Unsanctioned unit. Not yet fully supported. Set an
|
||||
// error code. Once we support not-built-in units here, unitRef may be
|
||||
// anything, but if not built-in, perUnit has to be "none".
|
||||
status = U_UNSUPPORTED_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
UnicodeString simpleFormats[ARRAY_LENGTH];
|
||||
getMeasureData(loc, unit, width, simpleFormats, status);
|
||||
if (U_FAILURE(status)) {
|
||||
@@ -263,6 +263,13 @@ void LongNameHandler::forCompoundUnit(const Locale &loc, const MeasureUnit &unit
|
||||
const MeasureUnit &perUnit, const UNumberUnitWidth &width,
|
||||
const PluralRules *rules, const MicroPropsGenerator *parent,
|
||||
LongNameHandler *fillIn, UErrorCode &status) {
|
||||
if (uprv_strcmp(unit.getType(), "") == 0 || uprv_strcmp(perUnit.getType(), "") == 0) {
|
||||
// TODO(ICU-20941): Unsanctioned unit. Not yet fully supported. Set an
|
||||
// error code. Once we support not-built-in units here, unitRef may be
|
||||
// anything, but if not built-in, perUnit has to be "none".
|
||||
status = U_UNSUPPORTED_ERROR;
|
||||
return;
|
||||
}
|
||||
if (fillIn == nullptr) {
|
||||
status = U_INTERNAL_PROGRAM_ERROR;
|
||||
return;
|
||||
@@ -455,6 +462,8 @@ const Modifier *MixedUnitLongNameHandler::getMixedUnitModifier(DecimalQuantity &
|
||||
status = U_UNSUPPORTED_ERROR;
|
||||
return µs.helpers.emptyWeakModifier;
|
||||
}
|
||||
// If we don't have at least one mixedMeasure, the LongNameHandler would be
|
||||
// sufficient and we shouldn't be running MixedUnitLongNameHandler code:
|
||||
U_ASSERT(micros.mixedMeasuresCount > 0);
|
||||
// mixedMeasures does not contain the last value:
|
||||
U_ASSERT(fMixedUnitCount == micros.mixedMeasuresCount + 1);
|
||||
@@ -486,6 +495,11 @@ const Modifier *MixedUnitLongNameHandler::getMixedUnitModifier(DecimalQuantity &
|
||||
for (int32_t i = 0; i < micros.mixedMeasuresCount; i++) {
|
||||
DecimalQuantity fdec;
|
||||
fdec.setToLong(micros.mixedMeasures[i]);
|
||||
if (i > 0 && fdec.isNegative()) {
|
||||
// If numbers are negative, only the first number needs to have its
|
||||
// negative sign formatted.
|
||||
fdec.negate();
|
||||
}
|
||||
StandardPlural::Form pluralForm = utils::getStandardPlural(rules, fdec);
|
||||
|
||||
UnicodeString simpleFormat =
|
||||
@@ -499,6 +513,13 @@ const Modifier *MixedUnitLongNameHandler::getMixedUnitModifier(DecimalQuantity &
|
||||
// TODO(icu-units#67): fix field positions
|
||||
}
|
||||
|
||||
// Reiterated: we have at least one mixedMeasure:
|
||||
U_ASSERT(micros.mixedMeasuresCount > 0);
|
||||
// Thus if negative, a negative has already been formatted:
|
||||
if (quantity.isNegative()) {
|
||||
quantity.negate();
|
||||
}
|
||||
|
||||
UnicodeString *finalSimpleFormats = &fMixedUnitData[(fMixedUnitCount - 1) * ARRAY_LENGTH];
|
||||
StandardPlural::Form finalPlural = utils::getPluralSafe(micros.rounder, rules, quantity, status);
|
||||
UnicodeString finalSimpleFormat = getWithPlural(finalSimpleFormats, finalPlural, status);
|
||||
|
||||
@@ -843,10 +843,6 @@ void GeneratorHelpers::generateSkeleton(const MacroProps& macros, UnicodeString&
|
||||
sb.append(u' ');
|
||||
}
|
||||
if (U_FAILURE(status)) { return; }
|
||||
if (GeneratorHelpers::perUnit(macros, sb, status)) {
|
||||
sb.append(u' ');
|
||||
}
|
||||
if (U_FAILURE(status)) { return; }
|
||||
if (GeneratorHelpers::usage(macros, sb, status)) {
|
||||
sb.append(u' ');
|
||||
}
|
||||
@@ -1025,14 +1021,6 @@ void blueprint_helpers::parseMeasureUnitOption(const StringSegment& segment, Mac
|
||||
status = U_NUMBER_SKELETON_SYNTAX_ERROR;
|
||||
}
|
||||
|
||||
void blueprint_helpers::generateMeasureUnitOption(const MeasureUnit& measureUnit, UnicodeString& sb,
|
||||
UErrorCode&) {
|
||||
// Need to do char <-> UChar conversion...
|
||||
sb.append(UnicodeString(measureUnit.getType(), -1, US_INV));
|
||||
sb.append(u'-');
|
||||
sb.append(UnicodeString(measureUnit.getSubtype(), -1, US_INV));
|
||||
}
|
||||
|
||||
void blueprint_helpers::parseMeasurePerUnitOption(const StringSegment& segment, MacroProps& macros,
|
||||
UErrorCode& status) {
|
||||
// A little bit of a hack: save the current unit (numerator), call the main measure unit
|
||||
@@ -1059,15 +1047,21 @@ void blueprint_helpers::parseIdentifierUnitOption(const StringSegment& segment,
|
||||
return;
|
||||
}
|
||||
|
||||
// Mixed units can only be represented by a full MeasureUnit instances, so
|
||||
// we ignore macros.perUnit.
|
||||
// Mixed units can only be represented by full MeasureUnit instances, so we
|
||||
// don't split the denominator into macros.perUnit.
|
||||
if (fullUnit.complexity == UMEASURE_UNIT_MIXED) {
|
||||
macros.unit = std::move(fullUnit).build(status);
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO(ICU-20941): Clean this up (see also
|
||||
// https://github.com/icu-units/icu/issues/35).
|
||||
// When we have a built-in unit (e.g. meter-per-second), we don't split it up
|
||||
MeasureUnit testBuiltin = fullUnit.copy(status).build(status);
|
||||
if (uprv_strcmp(testBuiltin.getType(), "") != 0) {
|
||||
macros.unit = std::move(testBuiltin);
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO(ICU-20941): Clean this up.
|
||||
for (int32_t i = 0; i < fullUnit.units.length(); i++) {
|
||||
SingleUnitImpl* subUnit = fullUnit.units[i];
|
||||
if (subUnit->dimensionality > 0) {
|
||||
@@ -1523,28 +1517,17 @@ bool GeneratorHelpers::unit(const MacroProps& macros, UnicodeString& sb, UErrorC
|
||||
} else if (utils::unitIsPermille(macros.unit)) {
|
||||
sb.append(u"permille", -1);
|
||||
return true;
|
||||
} else if (uprv_strcmp(macros.unit.getType(), "") != 0) {
|
||||
sb.append(u"measure-unit/", -1);
|
||||
blueprint_helpers::generateMeasureUnitOption(macros.unit, sb, status);
|
||||
return true;
|
||||
} else {
|
||||
// TODO(icu-units#35): add support for not-built-in units.
|
||||
status = U_UNSUPPORTED_ERROR;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool GeneratorHelpers::perUnit(const MacroProps& macros, UnicodeString& sb, UErrorCode& status) {
|
||||
// Per-units are currently expected to be only MeasureUnits.
|
||||
if (utils::unitIsBaseUnit(macros.perUnit)) {
|
||||
// Default value: ok to ignore
|
||||
return false;
|
||||
} else if (utils::unitIsCurrency(macros.perUnit)) {
|
||||
status = U_UNSUPPORTED_ERROR;
|
||||
return false;
|
||||
} else {
|
||||
sb.append(u"per-measure-unit/", -1);
|
||||
blueprint_helpers::generateMeasureUnitOption(macros.perUnit, sb, status);
|
||||
MeasureUnit unit = macros.unit;
|
||||
if (utils::unitIsCurrency(macros.perUnit)) {
|
||||
status = U_UNSUPPORTED_ERROR;
|
||||
return false;
|
||||
}
|
||||
if (!utils::unitIsBaseUnit(macros.perUnit)) {
|
||||
unit = unit.product(macros.perUnit.reciprocal(status), status);
|
||||
}
|
||||
sb.append(u"unit/", -1);
|
||||
sb.append(unit.getIdentifier());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -240,10 +240,10 @@ void parseCurrencyOption(const StringSegment& segment, MacroProps& macros, UErro
|
||||
|
||||
void generateCurrencyOption(const CurrencyUnit& currency, UnicodeString& sb, UErrorCode& status);
|
||||
|
||||
// "measure-unit/" is deprecated in favour of "unit/".
|
||||
void parseMeasureUnitOption(const StringSegment& segment, MacroProps& macros, UErrorCode& status);
|
||||
|
||||
void generateMeasureUnitOption(const MeasureUnit& measureUnit, UnicodeString& sb, UErrorCode& status);
|
||||
|
||||
// "per-measure-unit/" is deprecated in favour of "unit/".
|
||||
void parseMeasurePerUnitOption(const StringSegment& segment, MacroProps& macros, UErrorCode& status);
|
||||
|
||||
/**
|
||||
@@ -314,8 +314,6 @@ class GeneratorHelpers {
|
||||
|
||||
static bool unit(const MacroProps& macros, UnicodeString& sb, UErrorCode& status);
|
||||
|
||||
static bool perUnit(const MacroProps& macros, UnicodeString& sb, UErrorCode& status);
|
||||
|
||||
static bool usage(const MacroProps& macros, UnicodeString& sb, UErrorCode& status);
|
||||
|
||||
static bool precision(const MacroProps& macros, UnicodeString& sb, UErrorCode& status);
|
||||
|
||||
+125
-23
@@ -378,9 +378,23 @@ static double scaleForInt(double d) {
|
||||
return scale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method for the overrides of getSamples() for double and FixedDecimal
|
||||
* return value types. Provide only one of an allocated array of doubles or
|
||||
* FixedDecimals, and a nullptr for the other.
|
||||
*/
|
||||
static int32_t
|
||||
getSamplesFromString(const UnicodeString &samples, double *dest,
|
||||
int32_t destCapacity, UErrorCode& status) {
|
||||
getSamplesFromString(const UnicodeString &samples, double *destDbl,
|
||||
FixedDecimal* destFd, int32_t destCapacity,
|
||||
UErrorCode& status) {
|
||||
|
||||
if ((destDbl == nullptr && destFd == nullptr)
|
||||
|| (destDbl != nullptr && destFd != nullptr)) {
|
||||
status = U_INTERNAL_PROGRAM_ERROR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool isDouble = destDbl != nullptr;
|
||||
int32_t sampleCount = 0;
|
||||
int32_t sampleStartIdx = 0;
|
||||
int32_t sampleEndIdx = 0;
|
||||
@@ -398,9 +412,13 @@ getSamplesFromString(const UnicodeString &samples, double *dest,
|
||||
int32_t tildeIndex = sampleRange.indexOf(TILDE);
|
||||
if (tildeIndex < 0) {
|
||||
FixedDecimal fixed(sampleRange, status);
|
||||
double sampleValue = fixed.source;
|
||||
if (fixed.visibleDecimalDigitCount == 0 || sampleValue != floor(sampleValue)) {
|
||||
dest[sampleCount++] = sampleValue;
|
||||
if (isDouble) {
|
||||
double sampleValue = fixed.source;
|
||||
if (fixed.visibleDecimalDigitCount == 0 || sampleValue != floor(sampleValue)) {
|
||||
destDbl[sampleCount++] = sampleValue;
|
||||
}
|
||||
} else {
|
||||
destFd[sampleCount++] = fixed;
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -427,14 +445,21 @@ getSamplesFromString(const UnicodeString &samples, double *dest,
|
||||
rangeLo *= scale;
|
||||
rangeHi *= scale;
|
||||
for (double n=rangeLo; n<=rangeHi; n+=1) {
|
||||
// Hack Alert: don't return any decimal samples with integer values that
|
||||
// originated from a format with trailing decimals.
|
||||
// This API is returning doubles, which can't distinguish having displayed
|
||||
// zeros to the right of the decimal.
|
||||
// This results in test failures with values mapping back to a different keyword.
|
||||
double sampleValue = n/scale;
|
||||
if (!(sampleValue == floor(sampleValue) && fixedLo.visibleDecimalDigitCount > 0)) {
|
||||
dest[sampleCount++] = sampleValue;
|
||||
if (isDouble) {
|
||||
// Hack Alert: don't return any decimal samples with integer values that
|
||||
// originated from a format with trailing decimals.
|
||||
// This API is returning doubles, which can't distinguish having displayed
|
||||
// zeros to the right of the decimal.
|
||||
// This results in test failures with values mapping back to a different keyword.
|
||||
if (!(sampleValue == floor(sampleValue) && fixedLo.visibleDecimalDigitCount > 0)) {
|
||||
destDbl[sampleCount++] = sampleValue;
|
||||
}
|
||||
} else {
|
||||
int32_t v = (int32_t) fixedLo.getPluralOperand(PluralOperand::PLURAL_OPERAND_V);
|
||||
int32_t e = (int32_t) fixedLo.getPluralOperand(PluralOperand::PLURAL_OPERAND_E);
|
||||
FixedDecimal newSample = FixedDecimal::createWithExponent(sampleValue, v, e);
|
||||
destFd[sampleCount++] = newSample;
|
||||
}
|
||||
if (sampleCount >= destCapacity) {
|
||||
break;
|
||||
@@ -446,24 +471,52 @@ getSamplesFromString(const UnicodeString &samples, double *dest,
|
||||
return sampleCount;
|
||||
}
|
||||
|
||||
|
||||
int32_t
|
||||
PluralRules::getSamples(const UnicodeString &keyword, double *dest,
|
||||
int32_t destCapacity, UErrorCode& status) {
|
||||
if (destCapacity == 0 || U_FAILURE(status)) {
|
||||
if (U_FAILURE(status)) {
|
||||
return 0;
|
||||
}
|
||||
if (U_FAILURE(mInternalStatus)) {
|
||||
status = mInternalStatus;
|
||||
return 0;
|
||||
}
|
||||
if (dest != nullptr ? destCapacity < 0 : destCapacity != 0) {
|
||||
status = U_ILLEGAL_ARGUMENT_ERROR;
|
||||
return 0;
|
||||
}
|
||||
RuleChain *rc = rulesForKeyword(keyword);
|
||||
if (rc == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
int32_t numSamples = getSamplesFromString(rc->fIntegerSamples, dest, destCapacity, status);
|
||||
int32_t numSamples = getSamplesFromString(rc->fIntegerSamples, dest, nullptr, destCapacity, status);
|
||||
if (numSamples == 0) {
|
||||
numSamples = getSamplesFromString(rc->fDecimalSamples, dest, destCapacity, status);
|
||||
numSamples = getSamplesFromString(rc->fDecimalSamples, dest, nullptr, destCapacity, status);
|
||||
}
|
||||
return numSamples;
|
||||
}
|
||||
|
||||
int32_t
|
||||
PluralRules::getSamples(const UnicodeString &keyword, FixedDecimal *dest,
|
||||
int32_t destCapacity, UErrorCode& status) {
|
||||
if (U_FAILURE(status)) {
|
||||
return 0;
|
||||
}
|
||||
if (U_FAILURE(mInternalStatus)) {
|
||||
status = mInternalStatus;
|
||||
return 0;
|
||||
}
|
||||
if (dest != nullptr ? destCapacity < 0 : destCapacity != 0) {
|
||||
status = U_ILLEGAL_ARGUMENT_ERROR;
|
||||
return 0;
|
||||
}
|
||||
RuleChain *rc = rulesForKeyword(keyword);
|
||||
if (rc == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
int32_t numSamples = getSamplesFromString(rc->fIntegerSamples, nullptr, dest, destCapacity, status);
|
||||
if (numSamples == 0) {
|
||||
numSamples = getSamplesFromString(rc->fDecimalSamples, nullptr, dest, destCapacity, status);
|
||||
}
|
||||
return numSamples;
|
||||
}
|
||||
@@ -1548,8 +1601,8 @@ PluralOperand tokenTypeToPluralOperand(tokenType tt) {
|
||||
}
|
||||
}
|
||||
|
||||
FixedDecimal::FixedDecimal(double n, int32_t v, int64_t f) {
|
||||
init(n, v, f);
|
||||
FixedDecimal::FixedDecimal(double n, int32_t v, int64_t f, int32_t e) {
|
||||
init(n, v, f, e);
|
||||
// check values. TODO make into unit test.
|
||||
//
|
||||
// long visiblePower = (int) Math.pow(10, v);
|
||||
@@ -1565,6 +1618,10 @@ FixedDecimal::FixedDecimal(double n, int32_t v, int64_t f) {
|
||||
// }
|
||||
}
|
||||
|
||||
FixedDecimal::FixedDecimal(double n, int32_t v, int64_t f) {
|
||||
init(n, v, f);
|
||||
}
|
||||
|
||||
FixedDecimal::FixedDecimal(double n, int32_t v) {
|
||||
// Ugly, but for samples we don't care.
|
||||
init(n, v, getFractionalDigits(n, v));
|
||||
@@ -1584,20 +1641,36 @@ FixedDecimal::FixedDecimal() {
|
||||
|
||||
FixedDecimal::FixedDecimal(const UnicodeString &num, UErrorCode &status) {
|
||||
CharString cs;
|
||||
cs.appendInvariantChars(num, status);
|
||||
int32_t parsedExponent = 0;
|
||||
|
||||
int32_t exponentIdx = num.indexOf(u'e');
|
||||
if (exponentIdx < 0) {
|
||||
exponentIdx = num.indexOf(u'E');
|
||||
}
|
||||
if (exponentIdx >= 0) {
|
||||
cs.appendInvariantChars(num.tempSubString(0, exponentIdx), status);
|
||||
int32_t expSubstrStart = exponentIdx + 1;
|
||||
parsedExponent = ICU_Utility::parseAsciiInteger(num, expSubstrStart);
|
||||
}
|
||||
else {
|
||||
cs.appendInvariantChars(num, status);
|
||||
}
|
||||
|
||||
DecimalQuantity dl;
|
||||
dl.setToDecNumber(cs.toStringPiece(), status);
|
||||
if (U_FAILURE(status)) {
|
||||
init(0, 0, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t decimalPoint = num.indexOf(DOT);
|
||||
double n = dl.toDouble();
|
||||
if (decimalPoint == -1) {
|
||||
init(n, 0, 0);
|
||||
init(n, 0, 0, parsedExponent);
|
||||
} else {
|
||||
int32_t v = num.length() - decimalPoint - 1;
|
||||
init(n, v, getFractionalDigits(n, v));
|
||||
int32_t fractionNumLength = exponentIdx < 0 ? num.length() : cs.length();
|
||||
int32_t v = fractionNumLength - decimalPoint - 1;
|
||||
init(n, v, getFractionalDigits(n, v), parsedExponent);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1608,6 +1681,7 @@ FixedDecimal::FixedDecimal(const FixedDecimal &other) {
|
||||
decimalDigits = other.decimalDigits;
|
||||
decimalDigitsWithoutTrailingZeros = other.decimalDigitsWithoutTrailingZeros;
|
||||
intValue = other.intValue;
|
||||
exponent = other.exponent;
|
||||
_hasIntegerValue = other._hasIntegerValue;
|
||||
isNegative = other.isNegative;
|
||||
_isNaN = other._isNaN;
|
||||
@@ -1616,6 +1690,10 @@ FixedDecimal::FixedDecimal(const FixedDecimal &other) {
|
||||
|
||||
FixedDecimal::~FixedDecimal() = default;
|
||||
|
||||
FixedDecimal FixedDecimal::createWithExponent(double n, int32_t v, int32_t e) {
|
||||
return FixedDecimal(n, v, getFractionalDigits(n, v), e);
|
||||
}
|
||||
|
||||
|
||||
void FixedDecimal::init(double n) {
|
||||
int32_t numFractionDigits = decimals(n);
|
||||
@@ -1624,10 +1702,17 @@ void FixedDecimal::init(double n) {
|
||||
|
||||
|
||||
void FixedDecimal::init(double n, int32_t v, int64_t f) {
|
||||
int32_t exponent = 0;
|
||||
init(n, v, f, exponent);
|
||||
}
|
||||
|
||||
|
||||
void FixedDecimal::init(double n, int32_t v, int64_t f, int32_t e) {
|
||||
isNegative = n < 0.0;
|
||||
source = fabs(n);
|
||||
_isNaN = uprv_isNaN(source);
|
||||
_isInfinite = uprv_isInfinite(source);
|
||||
exponent = e;
|
||||
if (_isNaN || _isInfinite) {
|
||||
v = 0;
|
||||
f = 0;
|
||||
@@ -1757,7 +1842,7 @@ double FixedDecimal::getPluralOperand(PluralOperand operand) const {
|
||||
case PLURAL_OPERAND_F: return static_cast<double>(decimalDigits);
|
||||
case PLURAL_OPERAND_T: return static_cast<double>(decimalDigitsWithoutTrailingZeros);
|
||||
case PLURAL_OPERAND_V: return visibleDecimalDigitCount;
|
||||
case PLURAL_OPERAND_E: return 0;
|
||||
case PLURAL_OPERAND_E: return exponent;
|
||||
default:
|
||||
UPRV_UNREACHABLE; // unexpected.
|
||||
}
|
||||
@@ -1783,6 +1868,23 @@ int32_t FixedDecimal::getVisibleFractionDigitCount() const {
|
||||
return visibleDecimalDigitCount;
|
||||
}
|
||||
|
||||
bool FixedDecimal::operator==(const FixedDecimal &other) const {
|
||||
return source == other.source && visibleDecimalDigitCount == other.visibleDecimalDigitCount
|
||||
&& decimalDigits == other.decimalDigits && exponent == other.exponent;
|
||||
}
|
||||
|
||||
UnicodeString FixedDecimal::toString() const {
|
||||
char pattern[15];
|
||||
char buffer[20];
|
||||
if (exponent == 0) {
|
||||
snprintf(pattern, sizeof(pattern), "%%.%df", visibleDecimalDigitCount);
|
||||
snprintf(buffer, sizeof(buffer), pattern, source);
|
||||
} else {
|
||||
snprintf(pattern, sizeof(pattern), "%%.%dfe%%d", visibleDecimalDigitCount);
|
||||
snprintf(buffer, sizeof(buffer), pattern, source, exponent);
|
||||
}
|
||||
return UnicodeString(buffer, -1, US_INV);
|
||||
}
|
||||
|
||||
|
||||
PluralAvailableLocalesEnumeration::PluralAvailableLocalesEnumeration(UErrorCode &status) {
|
||||
|
||||
@@ -30,6 +30,12 @@
|
||||
#include "hash.h"
|
||||
#include "uassert.h"
|
||||
|
||||
/**
|
||||
* A FixedDecimal version of UPLRULES_NO_UNIQUE_VALUE used in PluralRulesTest
|
||||
* for parsing of samples.
|
||||
*/
|
||||
#define UPLRULES_NO_UNIQUE_VALUE_DECIMAL (FixedDecimal((double)-0.00123456777))
|
||||
|
||||
class PluralRulesTest;
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
@@ -274,7 +280,9 @@ class U_I18N_API FixedDecimal: public IFixedDecimal, public UObject {
|
||||
* @param n the number, e.g. 12.345
|
||||
* @param v The number of visible fraction digits, e.g. 3
|
||||
* @param f The fraction digits, e.g. 345
|
||||
* @param e The exponent, e.g. 7 in 1.2e7 (for compact/scientific)
|
||||
*/
|
||||
FixedDecimal(double n, int32_t v, int64_t f, int32_t e);
|
||||
FixedDecimal(double n, int32_t v, int64_t f);
|
||||
FixedDecimal(double n, int32_t);
|
||||
explicit FixedDecimal(double n);
|
||||
@@ -283,6 +291,8 @@ class U_I18N_API FixedDecimal: public IFixedDecimal, public UObject {
|
||||
FixedDecimal(const UnicodeString &s, UErrorCode &ec);
|
||||
FixedDecimal(const FixedDecimal &other);
|
||||
|
||||
static FixedDecimal createWithExponent(double n, int32_t v, int32_t e);
|
||||
|
||||
double getPluralOperand(PluralOperand operand) const U_OVERRIDE;
|
||||
bool isNaN() const U_OVERRIDE;
|
||||
bool isInfinite() const U_OVERRIDE;
|
||||
@@ -292,6 +302,7 @@ class U_I18N_API FixedDecimal: public IFixedDecimal, public UObject {
|
||||
|
||||
int32_t getVisibleFractionDigitCount() const;
|
||||
|
||||
void init(double n, int32_t v, int64_t f, int32_t e);
|
||||
void init(double n, int32_t v, int64_t f);
|
||||
void init(double n);
|
||||
UBool quickInit(double n); // Try a fast-path only initialization,
|
||||
@@ -300,11 +311,16 @@ class U_I18N_API FixedDecimal: public IFixedDecimal, public UObject {
|
||||
static int64_t getFractionalDigits(double n, int32_t v);
|
||||
static int32_t decimals(double n);
|
||||
|
||||
bool operator==(const FixedDecimal &other) const;
|
||||
|
||||
UnicodeString toString() const;
|
||||
|
||||
double source;
|
||||
int32_t visibleDecimalDigitCount;
|
||||
int64_t decimalDigits;
|
||||
int64_t decimalDigitsWithoutTrailingZeros;
|
||||
int64_t intValue;
|
||||
int32_t exponent;
|
||||
UBool _hasIntegerValue;
|
||||
UBool isNegative;
|
||||
UBool _isNaN;
|
||||
|
||||
@@ -304,7 +304,7 @@ public:
|
||||
* Starting with ICU 54, collation attributes can be specified via locale keywords as well,
|
||||
* in the old locale extension syntax ("el@colCaseFirst=upper")
|
||||
* or in language tag syntax ("el-u-kf-upper").
|
||||
* See <a href="http://userguide.icu-project.org/collation/api">User Guide: Collation API</a>.
|
||||
* See <a href="https://unicode-org.github.io/icu/userguide/collation/api">User Guide: Collation API</a>.
|
||||
*
|
||||
* The UErrorCode& err parameter is used to return status information to the user.
|
||||
* To check whether the construction succeeded or not, you should check
|
||||
@@ -788,7 +788,7 @@ public:
|
||||
* applications who wish to cache collators, or otherwise reuse
|
||||
* collators when possible. The functional equivalent may change
|
||||
* over time. For more information, please see the <a
|
||||
* href="http://userguide.icu-project.org/locale#TOC-Locales-and-Services">
|
||||
* href="https://unicode-org.github.io/icu/userguide/locale#locales-and-services">
|
||||
* Locales and Services</a> section of the ICU User Guide.
|
||||
* @param keyword a particular keyword as enumerated by
|
||||
* ucol_getKeywords.
|
||||
@@ -1139,7 +1139,7 @@ public:
|
||||
* This string will be normalized.
|
||||
* The structure and the syntax of the string is defined in the "Naming collators"
|
||||
* section of the users guide:
|
||||
* http://userguide.icu-project.org/collation/concepts#TOC-Collator-naming-scheme
|
||||
* https://unicode-org.github.io/icu/userguide/collation/concepts#collator-naming-scheme
|
||||
* This function supports preflighting.
|
||||
*
|
||||
* This is internal, and intended to be used with delegate converters.
|
||||
|
||||
@@ -541,13 +541,6 @@ class U_I18N_API MeasureUnit: public UObject {
|
||||
* @internal
|
||||
*/
|
||||
int32_t getOffset() const;
|
||||
|
||||
/**
|
||||
* ICU use only.
|
||||
* @internal
|
||||
*/
|
||||
static MeasureUnit resolveUnitPerUnit(
|
||||
const MeasureUnit &unit, const MeasureUnit &perUnit, bool* isResolved);
|
||||
#endif /* U_HIDE_INTERNAL_API */
|
||||
|
||||
// All code between the "Start generated createXXX methods" comment and
|
||||
|
||||
@@ -255,7 +255,7 @@ class NumberFormat;
|
||||
* or preformatted values, but not pattern strings or custom format objects.</p>
|
||||
*
|
||||
* <p>For more details, see the
|
||||
* <a href="http://userguide.icu-project.org/formatparse/messages">ICU User Guide</a>.</p>
|
||||
* <a href="https://unicode-org.github.io/icu/userguide/format_parse/messages">ICU User Guide</a>.</p>
|
||||
*
|
||||
* <h4>Usage Information</h4>
|
||||
*
|
||||
|
||||
@@ -1771,7 +1771,7 @@ class U_I18N_API NumberFormatterSettings {
|
||||
*
|
||||
* The default is HALF_EVEN. For more information on rounding mode, see the ICU userguide here:
|
||||
*
|
||||
* http://userguide.icu-project.org/formatparse/numbers/rounding-modes
|
||||
* https://unicode-org.github.io/icu/userguide/format_parse/numbers/rounding-modes
|
||||
*
|
||||
* @param roundingMode The rounding mode to use.
|
||||
* @return The fluent chain.
|
||||
|
||||
@@ -179,7 +179,7 @@ public:
|
||||
*
|
||||
* <p>
|
||||
* For more detail on rounding modes, see:
|
||||
* http://userguide.icu-project.org/formatparse/numbers/rounding-modes
|
||||
* https://unicode-org.github.io/icu/userguide/format_parse/numbers/rounding-modes
|
||||
*
|
||||
* @stable ICU 2.4
|
||||
*/
|
||||
|
||||
@@ -46,6 +46,7 @@ U_NAMESPACE_BEGIN
|
||||
|
||||
class Hashtable;
|
||||
class IFixedDecimal;
|
||||
class FixedDecimal;
|
||||
class RuleChain;
|
||||
class PluralRuleParser;
|
||||
class PluralKeywordEnumeration;
|
||||
@@ -475,6 +476,32 @@ public:
|
||||
double *dest, int32_t destCapacity,
|
||||
UErrorCode& status);
|
||||
|
||||
#ifndef U_HIDE_INTERNAL_API
|
||||
/**
|
||||
* Internal-only function that returns FixedDecimals instead of doubles.
|
||||
*
|
||||
* Returns sample values for which select() would return the keyword. If
|
||||
* the keyword is unknown, returns no values, but this is not an error.
|
||||
*
|
||||
* The number of returned values is typically small.
|
||||
*
|
||||
* @param keyword The keyword.
|
||||
* @param dest Array into which to put the returned values. May
|
||||
* be NULL if destCapacity is 0.
|
||||
* @param destCapacity The capacity of the array, must be at least 0.
|
||||
* @param status The error code.
|
||||
* @return The count of values written.
|
||||
* If more than destCapacity samples are available, then
|
||||
* only destCapacity are written, and destCapacity is returned as the count,
|
||||
* rather than setting a U_BUFFER_OVERFLOW_ERROR.
|
||||
* (The actual number of keyword values could be unlimited.)
|
||||
* @internal
|
||||
*/
|
||||
int32_t getSamples(const UnicodeString &keyword,
|
||||
FixedDecimal *dest, int32_t destCapacity,
|
||||
UErrorCode& status);
|
||||
#endif /* U_HIDE_INTERNAL_API */
|
||||
|
||||
/**
|
||||
* Returns true if the given keyword is defined in this
|
||||
* <code>PluralRules</code> object.
|
||||
|
||||
@@ -81,7 +81,7 @@ class LocalizedNumberFormatter;
|
||||
* the date and time formatting algorithm and pattern letters defined by
|
||||
* <a href="http://www.unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table">UTS#35
|
||||
* Unicode Locale Data Markup Language (LDML)</a> and further documented for ICU in the
|
||||
* <a href="https://sites.google.com/site/icuprojectuserguide/formatparse/datetime?pli=1#TOC-Date-Field-Symbol-Table">ICU
|
||||
* <a href="https://unicode-org.github.io/icu/userguide/format_parse/datetime/#date-field-symbol-table">ICU
|
||||
* User Guide</a>. The following pattern letters are currently available (note that the actual
|
||||
* values depend on CLDR and may change from the examples shown here):</p>
|
||||
*
|
||||
|
||||
@@ -99,14 +99,14 @@ class UVector64;
|
||||
* table-based collation.
|
||||
* <p>
|
||||
* For more information about the collation service see
|
||||
* <a href="http://userguide.icu-project.org/collation">the User Guide</a>.
|
||||
* <a href="https://unicode-org.github.io/icu/userguide/collation">the User Guide</a>.
|
||||
* <p>
|
||||
* Collation service provides correct sorting orders for most locales supported in ICU.
|
||||
* If specific data for a locale is not available, the orders eventually falls back
|
||||
* to the <a href="http://www.unicode.org/reports/tr35/tr35-collation.html#Root_Collation">CLDR root sort order</a>.
|
||||
* <p>
|
||||
* Sort ordering may be customized by providing your own set of rules. For more on
|
||||
* this subject see the <a href="http://userguide.icu-project.org/collation/customization">
|
||||
* this subject see the <a href="https://unicode-org.github.io/icu/userguide/collation/customization">
|
||||
* Collation Customization</a> section of the User Guide.
|
||||
* <p>
|
||||
* Note, RuleBasedCollator is not to be subclassed.
|
||||
@@ -495,7 +495,7 @@ public:
|
||||
* just the tailoring.
|
||||
*
|
||||
* getRules(void) should normally be used instead.
|
||||
* See http://userguide.icu-project.org/collation/customization#TOC-Building-on-Existing-Locales
|
||||
* See https://unicode-org.github.io/icu/userguide/collation/customization#building-on-existing-locales
|
||||
* @param delta one of UCOL_TAILORING_ONLY, UCOL_FULL_RULES.
|
||||
* @param buffer UnicodeString to store the result rules
|
||||
* @stable ICU 2.2
|
||||
@@ -702,7 +702,7 @@ public:
|
||||
* This string will be normalized.
|
||||
* The structure and the syntax of the string is defined in the "Naming collators"
|
||||
* section of the users guide:
|
||||
* http://userguide.icu-project.org/collation/concepts#TOC-Collator-naming-scheme
|
||||
* https://unicode-org.github.io/icu/userguide/collation/concepts#collator-naming-scheme
|
||||
* This function supports preflighting.
|
||||
*
|
||||
* This is internal, and intended to be used with delegate converters.
|
||||
|
||||
@@ -403,7 +403,7 @@ public:
|
||||
*
|
||||
* <p>This implementation utilizes <a href="http://unicode.org/cldr/charts/supplemental/zone_tzid.html">
|
||||
* Zone-Tzid mapping data</a>. The mapping data is updated time to time. To get the latest changes,
|
||||
* please read the ICU user guide section <a href="http://userguide.icu-project.org/datetime/timezone#TOC-Updating-the-Time-Zone-Data">
|
||||
* please read the ICU user guide section <a href="https://unicode-org.github.io/icu/userguide/datetime/timezone#updating-the-time-zone-data">
|
||||
* Updating the Time Zone Data</a>.
|
||||
*
|
||||
* @param id A system time zone ID.
|
||||
@@ -431,7 +431,7 @@ public:
|
||||
*
|
||||
* <p>This implementation utilizes <a href="http://unicode.org/cldr/charts/supplemental/zone_tzid.html">
|
||||
* Zone-Tzid mapping data</a>. The mapping data is updated time to time. To get the latest changes,
|
||||
* please read the ICU user guide section <a href="http://userguide.icu-project.org/datetime/timezone#TOC-Updating-the-Time-Zone-Data">
|
||||
* please read the ICU user guide section <a href="https://unicode-org.github.io/icu/userguide/datetime/timezone#updating-the-time-zone-data">
|
||||
* Updating the Time Zone Data</a>.
|
||||
*
|
||||
* @param winid A Windows time zone ID.
|
||||
|
||||
@@ -1568,7 +1568,7 @@ ucal_getTimeZoneTransitionDate(const UCalendar* cal, UTimeZoneTransitionType typ
|
||||
*
|
||||
* <p>This implementation utilizes <a href="http://unicode.org/cldr/charts/supplemental/zone_tzid.html">
|
||||
* Zone-Tzid mapping data</a>. The mapping data is updated time to time. To get the latest changes,
|
||||
* please read the ICU user guide section <a href="http://userguide.icu-project.org/datetime/timezone#TOC-Updating-the-Time-Zone-Data">
|
||||
* please read the ICU user guide section <a href="https://unicode-org.github.io/icu/userguide/datetime/timezone#updating-the-time-zone-data">
|
||||
* Updating the Time Zone Data</a>.
|
||||
*
|
||||
* @param id A system time zone ID.
|
||||
@@ -1599,7 +1599,7 @@ ucal_getWindowsTimeZoneID(const UChar* id, int32_t len,
|
||||
*
|
||||
* <p>This implementation utilizes <a href="http://unicode.org/cldr/charts/supplemental/zone_tzid.html">
|
||||
* Zone-Tzid mapping data</a>. The mapping data is updated time to time. To get the latest changes,
|
||||
* please read the ICU user guide section <a href="http://userguide.icu-project.org/datetime/timezone#TOC-Updating-the-Time-Zone-Data">
|
||||
* please read the ICU user guide section <a href="https://unicode-org.github.io/icu/userguide/datetime/timezone#updating-the-time-zone-data">
|
||||
* Updating the Time Zone Data</a>.
|
||||
*
|
||||
* @param winid A Windows time zone ID.
|
||||
|
||||
@@ -35,14 +35,14 @@
|
||||
* searching and sorting routines for natural language text.
|
||||
* <p>
|
||||
* For more information about the collation service see
|
||||
* <a href="http://userguide.icu-project.org/collation">the User Guide</a>.
|
||||
* <a href="https://unicode-org.github.io/icu/userguide/collation">the User Guide</a>.
|
||||
* <p>
|
||||
* Collation service provides correct sorting orders for most locales supported in ICU.
|
||||
* If specific data for a locale is not available, the orders eventually falls back
|
||||
* to the <a href="http://www.unicode.org/reports/tr35/tr35-collation.html#Root_Collation">CLDR root sort order</a>.
|
||||
* <p>
|
||||
* Sort ordering may be customized by providing your own set of rules. For more on
|
||||
* this subject see the <a href="http://userguide.icu-project.org/collation/customization">
|
||||
* this subject see the <a href="https://unicode-org.github.io/icu/userguide/collation/customization">
|
||||
* Collation Customization</a> section of the User Guide.
|
||||
* <p>
|
||||
* @see UCollationResult
|
||||
@@ -370,7 +370,7 @@ typedef enum {
|
||||
* Retrieves the "UCA rules" concatenated with the tailoring rules.
|
||||
* The "UCA rules" are an <i>approximation</i> of the root collator's sort order.
|
||||
* They are almost never used or useful at runtime and can be removed from the data.
|
||||
* See http://userguide.icu-project.org/collation/customization#TOC-Building-on-Existing-Locales
|
||||
* See https://unicode-org.github.io/icu/userguide/collation/customization#building-on-existing-locales
|
||||
* @stable ICU 2.0
|
||||
*/
|
||||
UCOL_FULL_RULES
|
||||
@@ -384,7 +384,7 @@ typedef enum {
|
||||
* Starting with ICU 54, collation attributes can be specified via locale keywords as well,
|
||||
* in the old locale extension syntax ("el@colCaseFirst=upper")
|
||||
* or in language tag syntax ("el-u-kf-upper").
|
||||
* See <a href="http://userguide.icu-project.org/collation/api">User Guide: Collation API</a>.
|
||||
* See <a href="https://unicode-org.github.io/icu/userguide/collation/api">User Guide: Collation API</a>.
|
||||
*
|
||||
* The UCollator pointer is used in all the calls to the Collation
|
||||
* service. After finished, collator must be disposed of by calling
|
||||
@@ -442,7 +442,7 @@ ucol_openRules( const UChar *rules,
|
||||
* Open a collator defined by a short form string.
|
||||
* The structure and the syntax of the string is defined in the "Naming collators"
|
||||
* section of the users guide:
|
||||
* http://userguide.icu-project.org/collation/concepts#TOC-Collator-naming-scheme
|
||||
* https://unicode-org.github.io/icu/userguide/collation/concepts#collator-naming-scheme
|
||||
* Attributes are overriden by the subsequent attributes. So, for "S2_S3", final
|
||||
* strength will be 3. 3066bis locale overrides individual locale parts.
|
||||
* The call to this function is equivalent to a call to ucol_open, followed by a
|
||||
@@ -904,7 +904,7 @@ ucol_getKeywordValuesForLocale(const char* key,
|
||||
* applications who wish to cache collators, or otherwise reuse
|
||||
* collators when possible. The functional equivalent may change
|
||||
* over time. For more information, please see the <a
|
||||
* href="http://userguide.icu-project.org/locale#TOC-Locales-and-Services">
|
||||
* href="https://unicode-org.github.io/icu/userguide/locale#locales-and-services">
|
||||
* Locales and Services</a> section of the ICU User Guide.
|
||||
* @param result fillin for the functionally equivalent result locale
|
||||
* @param resultCapacity capacity of the fillin buffer
|
||||
@@ -945,7 +945,7 @@ ucol_getRules( const UCollator *coll,
|
||||
* This string will be normalized.
|
||||
* The structure and the syntax of the string is defined in the "Naming collators"
|
||||
* section of the users guide:
|
||||
* http://userguide.icu-project.org/collation/concepts#TOC-Collator-naming-scheme
|
||||
* https://unicode-org.github.io/icu/userguide/collation/concepts#collator-naming-scheme
|
||||
* This API supports preflighting.
|
||||
* @param coll a collator
|
||||
* @param locale a locale that will appear as a collators locale in the resulting
|
||||
@@ -1158,7 +1158,7 @@ ucol_getUCAVersion(const UCollator* coll, UVersionInfo info);
|
||||
* Using strings with U+FFFE may yield shorter sort keys.
|
||||
*
|
||||
* For details about Sort Key Features see
|
||||
* http://userguide.icu-project.org/collation/api#TOC-Sort-Key-Features
|
||||
* https://unicode-org.github.io/icu/userguide/collation/api#sort-key-features
|
||||
*
|
||||
* It is possible to merge multiple sort keys by consecutively merging
|
||||
* another one with the intermediate result.
|
||||
@@ -1354,7 +1354,7 @@ ucol_safeClone(const UCollator *coll,
|
||||
* to store rules, will store up to available space.
|
||||
*
|
||||
* ucol_getRules() should normally be used instead.
|
||||
* See http://userguide.icu-project.org/collation/customization#TOC-Building-on-Existing-Locales
|
||||
* See https://unicode-org.github.io/icu/userguide/collation/customization#building-on-existing-locales
|
||||
* @param coll collator to get the rules from
|
||||
* @param delta one of UCOL_TAILORING_ONLY, UCOL_FULL_RULES.
|
||||
* @param buffer buffer to store the result in. If NULL, you'll get no rules.
|
||||
|
||||
@@ -146,7 +146,7 @@
|
||||
* the date and time formatting algorithm and pattern letters defined by
|
||||
* <a href="http://www.unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table">UTS#35
|
||||
* Unicode Locale Data Markup Language (LDML)</a> and further documented for ICU in the
|
||||
* <a href="https://sites.google.com/site/icuprojectuserguide/formatparse/datetime?pli=1#TOC-Date-Field-Symbol-Table">ICU
|
||||
* <a href="https://unicode-org.github.io/icu/userguide/format_parse/datetime#date-field-symbol-table">ICU
|
||||
* User Guide</a>.</p>
|
||||
*/
|
||||
|
||||
|
||||
@@ -275,7 +275,7 @@ typedef enum UNumberFormatStyle {
|
||||
*
|
||||
* <p>
|
||||
* For more detail on rounding modes, see:
|
||||
* http://userguide.icu-project.org/formatparse/numbers/rounding-modes
|
||||
* https://unicode-org.github.io/icu/userguide/format_parse/numbers/rounding-modes
|
||||
*
|
||||
* @stable ICU 2.0
|
||||
*/
|
||||
|
||||
@@ -110,9 +110,13 @@ UBool ComplexUnitsConverter::greaterThanOrEqual(double quantity, double limit) c
|
||||
MaybeStackVector<Measure> ComplexUnitsConverter::convert(double quantity,
|
||||
icu::number::impl::RoundingImpl *rounder,
|
||||
UErrorCode &status) const {
|
||||
// TODO(icu-units#63): test negative numbers!
|
||||
// TODO(hugovdm): return an error for "foot-and-foot"?
|
||||
MaybeStackVector<Measure> result;
|
||||
int sign = 1;
|
||||
if (quantity < 0) {
|
||||
quantity *= -1;
|
||||
sign = -1;
|
||||
}
|
||||
|
||||
// For N converters:
|
||||
// - the first converter converts from the input unit to the largest unit,
|
||||
@@ -190,7 +194,7 @@ MaybeStackVector<Measure> ComplexUnitsConverter::convert(double quantity,
|
||||
// Package values into Measure instances in result:
|
||||
for (int i = 0, n = unitConverters_.length(); i < n; ++i) {
|
||||
if (i < n - 1) {
|
||||
Formattable formattableQuantity(intValues[i]);
|
||||
Formattable formattableQuantity(intValues[i] * sign);
|
||||
// Measure takes ownership of the MeasureUnit*
|
||||
MeasureUnit *type = new MeasureUnit(units_[i]->copy(status).build(status));
|
||||
if (result.emplaceBackAndCheckErrorCode(status, formattableQuantity, type, status) ==
|
||||
@@ -204,7 +208,7 @@ MaybeStackVector<Measure> ComplexUnitsConverter::convert(double quantity,
|
||||
}
|
||||
} else { // LAST ELEMENT
|
||||
// Add the last element, not an integer:
|
||||
Formattable formattableQuantity(quantity);
|
||||
Formattable formattableQuantity(quantity * sign);
|
||||
// Measure takes ownership of the MeasureUnit*
|
||||
MeasureUnit *type = new MeasureUnit(units_[i]->copy(status).build(status));
|
||||
if (result.emplaceBackAndCheckErrorCode(status, formattableQuantity, type, status) ==
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "unicode/measure.h"
|
||||
#include "units_data.h"
|
||||
#include "units_router.h"
|
||||
#include <cmath>
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
namespace units {
|
||||
@@ -96,7 +97,7 @@ RouteResult UnitsRouter::route(double quantity, icu::number::impl::RoundingImpl
|
||||
const ConverterPreference *converterPreference = nullptr;
|
||||
for (int32_t i = 0, n = converterPreferences_.length(); i < n; i++) {
|
||||
converterPreference = converterPreferences_[i];
|
||||
if (converterPreference->converter.greaterThanOrEqual(quantity * (1 + DBL_EPSILON),
|
||||
if (converterPreference->converter.greaterThanOrEqual(std::abs(quantity) * (1 + DBL_EPSILON),
|
||||
converterPreference->limit)) {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#include "uassert.h"
|
||||
|
||||
#ifndef U_IO_IMPLEMENTATION
|
||||
#error U_IO_IMPLEMENTATION not set - must be set for all ICU source files in io/ - see http://userguide.icu-project.org/howtouseicu
|
||||
#error U_IO_IMPLEMENTATION not set - must be set for all ICU source files in io/ - see https://unicode-org.github.io/icu/userguide/howtouseicu
|
||||
#endif
|
||||
|
||||
|
||||
@@ -69,4 +69,3 @@ void ucln_io_registerCleanup(ECleanupIOType type,
|
||||
ucln_registerAutomaticCleanup();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ U_NAMESPACE_BEGIN
|
||||
* You may use this class with the HarfBuzz icu-le-hb wrapper,
|
||||
* see http://www.freedesktop.org/wiki/Software/HarfBuzz/
|
||||
*
|
||||
* See http://userguide.icu-project.org/layoutengine for special build instructions.
|
||||
* See https://unicode-org.github.io/icu/userguide/layoutengine for special build instructions.
|
||||
*/
|
||||
class U_LAYOUTEX_API ParagraphLayout : public UObject
|
||||
{
|
||||
|
||||
@@ -65,10 +65,10 @@ static void TestExampleCode() {
|
||||
// Get the result string:
|
||||
int32_t len;
|
||||
const UChar* str = ufmtval_getString(unumrf_resultAsValue(uresult, &ec), &len, &ec);
|
||||
if (assertSuccessCheck("There should not be a failure in the example code", &ec, TRUE)) {
|
||||
assertUEquals("Should produce expected string result", u"$3 – $5", str);
|
||||
assertIntEquals("Length should be as expected", u_strlen(str), len);
|
||||
}
|
||||
assertSuccessCheck("There should not be a failure in the example code", &ec, TRUE);
|
||||
assertUEquals("Should produce expected string result", u"$3 – $5", str);
|
||||
int32_t resultLength = str != NULL ? u_strlen(str) : 0;
|
||||
assertIntEquals("Length should be as expected", resultLength, len);
|
||||
|
||||
// Cleanup:
|
||||
unumrf_close(uformatter);
|
||||
|
||||
@@ -3494,7 +3494,7 @@ void MeasureFormatTest::TestUnitPerUnitResolution() {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
Locale en("en");
|
||||
MeasureFormat fmt("en", UMEASFMT_WIDTH_SHORT, status);
|
||||
Measure measure(50.0, MeasureUnit::createPound(status), status);
|
||||
Measure measure(50.0, MeasureUnit::createPoundForce(status), status);
|
||||
LocalPointer<MeasureUnit> sqInch(MeasureUnit::createSquareInch(status));
|
||||
if (!assertSuccess("Create of format unit and per unit", status)) {
|
||||
return;
|
||||
|
||||
@@ -54,6 +54,7 @@ class NumberFormatterApiTest : public IntlTestWithFieldPosition {
|
||||
void notationCompact();
|
||||
void unitMeasure();
|
||||
void unitCompoundMeasure();
|
||||
void unitSkeletons();
|
||||
void unitUsage();
|
||||
void unitUsageErrorCodes();
|
||||
void unitUsageSkeletons();
|
||||
@@ -104,12 +105,15 @@ class NumberFormatterApiTest : public IntlTestWithFieldPosition {
|
||||
CurrencyUnit CNY;
|
||||
|
||||
MeasureUnit METER;
|
||||
MeasureUnit METER_PER_SECOND;
|
||||
MeasureUnit DAY;
|
||||
MeasureUnit SQUARE_METER;
|
||||
MeasureUnit FAHRENHEIT;
|
||||
MeasureUnit SECOND;
|
||||
MeasureUnit POUND;
|
||||
MeasureUnit POUND_FORCE;
|
||||
MeasureUnit SQUARE_MILE;
|
||||
MeasureUnit SQUARE_INCH;
|
||||
MeasureUnit JOULE;
|
||||
MeasureUnit FURLONG;
|
||||
MeasureUnit KELVIN;
|
||||
|
||||
@@ -53,12 +53,15 @@ NumberFormatterApiTest::NumberFormatterApiTest(UErrorCode& status)
|
||||
}
|
||||
METER = *unit;
|
||||
|
||||
METER_PER_SECOND = *LocalPointer<MeasureUnit>(MeasureUnit::createMeterPerSecond(status));
|
||||
DAY = *LocalPointer<MeasureUnit>(MeasureUnit::createDay(status));
|
||||
SQUARE_METER = *LocalPointer<MeasureUnit>(MeasureUnit::createSquareMeter(status));
|
||||
FAHRENHEIT = *LocalPointer<MeasureUnit>(MeasureUnit::createFahrenheit(status));
|
||||
SECOND = *LocalPointer<MeasureUnit>(MeasureUnit::createSecond(status));
|
||||
POUND = *LocalPointer<MeasureUnit>(MeasureUnit::createPound(status));
|
||||
POUND_FORCE = *LocalPointer<MeasureUnit>(MeasureUnit::createPoundForce(status));
|
||||
SQUARE_MILE = *LocalPointer<MeasureUnit>(MeasureUnit::createSquareMile(status));
|
||||
SQUARE_INCH = *LocalPointer<MeasureUnit>(MeasureUnit::createSquareInch(status));
|
||||
JOULE = *LocalPointer<MeasureUnit>(MeasureUnit::createJoule(status));
|
||||
FURLONG = *LocalPointer<MeasureUnit>(MeasureUnit::createFurlong(status));
|
||||
KELVIN = *LocalPointer<MeasureUnit>(MeasureUnit::createKelvin(status));
|
||||
@@ -77,6 +80,7 @@ void NumberFormatterApiTest::runIndexedTest(int32_t index, UBool exec, const cha
|
||||
TESTCASE_AUTO(notationCompact);
|
||||
TESTCASE_AUTO(unitMeasure);
|
||||
TESTCASE_AUTO(unitCompoundMeasure);
|
||||
TESTCASE_AUTO(unitSkeletons);
|
||||
TESTCASE_AUTO(unitUsage);
|
||||
TESTCASE_AUTO(unitUsageErrorCodes);
|
||||
TESTCASE_AUTO(unitUsageSkeletons);
|
||||
@@ -578,6 +582,23 @@ void NumberFormatterApiTest::unitMeasure() {
|
||||
u"0.0088 meters",
|
||||
u"0 meters");
|
||||
|
||||
// // TODO(ICU-20941): Support formatting for not-built-in units
|
||||
// assertFormatDescending(
|
||||
// u"Hectometers",
|
||||
// u"measure-unit/length-hectometer",
|
||||
// u"unit/hectometer",
|
||||
// NumberFormatter::with().unit(MeasureUnit::forIdentifier("hectometer", status)),
|
||||
// Locale::getEnglish(),
|
||||
// u"87,650 hm",
|
||||
// u"8,765 hm",
|
||||
// u"876.5 hm",
|
||||
// u"87.65 hm",
|
||||
// u"8.765 hm",
|
||||
// u"0.8765 hm",
|
||||
// u"0.08765 hm",
|
||||
// u"0.008765 hm",
|
||||
// u"0 hm");
|
||||
|
||||
// TODO: Implement Measure in C++
|
||||
// assertFormatSingleMeasure(
|
||||
// u"Meters with Measure Input",
|
||||
@@ -694,10 +715,9 @@ void NumberFormatterApiTest::unitMeasure() {
|
||||
5,
|
||||
u"5 a\u00F1os");
|
||||
|
||||
// TODO(icu-units#35): skeleton generation.
|
||||
assertFormatSingle(
|
||||
u"Mixed unit",
|
||||
nullptr,
|
||||
u"unit/yard-and-foot-and-inch",
|
||||
u"unit/yard-and-foot-and-inch",
|
||||
NumberFormatter::with()
|
||||
.unit(MeasureUnit::forIdentifier("yard-and-foot-and-inch", status)),
|
||||
@@ -705,10 +725,9 @@ void NumberFormatterApiTest::unitMeasure() {
|
||||
3.65,
|
||||
"3 yd, 1 ft, 11.4 in");
|
||||
|
||||
// TODO(icu-units#35): skeleton generation.
|
||||
assertFormatSingle(
|
||||
u"Mixed unit, Scientific",
|
||||
nullptr,
|
||||
u"unit/yard-and-foot-and-inch E0",
|
||||
u"unit/yard-and-foot-and-inch E0",
|
||||
NumberFormatter::with()
|
||||
.unit(MeasureUnit::forIdentifier("yard-and-foot-and-inch", status))
|
||||
@@ -717,10 +736,9 @@ void NumberFormatterApiTest::unitMeasure() {
|
||||
3.65,
|
||||
"3 yd, 1 ft, 1.14E1 in");
|
||||
|
||||
// TODO(icu-units#35): skeleton generation.
|
||||
assertFormatSingle(
|
||||
u"Mixed Unit (Narrow Version)",
|
||||
nullptr,
|
||||
u"unit/metric-ton-and-kilogram-and-gram unit-width-narrow",
|
||||
u"unit/metric-ton-and-kilogram-and-gram unit-width-narrow",
|
||||
NumberFormatter::with()
|
||||
.unit(MeasureUnit::forIdentifier("metric-ton-and-kilogram-and-gram", status))
|
||||
@@ -729,10 +747,9 @@ void NumberFormatterApiTest::unitMeasure() {
|
||||
4.28571,
|
||||
u"4t 285kg 710g");
|
||||
|
||||
// TODO(icu-units#35): skeleton generation.
|
||||
assertFormatSingle(
|
||||
u"Mixed Unit (Short Version)",
|
||||
nullptr,
|
||||
u"unit/metric-ton-and-kilogram-and-gram unit-width-short",
|
||||
u"unit/metric-ton-and-kilogram-and-gram unit-width-short",
|
||||
NumberFormatter::with()
|
||||
.unit(MeasureUnit::forIdentifier("metric-ton-and-kilogram-and-gram", status))
|
||||
@@ -741,10 +758,9 @@ void NumberFormatterApiTest::unitMeasure() {
|
||||
4.28571,
|
||||
u"4 t, 285 kg, 710 g");
|
||||
|
||||
// TODO(icu-units#35): skeleton generation.
|
||||
assertFormatSingle(
|
||||
u"Mixed Unit (Full Name Version)",
|
||||
nullptr,
|
||||
u"unit/metric-ton-and-kilogram-and-gram unit-width-full-name",
|
||||
u"unit/metric-ton-and-kilogram-and-gram unit-width-full-name",
|
||||
NumberFormatter::with()
|
||||
.unit(MeasureUnit::forIdentifier("metric-ton-and-kilogram-and-gram", status))
|
||||
@@ -755,8 +771,8 @@ void NumberFormatterApiTest::unitMeasure() {
|
||||
|
||||
assertFormatSingle(
|
||||
u"Testing \"1 foot 12 inches\"",
|
||||
nullptr,
|
||||
u"unit/foot-and-inch",
|
||||
u"unit/foot-and-inch @### unit-width-full-name",
|
||||
u"unit/foot-and-inch @### unit-width-full-name",
|
||||
NumberFormatter::with()
|
||||
.unit(MeasureUnit::forIdentifier("foot-and-inch", status))
|
||||
.precision(Precision::maxSignificantDigits(4))
|
||||
@@ -764,6 +780,24 @@ void NumberFormatterApiTest::unitMeasure() {
|
||||
Locale("en-US"),
|
||||
1.9999,
|
||||
u"2 feet, 0 inches");
|
||||
|
||||
assertFormatSingle(
|
||||
u"Negative numbers: temperature",
|
||||
u"measure-unit/temperature-celsius",
|
||||
u"unit/celsius",
|
||||
NumberFormatter::with().unit(MeasureUnit::forIdentifier("celsius", status)),
|
||||
Locale("nl-NL"),
|
||||
-6.5,
|
||||
u"-6,5\u00B0C");
|
||||
|
||||
assertFormatSingle(
|
||||
u"Negative numbers: time",
|
||||
u"unit/hour-and-minute-and-second",
|
||||
u"unit/hour-and-minute-and-second",
|
||||
NumberFormatter::with().unit(MeasureUnit::forIdentifier("hour-and-minute-and-second", status)),
|
||||
Locale("de-DE"),
|
||||
-1.24,
|
||||
u"-1 Std., 14 Min. und 24 Sek.");
|
||||
}
|
||||
|
||||
void NumberFormatterApiTest::unitCompoundMeasure() {
|
||||
@@ -785,16 +819,21 @@ void NumberFormatterApiTest::unitCompoundMeasure() {
|
||||
u"0.008765 m/s",
|
||||
u"0 m/s");
|
||||
|
||||
// TODO(icu-units#35): does not normalize as desired: while "unit/*" does
|
||||
// get split into unit/perUnit, ".unit(*)" and "measure-unit/*" don't:
|
||||
assertFormatSingle(
|
||||
u"Built-in unit, meter-per-second",
|
||||
u"measure-unit/speed-meter-per-second",
|
||||
u"~unit/meter-per-second",
|
||||
NumberFormatter::with().unit(MeasureUnit::getMeterPerSecond()),
|
||||
Locale("en-GB"),
|
||||
2.4,
|
||||
u"2.4 m/s");
|
||||
assertFormatDescending(
|
||||
u"Meters Per Second Short, built-in m/s",
|
||||
u"measure-unit/speed-meter-per-second",
|
||||
u"unit/meter-per-second",
|
||||
NumberFormatter::with().unit(METER_PER_SECOND),
|
||||
Locale::getEnglish(),
|
||||
u"87,650 m/s",
|
||||
u"8,765 m/s",
|
||||
u"876.5 m/s",
|
||||
u"87.65 m/s",
|
||||
u"8.765 m/s",
|
||||
u"0.8765 m/s",
|
||||
u"0.08765 m/s",
|
||||
u"0.008765 m/s",
|
||||
u"0 m/s");
|
||||
|
||||
assertFormatDescending(
|
||||
u"Pounds Per Square Mile Short (secondary unit has per-format) and adoptPerUnit method",
|
||||
@@ -845,23 +884,55 @@ void NumberFormatterApiTest::unitCompoundMeasure() {
|
||||
// u"0.008765 J/fur",
|
||||
// u"0 J/fur");
|
||||
|
||||
// TODO(icu-units#59): THIS UNIT TEST DEMONSTRATES UNDESIREABLE BEHAVIOUR!
|
||||
// When specifying built-in types, one can give both a unit and a perUnit.
|
||||
// Resolving to a built-in unit does not always work.
|
||||
//
|
||||
// (Unit-testing philosophy: do we leave this enabled to demonstrate current
|
||||
// behaviour, and changing behaviour in the future? Or comment it out to
|
||||
// avoid asserting this is "correct"?)
|
||||
assertFormatDescending(
|
||||
u"Pounds per Square Inch: composed",
|
||||
u"measure-unit/force-pound-force per-measure-unit/area-square-inch",
|
||||
u"unit/pound-force-per-square-inch",
|
||||
NumberFormatter::with().unit(POUND_FORCE).perUnit(SQUARE_INCH),
|
||||
Locale::getEnglish(),
|
||||
u"87,650 psi",
|
||||
u"8,765 psi",
|
||||
u"876.5 psi",
|
||||
u"87.65 psi",
|
||||
u"8.765 psi",
|
||||
u"0.8765 psi",
|
||||
u"0.08765 psi",
|
||||
u"0.008765 psi",
|
||||
u"0 psi");
|
||||
|
||||
assertFormatDescending(
|
||||
u"Pounds per Square Inch: built-in",
|
||||
u"measure-unit/force-pound-force per-measure-unit/area-square-inch",
|
||||
u"unit/pound-force-per-square-inch",
|
||||
NumberFormatter::with().unit(MeasureUnit::getPoundPerSquareInch()),
|
||||
Locale::getEnglish(),
|
||||
u"87,650 psi",
|
||||
u"8,765 psi",
|
||||
u"876.5 psi",
|
||||
u"87.65 psi",
|
||||
u"8.765 psi",
|
||||
u"0.8765 psi",
|
||||
u"0.08765 psi",
|
||||
u"0.008765 psi",
|
||||
u"0 psi");
|
||||
|
||||
assertFormatSingle(
|
||||
u"DEMONSTRATING BAD BEHAVIOUR, TODO(icu-units#59)",
|
||||
u"m/s/s simplifies to m/s^2",
|
||||
u"measure-unit/speed-meter-per-second per-measure-unit/duration-second",
|
||||
u"measure-unit/speed-meter-per-second per-measure-unit/duration-second",
|
||||
NumberFormatter::with()
|
||||
.unit(MeasureUnit::getMeterPerSecond())
|
||||
.perUnit(MeasureUnit::getSecond()),
|
||||
u"unit/meter-per-square-second",
|
||||
NumberFormatter::with().unit(METER_PER_SECOND).perUnit(SECOND),
|
||||
Locale("en-GB"),
|
||||
2.4,
|
||||
"2.4 m/s/s");
|
||||
u"2.4 m/s\u00B2");
|
||||
|
||||
assertFormatSingle(
|
||||
u"Negative numbers: acceleration",
|
||||
u"measure-unit/acceleration-meter-per-square-second",
|
||||
u"unit/meter-per-second-second",
|
||||
NumberFormatter::with().unit(MeasureUnit::forIdentifier("meter-per-pow2-second", status)),
|
||||
Locale("af-ZA"),
|
||||
-9.81,
|
||||
u"-9,81 m/s\u00B2");
|
||||
|
||||
// Testing the rejection of invalid specifications
|
||||
|
||||
@@ -880,12 +951,10 @@ void NumberFormatterApiTest::unitCompoundMeasure() {
|
||||
status.assertSuccess();
|
||||
}
|
||||
|
||||
// .perUnit() may only be passed a built-in type, "square-second" is not a
|
||||
// built-in type.
|
||||
nf = NumberFormatter::with()
|
||||
.unit(MeasureUnit::getMeter())
|
||||
.perUnit(MeasureUnit::forIdentifier("square-second", status))
|
||||
.locale("en-GB");
|
||||
// .perUnit() may only be passed a built-in type, or something that combines
|
||||
// to a built-in type together with .unit().
|
||||
MeasureUnit SQUARE_SECOND = MeasureUnit::forIdentifier("square-second", status);
|
||||
nf = NumberFormatter::with().unit(FURLONG).perUnit(SQUARE_SECOND).locale("en-GB");
|
||||
status.assertSuccess(); // Error is only returned once we try to format.
|
||||
num = nf.formatDouble(2.4, status);
|
||||
if (!status.expectErrorAndReset(U_UNSUPPORTED_ERROR)) {
|
||||
@@ -893,6 +962,128 @@ void NumberFormatterApiTest::unitCompoundMeasure() {
|
||||
nf.formatDouble(2.4, status).toString(status) + "\".");
|
||||
status.assertSuccess();
|
||||
}
|
||||
// As above, "square-second" is not a built-in type, however this time,
|
||||
// meter-per-square-second is a built-in type.
|
||||
assertFormatSingle(
|
||||
u"meter per square-second works as a composed unit",
|
||||
u"measure-unit/speed-meter-per-second per-measure-unit/duration-second",
|
||||
u"unit/meter-per-square-second",
|
||||
NumberFormatter::with().unit(METER).perUnit(SQUARE_SECOND),
|
||||
Locale("en-GB"),
|
||||
2.4,
|
||||
u"2.4 m/s\u00B2");
|
||||
}
|
||||
|
||||
void NumberFormatterApiTest::unitSkeletons() {
|
||||
const struct TestCase {
|
||||
const char *msg;
|
||||
const char16_t *inputSkeleton;
|
||||
const char16_t *normalizedSkeleton;
|
||||
} cases[] = {
|
||||
{"old-form built-in compound unit", //
|
||||
u"measure-unit/speed-meter-per-second", //
|
||||
u"unit/meter-per-second"},
|
||||
|
||||
{"old-form compound construction, converts to built-in", //
|
||||
u"measure-unit/length-meter per-measure-unit/duration-second", //
|
||||
u"unit/meter-per-second"},
|
||||
|
||||
{"old-form compound construction which does not simplify to a built-in", //
|
||||
u"measure-unit/energy-joule per-measure-unit/length-meter", //
|
||||
u"unit/joule-per-meter"},
|
||||
|
||||
{"old-form compound-compound ugliness resolves neatly", //
|
||||
u"measure-unit/speed-meter-per-second per-measure-unit/duration-second", //
|
||||
u"unit/meter-per-square-second"},
|
||||
|
||||
{"short-form built-in units stick with the built-in", //
|
||||
u"unit/meter-per-second", //
|
||||
u"unit/meter-per-second"},
|
||||
|
||||
{"short-form compound units stay as is", //
|
||||
u"unit/square-meter-per-square-meter", //
|
||||
u"unit/square-meter-per-square-meter"},
|
||||
|
||||
{"short-form compound units stay as is", //
|
||||
u"unit/joule-per-furlong", //
|
||||
u"unit/joule-per-furlong"},
|
||||
|
||||
{"short-form that doesn't consist of built-in units", //
|
||||
u"unit/hectometer-per-second", //
|
||||
u"unit/hectometer-per-second"},
|
||||
|
||||
{"short-form that doesn't consist of built-in units", //
|
||||
u"unit/meter-per-hectosecond", //
|
||||
u"unit/meter-per-hectosecond"},
|
||||
|
||||
// // TODO: binary prefixes not supported yet!
|
||||
// {"Round-trip example from icu-units#35", //
|
||||
// u"unit/kibijoule-per-furlong", //
|
||||
// u"unit/kibijoule-per-furlong"},
|
||||
};
|
||||
for (auto &cas : cases) {
|
||||
IcuTestErrorCode status(*this, cas.msg);
|
||||
auto nf = NumberFormatter::forSkeleton(cas.inputSkeleton, status);
|
||||
if (status.errIfFailureAndReset("NumberFormatter::forSkeleton failed")) {
|
||||
continue;
|
||||
}
|
||||
assertEquals( //
|
||||
UnicodeString(TRUE, cas.inputSkeleton, -1) + u" normalization", //
|
||||
cas.normalizedSkeleton, //
|
||||
nf.toSkeleton(status));
|
||||
status.errIfFailureAndReset("NumberFormatter::toSkeleton failed");
|
||||
}
|
||||
|
||||
const struct FailCase {
|
||||
const char *msg;
|
||||
const char16_t *inputSkeleton;
|
||||
UErrorCode expectedForSkelStatus;
|
||||
UErrorCode expectedToSkelStatus;
|
||||
} failCases[] = {
|
||||
{"Parsing measure-unit/* results in failure if not built-in unit",
|
||||
u"measure-unit/hectometer", //
|
||||
U_NUMBER_SKELETON_SYNTAX_ERROR, //
|
||||
U_ZERO_ERROR},
|
||||
|
||||
{"Parsing per-measure-unit/* results in failure if not built-in unit",
|
||||
u"measure-unit/meter per-measure-unit/hectosecond", //
|
||||
U_NUMBER_SKELETON_SYNTAX_ERROR, //
|
||||
U_ZERO_ERROR},
|
||||
};
|
||||
for (auto &cas : failCases) {
|
||||
IcuTestErrorCode status(*this, cas.msg);
|
||||
auto nf = NumberFormatter::forSkeleton(cas.inputSkeleton, status);
|
||||
if (status.expectErrorAndReset(cas.expectedForSkelStatus, cas.msg)) {
|
||||
continue;
|
||||
}
|
||||
nf.toSkeleton(status);
|
||||
status.expectErrorAndReset(cas.expectedToSkelStatus, cas.msg);
|
||||
}
|
||||
|
||||
IcuTestErrorCode status(*this, "unitSkeletons");
|
||||
MeasureUnit METER_PER_SECOND = MeasureUnit::forIdentifier("meter-per-second", status);
|
||||
|
||||
assertEquals( //
|
||||
".unit(METER_PER_SECOND) normalization", //
|
||||
u"unit/meter-per-second", //
|
||||
NumberFormatter::with().unit(METER_PER_SECOND).toSkeleton(status));
|
||||
assertEquals( //
|
||||
".unit(METER).perUnit(SECOND) normalization", //
|
||||
u"unit/meter-per-second",
|
||||
NumberFormatter::with().unit(METER).perUnit(SECOND).toSkeleton(status));
|
||||
assertEquals( //
|
||||
".unit(MeasureUnit::forIdentifier(\"hectometer\", status)) normalization", //
|
||||
u"unit/hectometer",
|
||||
NumberFormatter::with()
|
||||
.unit(MeasureUnit::forIdentifier("hectometer", status))
|
||||
.toSkeleton(status));
|
||||
assertEquals( //
|
||||
".unit(MeasureUnit::forIdentifier(\"hectometer\", status)) normalization", //
|
||||
u"unit/meter-per-hectosecond",
|
||||
NumberFormatter::with()
|
||||
.unit(METER)
|
||||
.perUnit(MeasureUnit::forIdentifier("hectosecond", status))
|
||||
.toSkeleton(status));
|
||||
}
|
||||
|
||||
void NumberFormatterApiTest::unitUsage() {
|
||||
@@ -1134,6 +1325,15 @@ void NumberFormatterApiTest::unitUsage() {
|
||||
u"8,765E0 square metres",
|
||||
u"0E0 square centimetres");
|
||||
|
||||
assertFormatSingle(
|
||||
u"Negative numbers: minute-and-second",
|
||||
u"measure-unit/duration-second usage/media",
|
||||
u"unit/second usage/media",
|
||||
NumberFormatter::with().unit(SECOND).usage("media"),
|
||||
Locale("nl-NL"),
|
||||
-77.7,
|
||||
u"-1 min, 18 sec");
|
||||
|
||||
assertFormatSingle(
|
||||
u"Rounding Mode propagates: rounding down",
|
||||
u"usage/road measure-unit/length-centimeter rounding-mode-floor",
|
||||
@@ -3495,11 +3695,11 @@ void NumberFormatterApiTest::fieldPositionCoverage() {
|
||||
}
|
||||
|
||||
{
|
||||
const char16_t* message = u"Measure unit field position with prefix and suffix";
|
||||
const char16_t* message = u"Measure unit field position with prefix and suffix, composed m/s";
|
||||
FormattedNumber result = assertFormatSingle(
|
||||
message,
|
||||
u"measure-unit/length-meter per-measure-unit/duration-second unit-width-full-name",
|
||||
u"unit/meter-per-second unit-width-full-name",
|
||||
u"measure-unit/length-meter per-measure-unit/duration-second unit-width-full-name",
|
||||
NumberFormatter::with().unit(METER).perUnit(SECOND).unitWidth(UNUM_UNIT_WIDTH_FULL_NAME),
|
||||
"ky", // locale with the interesting data
|
||||
68,
|
||||
@@ -3516,6 +3716,28 @@ void NumberFormatterApiTest::fieldPositionCoverage() {
|
||||
UPRV_LENGTHOF(expectedFieldPositions));
|
||||
}
|
||||
|
||||
{
|
||||
const char16_t* message = u"Measure unit field position with prefix and suffix, built-in m/s";
|
||||
FormattedNumber result = assertFormatSingle(
|
||||
message,
|
||||
u"measure-unit/speed-meter-per-second unit-width-full-name",
|
||||
u"unit/meter-per-second unit-width-full-name",
|
||||
NumberFormatter::with().unit(METER_PER_SECOND).unitWidth(UNUM_UNIT_WIDTH_FULL_NAME),
|
||||
"ky", // locale with the interesting data
|
||||
68,
|
||||
u"секундасына 68 метр");
|
||||
static const UFieldPosition expectedFieldPositions[] = {
|
||||
// field, begin index, end index
|
||||
{UNUM_MEASURE_UNIT_FIELD, 0, 11},
|
||||
{UNUM_INTEGER_FIELD, 12, 14},
|
||||
{UNUM_MEASURE_UNIT_FIELD, 15, 19}};
|
||||
assertNumberFieldPositions(
|
||||
message,
|
||||
result,
|
||||
expectedFieldPositions,
|
||||
UPRV_LENGTHOF(expectedFieldPositions));
|
||||
}
|
||||
|
||||
{
|
||||
const char16_t* message = u"Measure unit field position with inner spaces";
|
||||
FormattedNumber result = assertFormatSingle(
|
||||
@@ -4104,6 +4326,15 @@ void NumberFormatterApiTest::microPropsInternals() {
|
||||
assertEquals("Copy Assigned capacity", 4, copyAssigned.mixedMeasures.getCapacity());
|
||||
}
|
||||
|
||||
/* For skeleton comparisons: this checks the toSkeleton output for `f` and for
|
||||
* `conciseSkeleton` against the normalized version of `uskeleton` - this does
|
||||
* not round-trip uskeleton itself.
|
||||
*
|
||||
* If `conciseSkeleton` starts with a "~", its round-trip check is skipped.
|
||||
*
|
||||
* If `uskeleton` is nullptr, toSkeleton is expected to return an
|
||||
* U_UNSUPPORTED_ERROR.
|
||||
*/
|
||||
void NumberFormatterApiTest::assertFormatDescending(
|
||||
const char16_t* umessage,
|
||||
const char16_t* uskeleton,
|
||||
@@ -4165,6 +4396,15 @@ void NumberFormatterApiTest::assertFormatDescending(
|
||||
}
|
||||
}
|
||||
|
||||
/* For skeleton comparisons: this checks the toSkeleton output for `f` and for
|
||||
* `conciseSkeleton` against the normalized version of `uskeleton` - this does
|
||||
* not round-trip uskeleton itself.
|
||||
*
|
||||
* If `conciseSkeleton` starts with a "~", its round-trip check is skipped.
|
||||
*
|
||||
* If `uskeleton` is nullptr, toSkeleton is expected to return an
|
||||
* U_UNSUPPORTED_ERROR.
|
||||
*/
|
||||
void NumberFormatterApiTest::assertFormatDescendingBig(
|
||||
const char16_t* umessage,
|
||||
const char16_t* uskeleton,
|
||||
@@ -4226,6 +4466,15 @@ void NumberFormatterApiTest::assertFormatDescendingBig(
|
||||
}
|
||||
}
|
||||
|
||||
/* For skeleton comparisons: this checks the toSkeleton output for `f` and for
|
||||
* `conciseSkeleton` against the normalized version of `uskeleton` - this does
|
||||
* not round-trip uskeleton itself.
|
||||
*
|
||||
* If `conciseSkeleton` starts with a "~", its round-trip check is skipped.
|
||||
*
|
||||
* If `uskeleton` is nullptr, toSkeleton is expected to return an
|
||||
* U_UNSUPPORTED_ERROR.
|
||||
*/
|
||||
FormattedNumber
|
||||
NumberFormatterApiTest::assertFormatSingle(
|
||||
const char16_t* umessage,
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "unicode/numberrangeformatter.h"
|
||||
|
||||
#include "cmemory.h"
|
||||
#include "cstr.h"
|
||||
#include "plurrule_impl.h"
|
||||
#include "plurults.h"
|
||||
#include "uhash.h"
|
||||
@@ -49,6 +50,8 @@ void PluralRulesTest::runIndexedTest( int32_t index, UBool exec, const char* &na
|
||||
TESTCASE_AUTO(testAPI);
|
||||
// TESTCASE_AUTO(testGetUniqueKeywordValue);
|
||||
TESTCASE_AUTO(testGetSamples);
|
||||
TESTCASE_AUTO(testGetFixedDecimalSamples);
|
||||
TESTCASE_AUTO(testSamplesWithExponent);
|
||||
TESTCASE_AUTO(testWithin);
|
||||
TESTCASE_AUTO(testGetAllKeywordValues);
|
||||
TESTCASE_AUTO(testCompactDecimalPluralKeyword);
|
||||
@@ -356,124 +359,245 @@ UBool testEquality(const PluralRules &test) {
|
||||
|
||||
void
|
||||
PluralRulesTest::assertRuleValue(const UnicodeString& rule, double expected) {
|
||||
assertRuleKeyValue("a:" + rule, "a", expected);
|
||||
assertRuleKeyValue("a:" + rule, "a", expected);
|
||||
}
|
||||
|
||||
void
|
||||
PluralRulesTest::assertRuleKeyValue(const UnicodeString& rule,
|
||||
const UnicodeString& key, double expected) {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
PluralRules *pr = PluralRules::createRules(rule, status);
|
||||
double result = pr->getUniqueKeywordValue(key);
|
||||
delete pr;
|
||||
if (expected != result) {
|
||||
errln("expected %g but got %g", expected, result);
|
||||
}
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
PluralRules *pr = PluralRules::createRules(rule, status);
|
||||
double result = pr->getUniqueKeywordValue(key);
|
||||
delete pr;
|
||||
if (expected != result) {
|
||||
errln("expected %g but got %g", expected, result);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: UniqueKeywordValue() is not currently supported.
|
||||
// If it never will be, this test code should be removed.
|
||||
void PluralRulesTest::testGetUniqueKeywordValue() {
|
||||
assertRuleValue("n is 1", 1);
|
||||
assertRuleValue("n in 2..2", 2);
|
||||
assertRuleValue("n within 2..2", 2);
|
||||
assertRuleValue("n in 3..4", UPLRULES_NO_UNIQUE_VALUE);
|
||||
assertRuleValue("n within 3..4", UPLRULES_NO_UNIQUE_VALUE);
|
||||
assertRuleValue("n is 2 or n is 2", 2);
|
||||
assertRuleValue("n is 2 and n is 2", 2);
|
||||
assertRuleValue("n is 2 or n is 3", UPLRULES_NO_UNIQUE_VALUE);
|
||||
assertRuleValue("n is 2 and n is 3", UPLRULES_NO_UNIQUE_VALUE);
|
||||
assertRuleValue("n is 2 or n in 2..3", UPLRULES_NO_UNIQUE_VALUE);
|
||||
assertRuleValue("n is 2 and n in 2..3", 2);
|
||||
assertRuleKeyValue("a: n is 1", "not_defined", UPLRULES_NO_UNIQUE_VALUE); // key not defined
|
||||
assertRuleKeyValue("a: n is 1", "other", UPLRULES_NO_UNIQUE_VALUE); // key matches default rule
|
||||
assertRuleValue("n is 1", 1);
|
||||
assertRuleValue("n in 2..2", 2);
|
||||
assertRuleValue("n within 2..2", 2);
|
||||
assertRuleValue("n in 3..4", UPLRULES_NO_UNIQUE_VALUE);
|
||||
assertRuleValue("n within 3..4", UPLRULES_NO_UNIQUE_VALUE);
|
||||
assertRuleValue("n is 2 or n is 2", 2);
|
||||
assertRuleValue("n is 2 and n is 2", 2);
|
||||
assertRuleValue("n is 2 or n is 3", UPLRULES_NO_UNIQUE_VALUE);
|
||||
assertRuleValue("n is 2 and n is 3", UPLRULES_NO_UNIQUE_VALUE);
|
||||
assertRuleValue("n is 2 or n in 2..3", UPLRULES_NO_UNIQUE_VALUE);
|
||||
assertRuleValue("n is 2 and n in 2..3", 2);
|
||||
assertRuleKeyValue("a: n is 1", "not_defined", UPLRULES_NO_UNIQUE_VALUE); // key not defined
|
||||
assertRuleKeyValue("a: n is 1", "other", UPLRULES_NO_UNIQUE_VALUE); // key matches default rule
|
||||
}
|
||||
|
||||
void PluralRulesTest::testGetSamples() {
|
||||
// TODO: fix samples, re-enable this test.
|
||||
// TODO: fix samples, re-enable this test.
|
||||
|
||||
// no get functional equivalent API in ICU4C, so just
|
||||
// test every locale...
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
int32_t numLocales;
|
||||
const Locale* locales = Locale::getAvailableLocales(numLocales);
|
||||
// no get functional equivalent API in ICU4C, so just
|
||||
// test every locale...
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
int32_t numLocales;
|
||||
const Locale* locales = Locale::getAvailableLocales(numLocales);
|
||||
|
||||
double values[1000];
|
||||
for (int32_t i = 0; U_SUCCESS(status) && i < numLocales; ++i) {
|
||||
if (uprv_strcmp(locales[i].getLanguage(), "fr") == 0 &&
|
||||
logKnownIssue("21299", "PluralRules::getSamples cannot distinguish 1e5 from 100000")) {
|
||||
continue;
|
||||
}
|
||||
PluralRules *rules = PluralRules::forLocale(locales[i], status);
|
||||
if (U_FAILURE(status)) {
|
||||
break;
|
||||
}
|
||||
StringEnumeration *keywords = rules->getKeywords(status);
|
||||
if (U_FAILURE(status)) {
|
||||
delete rules;
|
||||
break;
|
||||
}
|
||||
const UnicodeString* keyword;
|
||||
while (NULL != (keyword = keywords->snext(status))) {
|
||||
int32_t count = rules->getSamples(*keyword, values, UPRV_LENGTHOF(values), status);
|
||||
if (U_FAILURE(status)) {
|
||||
errln(UNICODE_STRING_SIMPLE("getSamples() failed for locale ") +
|
||||
locales[i].getName() +
|
||||
UNICODE_STRING_SIMPLE(", keyword ") + *keyword);
|
||||
continue;
|
||||
}
|
||||
if (count == 0) {
|
||||
// TODO: Lots of these.
|
||||
// errln(UNICODE_STRING_SIMPLE("no samples for keyword ") + *keyword + UNICODE_STRING_SIMPLE(" in locale ") + locales[i].getName() );
|
||||
}
|
||||
if (count > UPRV_LENGTHOF(values)) {
|
||||
errln(UNICODE_STRING_SIMPLE("getSamples()=") + count +
|
||||
UNICODE_STRING_SIMPLE(", too many values, for locale ") +
|
||||
locales[i].getName() +
|
||||
UNICODE_STRING_SIMPLE(", keyword ") + *keyword);
|
||||
count = UPRV_LENGTHOF(values);
|
||||
}
|
||||
for (int32_t j = 0; j < count; ++j) {
|
||||
if (values[j] == UPLRULES_NO_UNIQUE_VALUE) {
|
||||
errln("got 'no unique value' among values");
|
||||
} else {
|
||||
UnicodeString resultKeyword = rules->select(values[j]);
|
||||
// if (strcmp(locales[i].getName(), "uk") == 0) { // Debug only.
|
||||
// std::cout << " uk " << US(resultKeyword).cstr() << " " << values[j] << std::endl;
|
||||
// }
|
||||
if (*keyword != resultKeyword) {
|
||||
errln("file %s, line %d, Locale %s, sample for keyword \"%s\": %g, select(%g) returns keyword \"%s\"",
|
||||
__FILE__, __LINE__, locales[i].getName(), US(*keyword).cstr(), values[j], values[j], US(resultKeyword).cstr());
|
||||
}
|
||||
double values[1000];
|
||||
for (int32_t i = 0; U_SUCCESS(status) && i < numLocales; ++i) {
|
||||
if (uprv_strcmp(locales[i].getLanguage(), "fr") == 0 &&
|
||||
logKnownIssue("21299", "PluralRules::getSamples cannot distinguish 1e5 from 100000")) {
|
||||
continue;
|
||||
}
|
||||
LocalPointer<PluralRules> rules(PluralRules::forLocale(locales[i], status));
|
||||
if (U_FAILURE(status)) {
|
||||
break;
|
||||
}
|
||||
LocalPointer<StringEnumeration> keywords(rules->getKeywords(status));
|
||||
if (U_FAILURE(status)) {
|
||||
break;
|
||||
}
|
||||
const UnicodeString* keyword;
|
||||
while (NULL != (keyword = keywords->snext(status))) {
|
||||
int32_t count = rules->getSamples(*keyword, values, UPRV_LENGTHOF(values), status);
|
||||
if (U_FAILURE(status)) {
|
||||
errln(UnicodeString(u"getSamples() failed for locale ") +
|
||||
locales[i].getName() +
|
||||
UnicodeString(u", keyword ") + *keyword);
|
||||
continue;
|
||||
}
|
||||
if (count == 0) {
|
||||
// TODO: Lots of these.
|
||||
// errln(UnicodeString(u"no samples for keyword ") + *keyword + UnicodeString(u" in locale ") + locales[i].getName() );
|
||||
}
|
||||
if (count > UPRV_LENGTHOF(values)) {
|
||||
errln(UnicodeString(u"getSamples()=") + count +
|
||||
UnicodeString(u", too many values, for locale ") +
|
||||
locales[i].getName() +
|
||||
UnicodeString(u", keyword ") + *keyword);
|
||||
count = UPRV_LENGTHOF(values);
|
||||
}
|
||||
for (int32_t j = 0; j < count; ++j) {
|
||||
if (values[j] == UPLRULES_NO_UNIQUE_VALUE) {
|
||||
errln("got 'no unique value' among values");
|
||||
} else {
|
||||
UnicodeString resultKeyword = rules->select(values[j]);
|
||||
// if (strcmp(locales[i].getName(), "uk") == 0) { // Debug only.
|
||||
// std::cout << " uk " << US(resultKeyword).cstr() << " " << values[j] << std::endl;
|
||||
// }
|
||||
if (*keyword != resultKeyword) {
|
||||
errln("file %s, line %d, Locale %s, sample for keyword \"%s\": %g, select(%g) returns keyword \"%s\"",
|
||||
__FILE__, __LINE__, locales[i].getName(), US(*keyword).cstr(), values[j], values[j], US(resultKeyword).cstr());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
delete keywords;
|
||||
delete rules;
|
||||
}
|
||||
}
|
||||
|
||||
void PluralRulesTest::testGetFixedDecimalSamples() {
|
||||
// TODO: fix samples, re-enable this test.
|
||||
|
||||
// no get functional equivalent API in ICU4C, so just
|
||||
// test every locale...
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
int32_t numLocales;
|
||||
const Locale* locales = Locale::getAvailableLocales(numLocales);
|
||||
|
||||
FixedDecimal values[1000];
|
||||
for (int32_t i = 0; U_SUCCESS(status) && i < numLocales; ++i) {
|
||||
if (uprv_strcmp(locales[i].getLanguage(), "fr") == 0 &&
|
||||
logKnownIssue("21299", "PluralRules::getSamples cannot distinguish 1e5 from 100000")) {
|
||||
continue;
|
||||
}
|
||||
LocalPointer<PluralRules> rules(PluralRules::forLocale(locales[i], status));
|
||||
if (U_FAILURE(status)) {
|
||||
break;
|
||||
}
|
||||
LocalPointer<StringEnumeration> keywords(rules->getKeywords(status));
|
||||
if (U_FAILURE(status)) {
|
||||
break;
|
||||
}
|
||||
const UnicodeString* keyword;
|
||||
while (NULL != (keyword = keywords->snext(status))) {
|
||||
int32_t count = rules->getSamples(*keyword, values, UPRV_LENGTHOF(values), status);
|
||||
if (U_FAILURE(status)) {
|
||||
errln(UnicodeString(u"getSamples() failed for locale ") +
|
||||
locales[i].getName() +
|
||||
UnicodeString(u", keyword ") + *keyword);
|
||||
continue;
|
||||
}
|
||||
if (count == 0) {
|
||||
// TODO: Lots of these.
|
||||
// errln(UnicodeString(u"no samples for keyword ") + *keyword + UnicodeString(u" in locale ") + locales[i].getName() );
|
||||
}
|
||||
if (count > UPRV_LENGTHOF(values)) {
|
||||
errln(UnicodeString(u"getSamples()=") + count +
|
||||
UnicodeString(u", too many values, for locale ") +
|
||||
locales[i].getName() +
|
||||
UnicodeString(u", keyword ") + *keyword);
|
||||
count = UPRV_LENGTHOF(values);
|
||||
}
|
||||
for (int32_t j = 0; j < count; ++j) {
|
||||
if (values[j] == UPLRULES_NO_UNIQUE_VALUE_DECIMAL) {
|
||||
errln("got 'no unique value' among values");
|
||||
} else {
|
||||
UnicodeString resultKeyword = rules->select(values[j]);
|
||||
// if (strcmp(locales[i].getName(), "uk") == 0) { // Debug only.
|
||||
// std::cout << " uk " << US(resultKeyword).cstr() << " " << values[j] << std::endl;
|
||||
// }
|
||||
if (*keyword != resultKeyword) {
|
||||
errln("file %s, line %d, Locale %s, sample for keyword \"%s\": %s, select(%s) returns keyword \"%s\"",
|
||||
__FILE__, __LINE__, locales[i].getName(), US(*keyword).cstr(), values[j].toString().getBuffer(), values[j].toString().getBuffer(), US(resultKeyword).cstr());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PluralRulesTest::testSamplesWithExponent() {
|
||||
// integer samples
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
UnicodeString description(
|
||||
u"one: i = 0,1 @integer 0, 1, 1e5 @decimal 0.0~1.5, 1.1e5; "
|
||||
u"many: e = 0 and i != 0 and i % 1000000 = 0 and v = 0 or e != 0..5"
|
||||
u" @integer 1000000, 2e6, 3e6, 4e6, 5e6, 6e6, 7e6, … @decimal 2.1e6, 3.1e6, 4.1e6, 5.1e6, 6.1e6, 7.1e6, …; "
|
||||
u"other: @integer 2~17, 100, 1000, 10000, 100000, 2e5, 3e5, 4e5, 5e5, 6e5, 7e5, …"
|
||||
u" @decimal 2.0~3.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, 2.1e5, 3.1e5, 4.1e5, 5.1e5, 6.1e5, 7.1e5, …"
|
||||
);
|
||||
LocalPointer<PluralRules> test(PluralRules::createRules(description, status));
|
||||
if (U_FAILURE(status)) {
|
||||
errln("Couldn't create plural rules from a string using exponent notation, with error = %s", u_errorName(status));
|
||||
return;
|
||||
}
|
||||
checkNewSamples(description, test, u"one", u"@integer 0, 1, 1e5", FixedDecimal(0));
|
||||
checkNewSamples(description, test, u"many", u"@integer 1000000, 2e6, 3e6, 4e6, 5e6, 6e6, 7e6, …", FixedDecimal(1000000));
|
||||
checkNewSamples(description, test, u"other", u"@integer 2~17, 100, 1000, 10000, 100000, 2e5, 3e5, 4e5, 5e5, 6e5, 7e5, …", FixedDecimal(2));
|
||||
|
||||
// decimal samples
|
||||
status = U_ZERO_ERROR;
|
||||
UnicodeString description2(
|
||||
u"one: i = 0,1 @decimal 0.0~1.5, 1.1e5; "
|
||||
u"many: e = 0 and i != 0 and i % 1000000 = 0 and v = 0 or e != 0..5"
|
||||
u" @decimal 2.1e6, 3.1e6, 4.1e6, 5.1e6, 6.1e6, 7.1e6, …; "
|
||||
u"other: @decimal 2.0~3.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, 2.1e5, 3.1e5, 4.1e5, 5.1e5, 6.1e5, 7.1e5, …"
|
||||
);
|
||||
LocalPointer<PluralRules> test2(PluralRules::createRules(description2, status));
|
||||
if (U_FAILURE(status)) {
|
||||
errln("Couldn't create plural rules from a string using exponent notation, with error = %s", u_errorName(status));
|
||||
return;
|
||||
}
|
||||
checkNewSamples(description2, test2, u"one", u"@decimal 0.0~1.5, 1.1e5", FixedDecimal(0, 1));
|
||||
checkNewSamples(description2, test2, u"many", u"@decimal 2.1e6, 3.1e6, 4.1e6, 5.1e6, 6.1e6, 7.1e6, …", FixedDecimal::createWithExponent(2.1, 1, 6));
|
||||
checkNewSamples(description2, test2, u"other", u"@decimal 2.0~3.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, 2.1e5, 3.1e5, 4.1e5, 5.1e5, 6.1e5, 7.1e5, …", FixedDecimal(2.0, 1));
|
||||
}
|
||||
|
||||
void PluralRulesTest::checkNewSamples(
|
||||
UnicodeString description,
|
||||
const LocalPointer<PluralRules> &test,
|
||||
UnicodeString keyword,
|
||||
UnicodeString samplesString,
|
||||
FixedDecimal firstInRange) {
|
||||
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
FixedDecimal samples[1000];
|
||||
|
||||
test->getSamples(keyword, samples, UPRV_LENGTHOF(samples), status);
|
||||
if (U_FAILURE(status)) {
|
||||
errln("Couldn't retrieve plural samples, with error = %s", u_errorName(status));
|
||||
return;
|
||||
}
|
||||
FixedDecimal actualFirstSample = samples[0];
|
||||
|
||||
if (!(firstInRange == actualFirstSample)) {
|
||||
CStr descCstr(description);
|
||||
CStr samplesCstr(samplesString);
|
||||
char errMsg[1000];
|
||||
snprintf(errMsg, sizeof(errMsg), "First parsed sample FixedDecimal not equal to expected for samples: %s in rule string: %s\n", descCstr(), samplesCstr());
|
||||
errln(errMsg);
|
||||
}
|
||||
}
|
||||
|
||||
void PluralRulesTest::testWithin() {
|
||||
// goes to show you what lack of testing will do.
|
||||
// of course, this has been broken for two years and no one has noticed...
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
PluralRules *rules = PluralRules::createRules("a: n mod 10 in 5..8", status);
|
||||
if (!rules) {
|
||||
errln("couldn't instantiate rules");
|
||||
return;
|
||||
}
|
||||
// goes to show you what lack of testing will do.
|
||||
// of course, this has been broken for two years and no one has noticed...
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
PluralRules *rules = PluralRules::createRules("a: n mod 10 in 5..8", status);
|
||||
if (!rules) {
|
||||
errln("couldn't instantiate rules");
|
||||
return;
|
||||
}
|
||||
|
||||
UnicodeString keyword = rules->select((int32_t)26);
|
||||
if (keyword != "a") {
|
||||
errln("expected 'a' for 26 but didn't get it.");
|
||||
}
|
||||
UnicodeString keyword = rules->select((int32_t)26);
|
||||
if (keyword != "a") {
|
||||
errln("expected 'a' for 26 but didn't get it.");
|
||||
}
|
||||
|
||||
keyword = rules->select(26.5);
|
||||
if (keyword != "other") {
|
||||
errln("expected 'other' for 26.5 but didn't get it.");
|
||||
}
|
||||
keyword = rules->select(26.5);
|
||||
if (keyword != "other") {
|
||||
errln("expected 'other' for 26.5 but didn't get it.");
|
||||
}
|
||||
|
||||
delete rules;
|
||||
delete rules;
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -30,6 +30,8 @@ private:
|
||||
void testAPI();
|
||||
void testGetUniqueKeywordValue();
|
||||
void testGetSamples();
|
||||
void testGetFixedDecimalSamples();
|
||||
void testSamplesWithExponent();
|
||||
void testWithin();
|
||||
void testGetAllKeywordValues();
|
||||
void testCompactDecimalPluralKeyword();
|
||||
@@ -45,6 +47,11 @@ private:
|
||||
void assertRuleValue(const UnicodeString& rule, double expected);
|
||||
void assertRuleKeyValue(const UnicodeString& rule, const UnicodeString& key,
|
||||
double expected);
|
||||
void checkNewSamples(UnicodeString description,
|
||||
const LocalPointer<PluralRules> &test,
|
||||
UnicodeString keyword,
|
||||
UnicodeString samplesString,
|
||||
FixedDecimal firstInRange);
|
||||
UnicodeString getPluralKeyword(const LocalPointer<PluralRules> &rules,
|
||||
Locale locale, double number, const char16_t* skeleton);
|
||||
void checkSelect(const LocalPointer<PluralRules> &rules, UErrorCode &status,
|
||||
|
||||
@@ -104,7 +104,7 @@ main(int argc, char* argv[]) {
|
||||
"Reads the infiles with normalization data and\n"
|
||||
"creates a binary file, or a C source file (--csource), with the data,\n"
|
||||
"or writes a data file with the combined data (--combined).\n"
|
||||
"See http://userguide.icu-project.org/transforms/normalization#TOC-Data-File-Syntax\n"
|
||||
"See https://unicode-org.github.io/icu/userguide/transforms/normalization#data-file-syntax\n"
|
||||
"\n"
|
||||
"Alternate usage: %s [-options] a.txt b.txt minus p.txt q.txt -o outputfilename\n"
|
||||
"\n"
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
#include "unicode/utypes.h"
|
||||
|
||||
#ifndef U_TOOLUTIL_IMPLEMENTATION
|
||||
#error U_TOOLUTIL_IMPLEMENTATION not set - must be set for all ICU source files in common/ - see http://userguide.icu-project.org/howtouseicu
|
||||
#error U_TOOLUTIL_IMPLEMENTATION not set - must be set for all ICU source files in common/ - see https://unicode-org.github.io/icu/userguide/howtouseicu
|
||||
#endif
|
||||
|
||||
#if U_PLATFORM_USES_ONLY_WIN32_API
|
||||
|
||||
+159
-198
@@ -4,255 +4,216 @@
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<!-- © 2020 and later: Unicode, Inc. and others. -->
|
||||
<!-- License & terms of use: http://www.unicode.org/copyright.html -->
|
||||
<title>ICU4J API Comparison: ICU4J 66.1 with ICU4J 67.1</title>
|
||||
<title>ICU4J API Comparison: ICU4J 67.1 with ICU4J 68.1</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>ICU4J API Comparison: ICU4J 66.1 with ICU4J 67.1</h1>
|
||||
<h1>ICU4J API Comparison: ICU4J 67.1 with ICU4J 68.1</h1>
|
||||
|
||||
<hr/>
|
||||
<h2>Removed from ICU4J 66.1</h2>
|
||||
|
||||
<h3>Package com.ibm.icu.number</h3>
|
||||
<ul>
|
||||
FormattedNumber
|
||||
<ul>
|
||||
<li><span style='color:orange'>(draft)</span> public boolean <i>equals</i>(java.lang.Object)</li>
|
||||
<li><span style='color:orange'>(draft)</span> public int <i>hashCode</i>()</li>
|
||||
<li><span style='color:orange'>(draft)</span> public boolean <i>nextFieldPosition</i>(java.text.FieldPosition)</li>
|
||||
</ul>
|
||||
FormattedNumberRange
|
||||
<ul>
|
||||
<li><span style='color:orange'>(draft)</span> public boolean <i>nextFieldPosition</i>(java.text.FieldPosition)</li>
|
||||
</ul>
|
||||
Precision
|
||||
<ul>
|
||||
<li><span style='color:orange'>(draft)</span> public java.lang.Object <i>clone</i>()</li>
|
||||
</ul>
|
||||
ScientificNotation
|
||||
<ul>
|
||||
<li><span style='color:orange'>(draft)</span> public java.lang.Object <i>clone</i>()</li>
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
<h2>Removed from ICU4J 67.1</h2>
|
||||
<p>(no API removed)</p>
|
||||
|
||||
<hr/>
|
||||
<h2>Deprecated or Obsoleted in ICU4J 67.1</h2>
|
||||
<h2>Deprecated or Obsoleted in ICU4J 68.1</h2>
|
||||
<p>(no API obsoleted)</p>
|
||||
|
||||
<hr/>
|
||||
<h2>Changed in ICU4J 67.1 (old, new)</h2>
|
||||
<h2>Changed in ICU4J 68.1 (old, new)</h2>
|
||||
|
||||
<h3>Package com.ibm.icu.number</h3>
|
||||
<h3>Package com.ibm.icu.util</h3>
|
||||
<ul>
|
||||
<li> <span style='color:green'>(stable)</span> public abstract class <i>Precision</i> extends java.lang.Object implements java.lang.Cloneable</br>
|
||||
<span style='color:green'>(stable)</span> public abstract class <i>Precision</i> extends java.lang.Object</li>
|
||||
<li> <span style='color:green'>(stable)</span> public class <i>ScientificNotation</i> extends com.ibm.icu.number.Notation implements java.lang.Cloneable</br>
|
||||
<span style='color:green'>(stable)</span> public class <i>ScientificNotation</i> extends com.ibm.icu.number.Notation</li>
|
||||
<li> <span style='color:orange'>(draft)</span> public class <i>NoUnit</i> extends com.ibm.icu.util.MeasureUnit</br>
|
||||
<span style='color:orange'>(draft)</span> public final class <i>NoUnit</i> extends java.lang.Object</li>
|
||||
NoUnit
|
||||
<ul>
|
||||
<li> <span style='color:orange'>(draft)</span> public static final com.ibm.icu.util.NoUnit BASE</br>
|
||||
<span style='color:orange'>(draft)</span> public static final com.ibm.icu.util.MeasureUnit BASE</li>
|
||||
<li> <span style='color:orange'>(draft)</span> public static final com.ibm.icu.util.NoUnit PERCENT</br>
|
||||
<span style='color:orange'>(draft)</span> public static final com.ibm.icu.util.MeasureUnit PERCENT</li>
|
||||
<li> <span style='color:orange'>(draft)</span> public static final com.ibm.icu.util.NoUnit PERMILLE</br>
|
||||
<span style='color:orange'>(draft)</span> public static final com.ibm.icu.util.MeasureUnit PERMILLE</li>
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
|
||||
<hr/>
|
||||
<h2>Promoted to stable in ICU4J 67.1</h2>
|
||||
<h2>Promoted to stable in ICU4J 68.1</h2>
|
||||
|
||||
<h3>Package com.ibm.icu.text</h3>
|
||||
<ul>
|
||||
RelativeDateTimeFormatter.AbsoluteUnit
|
||||
<ul>
|
||||
<li><span style='color:green'>(stable)</span> public static final RelativeDateTimeFormatter.AbsoluteUnit HOUR</li>
|
||||
<li><span style='color:green'>(stable)</span> public static final RelativeDateTimeFormatter.AbsoluteUnit MINUTE</li>
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
<h3>Package com.ibm.icu.util</h3>
|
||||
<ul>
|
||||
<li><span style='color:green'>(stable)</span> public static final class <i>LocaleMatcher.Builder</i></li>
|
||||
<li><span style='color:green'>(stable)</span> public static final class <i>LocaleMatcher.Result</i></li>
|
||||
<li><span style='color:green'>(stable)</span> public static enum <i>LocaleMatcher.Demotion</i></li>
|
||||
<li><span style='color:green'>(stable)</span> public static enum <i>LocaleMatcher.FavorSubtag</i></li>
|
||||
<li><span style='color:green'>(stable)</span> public static enum <i>ULocale.AvailableType</i></li>
|
||||
LocaleMatcher
|
||||
<ul>
|
||||
<li><span style='color:green'>(stable)</span> public static LocaleMatcher.Builder <i>builder</i>()</li>
|
||||
<li><span style='color:green'>(stable)</span> public java.util.Locale <i>getBestLocale</i>(java.lang.Iterable<java.util.Locale>)</li>
|
||||
<li><span style='color:green'>(stable)</span> public java.util.Locale <i>getBestLocale</i>(java.util.Locale)</li>
|
||||
<li><span style='color:green'>(stable)</span> public LocaleMatcher.Result <i>getBestLocaleResult</i>(java.lang.Iterable<java.util.Locale>)</li>
|
||||
<li><span style='color:green'>(stable)</span> public LocaleMatcher.Result <i>getBestLocaleResult</i>(java.util.Locale)</li>
|
||||
<li><span style='color:green'>(stable)</span> public LocaleMatcher.Result <i>getBestMatchResult</i>(ULocale)</li>
|
||||
<li><span style='color:green'>(stable)</span> public LocaleMatcher.Result <i>getBestMatchResult</i>(java.lang.Iterable<ULocale>)</li>
|
||||
</ul>
|
||||
LocaleMatcher.Demotion
|
||||
<ul>
|
||||
<li><span style='color:green'>(stable)</span> public static final LocaleMatcher.Demotion NONE</li>
|
||||
<li><span style='color:green'>(stable)</span> public static final LocaleMatcher.Demotion REGION</li>
|
||||
</ul>
|
||||
LocaleMatcher.FavorSubtag
|
||||
<ul>
|
||||
<li><span style='color:green'>(stable)</span> public static final LocaleMatcher.FavorSubtag LANGUAGE</li>
|
||||
<li><span style='color:green'>(stable)</span> public static final LocaleMatcher.FavorSubtag SCRIPT</li>
|
||||
</ul>
|
||||
LocalePriorityList
|
||||
<ul>
|
||||
<li><span style='color:green'>(stable)</span> public java.util.Set<ULocale> <i>getULocales</i>()</li>
|
||||
</ul>
|
||||
MeasureUnit
|
||||
<ul>
|
||||
<li><span style='color:green'>(stable)</span> public static final MeasureUnit BAR</li>
|
||||
<li><span style='color:green'>(stable)</span> public static final MeasureUnit DECADE</li>
|
||||
<li><span style='color:green'>(stable)</span> public static final MeasureUnit DOT_PER_CENTIMETER</li>
|
||||
<li><span style='color:green'>(stable)</span> public static final MeasureUnit DOT_PER_INCH</li>
|
||||
<li><span style='color:green'>(stable)</span> public static final MeasureUnit EM</li>
|
||||
<li><span style='color:green'>(stable)</span> public static final MeasureUnit MEGAPIXEL</li>
|
||||
<li><span style='color:green'>(stable)</span> public static final MeasureUnit PASCAL</li>
|
||||
<li><span style='color:green'>(stable)</span> public static final MeasureUnit PIXEL</li>
|
||||
<li><span style='color:green'>(stable)</span> public static final MeasureUnit PIXEL_PER_CENTIMETER</li>
|
||||
<li><span style='color:green'>(stable)</span> public static final MeasureUnit PIXEL_PER_INCH</li>
|
||||
<li><span style='color:green'>(stable)</span> public static final MeasureUnit THERM_US</li>
|
||||
</ul>
|
||||
ULocale
|
||||
<ul>
|
||||
<li><span style='color:green'>(stable)</span> public static java.util.Collection<ULocale> <i>getAvailableLocalesByType</i>(ULocale.AvailableType)</li>
|
||||
</ul>
|
||||
ULocale.AvailableType
|
||||
<ul>
|
||||
<li><span style='color:green'>(stable)</span> public static final ULocale.AvailableType DEFAULT</li>
|
||||
<li><span style='color:green'>(stable)</span> public static final ULocale.AvailableType ONLY_LEGACY_ALIASES</li>
|
||||
<li><span style='color:green'>(stable)</span> public static final ULocale.AvailableType WITH_LEGACY_ALIASES</li>
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
|
||||
<hr/>
|
||||
<h2>Added in ICU4J 68.1</h2>
|
||||
|
||||
<h3>Package com.ibm.icu.number</h3>
|
||||
<ul>
|
||||
FormattedNumber
|
||||
<ul>
|
||||
<li><span style='color:green'>(stable)</span> public char <i>charAt</i>(int)</li>
|
||||
<li><span style='color:green'>(stable)</span> public int <i>length</i>()</li>
|
||||
<li><span style='color:green'>(stable)</span> public boolean <i>nextPosition</i>(ConstrainedFieldPosition)</li>
|
||||
<li><span style='color:green'>(stable)</span> public java.lang.CharSequence <i>subSequence</i>(int, int)</li>
|
||||
<li><span style='color:orange'>(draft)</span> public MeasureUnit <i>getOutputUnit</i>()</li>
|
||||
</ul>
|
||||
FormattedNumberRange
|
||||
NumberFormatterSettings
|
||||
<ul>
|
||||
<li><span style='color:green'>(stable)</span> public char <i>charAt</i>(int)</li>
|
||||
<li><span style='color:green'>(stable)</span> public boolean <i>equals</i>(java.lang.Object)</li>
|
||||
<li><span style='color:green'>(stable)</span> public int <i>hashCode</i>()</li>
|
||||
<li><span style='color:green'>(stable)</span> public int <i>length</i>()</li>
|
||||
<li><span style='color:green'>(stable)</span> public boolean <i>nextPosition</i>(ConstrainedFieldPosition)</li>
|
||||
<li><span style='color:green'>(stable)</span> public java.lang.CharSequence <i>subSequence</i>(int, int)</li>
|
||||
<li><span style='color:orange'>(draft)</span> public T extends NumberFormatterSettings<?> <i>usage</i>(java.lang.String)</li>
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
<h3>Package com.ibm.icu.text</h3>
|
||||
<ul>
|
||||
<li><span style='color:green'>(stable)</span> public class <i>ConstrainedFieldPosition</i></li>
|
||||
<li><span style='color:green'>(stable)</span> public static final class <i>DateIntervalFormat.FormattedDateInterval</i></li>
|
||||
<li><span style='color:green'>(stable)</span> public static final class <i>DateIntervalFormat.SpanField</i></li>
|
||||
<li><span style='color:green'>(stable)</span> public interface <i>FormattedValue</i></li>
|
||||
<li><span style='color:green'>(stable)</span> public static class <i>RelativeDateTimeFormatter.Field</i></li>
|
||||
<li><span style='color:green'>(stable)</span> public static class <i>RelativeDateTimeFormatter.FormattedRelativeDateTime</i></li>
|
||||
<li><span style='color:green'>(stable)</span> public static abstract class <i>UFormat.SpanField</i></li>
|
||||
DateFormatSymbols
|
||||
<ul>
|
||||
<li><span style='color:green'>(stable)</span> public java.lang.String[] <i>getNarrowEras</i>()</li>
|
||||
<li><span style='color:green'>(stable)</span> public void <i>setNarrowEras</i>(java.lang.String[])</li>
|
||||
</ul>
|
||||
DateIntervalFormat
|
||||
<ul>
|
||||
<li><span style='color:green'>(stable)</span> public DateIntervalFormat.FormattedDateInterval <i>formatToValue</i>(Calendar, Calendar)</li>
|
||||
<li><span style='color:green'>(stable)</span> public DateIntervalFormat.FormattedDateInterval <i>formatToValue</i>(DateInterval)</li>
|
||||
<li><span style='color:orange'>(draft)</span> public DisplayContext <i>getContext</i>(DisplayContext.Type)</li>
|
||||
<li><span style='color:orange'>(draft)</span> public void <i>setContext</i>(DisplayContext)</li>
|
||||
</ul>
|
||||
DecimalFormat
|
||||
<ul>
|
||||
<li><span style='color:green'>(stable)</span> public synchronized int <i>getMinimumGroupingDigits</i>()</li>
|
||||
<li><span style='color:green'>(stable)</span> public synchronized boolean <i>isParseCaseSensitive</i>()</li>
|
||||
<li><span style='color:green'>(stable)</span> public synchronized boolean <i>isParseNoExponent</i>()</li>
|
||||
<li><span style='color:green'>(stable)</span> public synchronized boolean <i>isSignAlwaysShown</i>()</li>
|
||||
<li><span style='color:green'>(stable)</span> public synchronized void <i>setMinimumGroupingDigits</i>(int)</li>
|
||||
<li><span style='color:green'>(stable)</span> public synchronized void <i>setParseCaseSensitive</i>(boolean)</li>
|
||||
<li><span style='color:green'>(stable)</span> public synchronized void <i>setParseNoExponent</i>(boolean)</li>
|
||||
<li><span style='color:green'>(stable)</span> public synchronized void <i>setSignAlwaysShown</i>(boolean)</li>
|
||||
</ul>
|
||||
NumberFormat.Field
|
||||
<ul>
|
||||
<li><span style='color:green'>(stable)</span> public static final NumberFormat.Field COMPACT</li>
|
||||
<li><span style='color:green'>(stable)</span> public static final NumberFormat.Field MEASURE_UNIT</li>
|
||||
<li><span style='color:orange'>(draft)</span> public static final int MINIMUM_GROUPING_DIGITS_AUTO</li>
|
||||
<li><span style='color:orange'>(draft)</span> public static final int MINIMUM_GROUPING_DIGITS_MIN2</li>
|
||||
</ul>
|
||||
PluralRules
|
||||
<ul>
|
||||
<li><span style='color:green'>(stable)</span> public java.lang.String <i>select</i>(FormattedNumber)</li>
|
||||
</ul>
|
||||
RelativeDateTimeFormatter
|
||||
<ul>
|
||||
<li><span style='color:green'>(stable)</span> public RelativeDateTimeFormatter.FormattedRelativeDateTime <i>formatNumericToValue</i>(double, RelativeDateTimeFormatter.RelativeDateTimeUnit)</li>
|
||||
<li><span style='color:green'>(stable)</span> public RelativeDateTimeFormatter.FormattedRelativeDateTime <i>formatToValue</i>(RelativeDateTimeFormatter.Direction, RelativeDateTimeFormatter.AbsoluteUnit)</li>
|
||||
<li><span style='color:green'>(stable)</span> public RelativeDateTimeFormatter.FormattedRelativeDateTime <i>formatToValue</i>(double, RelativeDateTimeFormatter.Direction, RelativeDateTimeFormatter.RelativeUnit)</li>
|
||||
<li><span style='color:green'>(stable)</span> public RelativeDateTimeFormatter.FormattedRelativeDateTime <i>formatToValue</i>(double, RelativeDateTimeFormatter.RelativeDateTimeUnit)</li>
|
||||
</ul>
|
||||
RelativeDateTimeFormatter.AbsoluteUnit
|
||||
<ul>
|
||||
<li><span style='color:green'>(stable)</span> public static final RelativeDateTimeFormatter.AbsoluteUnit QUARTER</li>
|
||||
<li><span style='color:orange'>(draft)</span> public java.lang.String <i>select</i>(FormattedNumberRange)</li>
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
<h3>Package com.ibm.icu.util</h3>
|
||||
<ul>
|
||||
BytesTrie
|
||||
<li><span style='color:orange'>(draft)</span> public class <i>ICUInputTooLongException</i></li>
|
||||
<li><span style='color:orange'>(draft)</span> public static enum <i>MeasureUnit.Complexity</i></li>
|
||||
<li><span style='color:orange'>(draft)</span> public static enum <i>MeasureUnit.SIPrefix</i></li>
|
||||
LocaleMatcher
|
||||
<ul>
|
||||
<li><span style='color:green'>(stable)</span> public <i>BytesTrie</i>(BytesTrie)</li>
|
||||
<li><span style='color:green'>(stable)</span> public long <i>getState64</i>()</li>
|
||||
<li><span style='color:green'>(stable)</span> public BytesTrie <i>resetToState64</i>(long)</li>
|
||||
</ul>
|
||||
CharsTrie
|
||||
<ul>
|
||||
<li><span style='color:green'>(stable)</span> public <i>CharsTrie</i>(CharsTrie)</li>
|
||||
<li><span style='color:green'>(stable)</span> public long <i>getState64</i>()</li>
|
||||
<li><span style='color:green'>(stable)</span> public CharsTrie <i>resetToState64</i>(long)</li>
|
||||
</ul>
|
||||
MeasureUnit
|
||||
<ul>
|
||||
<li><span style='color:green'>(stable)</span> public static final MeasureUnit BARREL</li>
|
||||
<li><span style='color:green'>(stable)</span> public static final MeasureUnit BRITISH_THERMAL_UNIT</li>
|
||||
<li><span style='color:green'>(stable)</span> public static final MeasureUnit DALTON</li>
|
||||
<li><span style='color:green'>(stable)</span> public static final MeasureUnit DAY_PERSON</li>
|
||||
<li><span style='color:green'>(stable)</span> public static final MeasureUnit DUNAM</li>
|
||||
<li><span style='color:green'>(stable)</span> public static final MeasureUnit EARTH_MASS</li>
|
||||
<li><span style='color:green'>(stable)</span> public static final MeasureUnit ELECTRONVOLT</li>
|
||||
<li><span style='color:green'>(stable)</span> public static final MeasureUnit FLUID_OUNCE_IMPERIAL</li>
|
||||
<li><span style='color:green'>(stable)</span> public static final MeasureUnit KILOPASCAL</li>
|
||||
<li><span style='color:green'>(stable)</span> public static final MeasureUnit MEGAPASCAL</li>
|
||||
<li><span style='color:green'>(stable)</span> public static final MeasureUnit MOLE</li>
|
||||
<li><span style='color:green'>(stable)</span> public static final MeasureUnit MONTH_PERSON</li>
|
||||
<li><span style='color:green'>(stable)</span> public static final MeasureUnit NEWTON</li>
|
||||
<li><span style='color:green'>(stable)</span> public static final MeasureUnit NEWTON_METER</li>
|
||||
<li><span style='color:green'>(stable)</span> public static final MeasureUnit PERMYRIAD</li>
|
||||
<li><span style='color:green'>(stable)</span> public static final MeasureUnit POUND_FOOT</li>
|
||||
<li><span style='color:green'>(stable)</span> public static final MeasureUnit POUND_FORCE</li>
|
||||
<li><span style='color:green'>(stable)</span> public static final MeasureUnit SOLAR_LUMINOSITY</li>
|
||||
<li><span style='color:green'>(stable)</span> public static final MeasureUnit SOLAR_MASS</li>
|
||||
<li><span style='color:green'>(stable)</span> public static final MeasureUnit SOLAR_RADIUS</li>
|
||||
<li><span style='color:green'>(stable)</span> public static final MeasureUnit WEEK_PERSON</li>
|
||||
<li><span style='color:green'>(stable)</span> public static final MeasureUnit YEAR_PERSON</li>
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
|
||||
<hr/>
|
||||
<h2>Added in ICU4J 67.1</h2>
|
||||
|
||||
<h3>Package com.ibm.icu.number</h3>
|
||||
<ul>
|
||||
NumberFormatter.UnitWidth
|
||||
<ul>
|
||||
<li><span style='color:orange'>(draft)</span> public static final NumberFormatter.UnitWidth FORMAL</li>
|
||||
<li><span style='color:orange'>(draft)</span> public static final NumberFormatter.UnitWidth VARIANT</li>
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
<h3>Package com.ibm.icu.text</h3>
|
||||
<ul>
|
||||
<li><span style='color:orange'>(draft)</span> public static final class <i>ListFormatter.Field</i></li>
|
||||
<li><span style='color:orange'>(draft)</span> public static final class <i>ListFormatter.FormattedList</i></li>
|
||||
<li><span style='color:orange'>(draft)</span> public static final class <i>ListFormatter.SpanField</i></li>
|
||||
<li><span style='color:orange'>(draft)</span> public static enum <i>DateFormat.HourCycle</i></li>
|
||||
<li><span style='color:orange'>(draft)</span> public static enum <i>ListFormatter.Type</i></li>
|
||||
<li><span style='color:orange'>(draft)</span> public static enum <i>ListFormatter.Width</i></li>
|
||||
CurrencyDisplayNames
|
||||
<ul>
|
||||
<li><span style='color:orange'>(draft)</span> public abstract java.lang.String <i>getFormalSymbol</i>(java.lang.String)</li>
|
||||
<li><span style='color:orange'>(draft)</span> public abstract java.lang.String <i>getVariantSymbol</i>(java.lang.String)</li>
|
||||
</ul>
|
||||
DateFormat.HourCycle
|
||||
<ul>
|
||||
<li><span style='color:orange'>(draft)</span> public static final DateFormat.HourCycle HOUR_CYCLE_11</li>
|
||||
<li><span style='color:orange'>(draft)</span> public static final DateFormat.HourCycle HOUR_CYCLE_12</li>
|
||||
<li><span style='color:orange'>(draft)</span> public static final DateFormat.HourCycle HOUR_CYCLE_23</li>
|
||||
<li><span style='color:orange'>(draft)</span> public static final DateFormat.HourCycle HOUR_CYCLE_24</li>
|
||||
</ul>
|
||||
DateTimePatternGenerator
|
||||
<ul>
|
||||
<li><span style='color:orange'>(draft)</span> public DateFormat.HourCycle <i>getDefaultHourCycle</i>()</li>
|
||||
</ul>
|
||||
DecimalFormatSymbols
|
||||
<ul>
|
||||
<li><span style='color:gray'>(deprecated)</span> public java.lang.String <i>getCurrencyPattern</i>()</li>
|
||||
</ul>
|
||||
ListFormatter
|
||||
<ul>
|
||||
<li><span style='color:orange'>(draft)</span> public ListFormatter.FormattedList <i>formatToValue</i>(java.lang.Object...)</li>
|
||||
<li><span style='color:orange'>(draft)</span> public ListFormatter.FormattedList <i>formatToValue</i>(java.util.Collection<?>)</li>
|
||||
<li><span style='color:orange'>(draft)</span> public static ListFormatter <i>getInstance</i>(ULocale, ListFormatter.Type, ListFormatter.Width)</li>
|
||||
<li><span style='color:orange'>(draft)</span> public static ListFormatter <i>getInstance</i>(java.util.Locale, ListFormatter.Type, ListFormatter.Width)</li>
|
||||
</ul>
|
||||
ListFormatter.Type
|
||||
<ul>
|
||||
<li><span style='color:orange'>(draft)</span> public static final ListFormatter.Type AND</li>
|
||||
<li><span style='color:orange'>(draft)</span> public static final ListFormatter.Type OR</li>
|
||||
<li><span style='color:orange'>(draft)</span> public static final ListFormatter.Type UNITS</li>
|
||||
</ul>
|
||||
ListFormatter.Width
|
||||
<ul>
|
||||
<li><span style='color:orange'>(draft)</span> public static final ListFormatter.Width NARROW</li>
|
||||
<li><span style='color:orange'>(draft)</span> public static final ListFormatter.Width SHORT</li>
|
||||
<li><span style='color:orange'>(draft)</span> public static final ListFormatter.Width WIDE</li>
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
<h3>Package com.ibm.icu.util</h3>
|
||||
<ul>
|
||||
<li><span style='color:orange'>(draft)</span> public static enum <i>LocaleMatcher.Direction</i></li>
|
||||
Currency
|
||||
<ul>
|
||||
<li><span style='color:orange'>(draft)</span> public static final int FORMAL_SYMBOL_NAME</li>
|
||||
<li><span style='color:orange'>(draft)</span> public static final int VARIANT_SYMBOL_NAME</li>
|
||||
<li><span style='color:orange'>(draft)</span> public boolean <i>isMatch</i>(ULocale, ULocale)</li>
|
||||
<li><span style='color:orange'>(draft)</span> public boolean <i>isMatch</i>(java.util.Locale, java.util.Locale)</li>
|
||||
</ul>
|
||||
LocaleMatcher.Builder
|
||||
<ul>
|
||||
<li><span style='color:orange'>(draft)</span> public LocaleMatcher.Builder <i>setDirection</i>(LocaleMatcher.Direction)</li>
|
||||
<li><span style='color:orange'>(draft)</span> public LocaleMatcher.Builder <i>setMaxDistance</i>(ULocale, ULocale)</li>
|
||||
<li><span style='color:orange'>(draft)</span> public LocaleMatcher.Builder <i>setMaxDistance</i>(java.util.Locale, java.util.Locale)</li>
|
||||
<li><span style='color:orange'>(draft)</span> public LocaleMatcher.Builder <i>setNoDefaultLocale</i>()</li>
|
||||
</ul>
|
||||
LocaleMatcher.Direction
|
||||
MeasureUnit
|
||||
<ul>
|
||||
<li><span style='color:orange'>(draft)</span> public static final LocaleMatcher.Direction ONLY_TWO_WAY</li>
|
||||
<li><span style='color:orange'>(draft)</span> public static final LocaleMatcher.Direction WITH_ONE_WAY</li>
|
||||
<li><span style='color:orange'>(draft)</span> public static final MeasureUnit CANDELA</li>
|
||||
<li><span style='color:orange'>(draft)</span> public static final MeasureUnit DESSERT_SPOON</li>
|
||||
<li><span style='color:orange'>(draft)</span> public static final MeasureUnit DESSERT_SPOON_IMPERIAL</li>
|
||||
<li><span style='color:orange'>(draft)</span> public static final MeasureUnit DOT</li>
|
||||
<li><span style='color:orange'>(draft)</span> public static final MeasureUnit DRAM</li>
|
||||
<li><span style='color:orange'>(draft)</span> public static final MeasureUnit DROP</li>
|
||||
<li><span style='color:orange'>(draft)</span> public static final MeasureUnit EARTH_RADIUS</li>
|
||||
<li><span style='color:orange'>(draft)</span> public static final MeasureUnit GRAIN</li>
|
||||
<li><span style='color:orange'>(draft)</span> public static final MeasureUnit JIGGER</li>
|
||||
<li><span style='color:orange'>(draft)</span> public static final MeasureUnit LUMEN</li>
|
||||
<li><span style='color:orange'>(draft)</span> public static final MeasureUnit PINCH</li>
|
||||
<li><span style='color:orange'>(draft)</span> public static final MeasureUnit QUART_IMPERIAL</li>
|
||||
<li><span style='color:orange'>(draft)</span> public static MeasureUnit <i>forIdentifier</i>(java.lang.String)</li>
|
||||
<li><span style='color:orange'>(draft)</span> public MeasureUnit.Complexity <i>getComplexity</i>()</li>
|
||||
<li><span style='color:orange'>(draft)</span> public int <i>getDimensionality</i>()</li>
|
||||
<li><span style='color:orange'>(draft)</span> public java.lang.String <i>getIdentifier</i>()</li>
|
||||
<li><span style='color:orange'>(draft)</span> public MeasureUnit.SIPrefix <i>getSIPrefix</i>()</li>
|
||||
<li><span style='color:orange'>(draft)</span> public MeasureUnit <i>product</i>(MeasureUnit)</li>
|
||||
<li><span style='color:orange'>(draft)</span> public MeasureUnit <i>reciprocal</i>()</li>
|
||||
<li><span style='color:orange'>(draft)</span> public java.util.List<MeasureUnit> <i>splitToSingleUnits</i>()</li>
|
||||
<li><span style='color:orange'>(draft)</span> public MeasureUnit <i>withDimensionality</i>(int)</li>
|
||||
<li><span style='color:orange'>(draft)</span> public MeasureUnit <i>withSIPrefix</i>(MeasureUnit.SIPrefix)</li>
|
||||
</ul>
|
||||
ULocale
|
||||
MeasureUnit.Complexity
|
||||
<ul>
|
||||
<li><span style='color:orange'>(draft)</span> public static ULocale <i>createCanonical</i>(ULocale)</li>
|
||||
<li><span style='color:orange'>(draft)</span> public static final MeasureUnit.Complexity COMPOUND</li>
|
||||
<li><span style='color:orange'>(draft)</span> public static final MeasureUnit.Complexity MIXED</li>
|
||||
<li><span style='color:orange'>(draft)</span> public static final MeasureUnit.Complexity SINGLE</li>
|
||||
</ul>
|
||||
MeasureUnit.SIPrefix
|
||||
<ul>
|
||||
<li><span style='color:orange'>(draft)</span> public int <i>getPower</i>()</li>
|
||||
<li><span style='color:orange'>(draft)</span> public static final MeasureUnit.SIPrefix ATTO</li>
|
||||
<li><span style='color:orange'>(draft)</span> public static final MeasureUnit.SIPrefix CENTI</li>
|
||||
<li><span style='color:orange'>(draft)</span> public static final MeasureUnit.SIPrefix DECI</li>
|
||||
<li><span style='color:orange'>(draft)</span> public static final MeasureUnit.SIPrefix DEKA</li>
|
||||
<li><span style='color:orange'>(draft)</span> public static final MeasureUnit.SIPrefix EXA</li>
|
||||
<li><span style='color:orange'>(draft)</span> public static final MeasureUnit.SIPrefix FEMTO</li>
|
||||
<li><span style='color:orange'>(draft)</span> public static final MeasureUnit.SIPrefix GIGA</li>
|
||||
<li><span style='color:orange'>(draft)</span> public static final MeasureUnit.SIPrefix HECTO</li>
|
||||
<li><span style='color:orange'>(draft)</span> public static final MeasureUnit.SIPrefix KILO</li>
|
||||
<li><span style='color:orange'>(draft)</span> public static final MeasureUnit.SIPrefix MEGA</li>
|
||||
<li><span style='color:orange'>(draft)</span> public static final MeasureUnit.SIPrefix MICRO</li>
|
||||
<li><span style='color:orange'>(draft)</span> public static final MeasureUnit.SIPrefix MILLI</li>
|
||||
<li><span style='color:orange'>(draft)</span> public static final MeasureUnit.SIPrefix NANO</li>
|
||||
<li><span style='color:orange'>(draft)</span> public static final MeasureUnit.SIPrefix ONE</li>
|
||||
<li><span style='color:orange'>(draft)</span> public static final MeasureUnit.SIPrefix PETA</li>
|
||||
<li><span style='color:orange'>(draft)</span> public static final MeasureUnit.SIPrefix PICO</li>
|
||||
<li><span style='color:orange'>(draft)</span> public static final MeasureUnit.SIPrefix TERA</li>
|
||||
<li><span style='color:orange'>(draft)</span> public static final MeasureUnit.SIPrefix YOCTO</li>
|
||||
<li><span style='color:orange'>(draft)</span> public static final MeasureUnit.SIPrefix YOTTA</li>
|
||||
<li><span style='color:orange'>(draft)</span> public static final MeasureUnit.SIPrefix ZEPTO</li>
|
||||
<li><span style='color:orange'>(draft)</span> public static final MeasureUnit.SIPrefix ZETTA</li>
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
<hr/>
|
||||
<p><i><font size="-1">Contents generated by ReportAPI tool on Wed Apr 01 16:15:30 EDT 2020<br/>© 2020 and later: Unicode, Inc. and others. License & terms of use: <a href="http://www.unicode.org/copyright.html">http://www.unicode.org/copyright.html</a></font></i></p>
|
||||
<p><i><font size="-1">Contents generated by ReportAPI tool on Thu Oct 01 10:15:24 PDT 2020<br/>© 2020 and later: Unicode, Inc. and others. License & terms of use: <a href="http://www.unicode.org/copyright.html">http://www.unicode.org/copyright.html</a></font></i></p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -55,7 +55,7 @@ import com.ibm.icu.impl.coll.UVector32;
|
||||
* can not be compared simply by using basic arithmetic operators,
|
||||
* e.g. <, == or >, further processing has to be done. Details
|
||||
* can be found in the ICU
|
||||
* <a href="http://userguide.icu-project.org/collation/architecture">
|
||||
* <a href="https://unicode-org.github.io/icu/userguide/collation/architecture">
|
||||
* User Guide</a>. An example of using the CollationElementIterator
|
||||
* for collation ordering comparison is the class
|
||||
* {@link com.ibm.icu.text.StringSearch}.
|
||||
|
||||
@@ -491,7 +491,7 @@ public final class CollationKey implements Comparable<CollationKey>
|
||||
* Using strings with U+FFFE may yield shorter sort keys.
|
||||
*
|
||||
* <p>For details about Sort Key Features see
|
||||
* http://userguide.icu-project.org/collation/api#TOC-Sort-Key-Features
|
||||
* https://unicode-org.github.io/icu/userguide/collation/api#sort-key-features
|
||||
*
|
||||
* <p>It is possible to merge multiple sort keys by consecutively merging
|
||||
* another one with the intermediate result.
|
||||
|
||||
@@ -64,7 +64,7 @@ import com.ibm.icu.util.VersionInfo;
|
||||
* difference between large and small Kana. A tertiary difference is ignored
|
||||
* when there is a primary or secondary difference anywhere in the strings.
|
||||
* <li>QUATERNARY strength: When punctuation is ignored
|
||||
* (see <a href="http://userguide.icu-project.org/collation/concepts#TOC-Ignoring-Punctuation">
|
||||
* (see <a href="https://unicode-org.github.io/icu/userguide/collation/concepts#ignoring-punctuation">
|
||||
* Ignoring Punctuations in the User Guide</a>) at PRIMARY to TERTIARY
|
||||
* strength, an additional strength level can
|
||||
* be used to distinguish words with and without punctuation (for example,
|
||||
@@ -95,7 +95,7 @@ import com.ibm.icu.util.VersionInfo;
|
||||
* a comparison or before getting a CollationKey.
|
||||
*
|
||||
* <p>For more information about the collation service see the
|
||||
* <a href="http://userguide.icu-project.org/collation">User Guide</a>.
|
||||
* <a href="https://unicode-org.github.io/icu/userguide/collation">User Guide</a>.
|
||||
*
|
||||
* <p>Examples of use
|
||||
* <pre>
|
||||
@@ -172,7 +172,7 @@ public abstract class Collator implements Comparator<Object>, Freezable<Collator
|
||||
/**
|
||||
* {@icu} Fourth level collator strength value.
|
||||
* When punctuation is ignored
|
||||
* (see <a href="http://userguide.icu-project.org/collation/concepts#TOC-Ignoring-Punctuation">
|
||||
* (see <a href="https://unicode-org.github.io/icu/userguide/collation/concepts#ignoring-punctuation">
|
||||
* Ignoring Punctuation in the User Guide</a>) at PRIMARY to TERTIARY
|
||||
* strength, an additional strength level can
|
||||
* be used to distinguish words with and without punctuation.
|
||||
@@ -807,7 +807,7 @@ public abstract class Collator implements Comparator<Object>, Freezable<Collator
|
||||
* Starting with ICU 54, collation attributes can be specified via locale keywords as well,
|
||||
* in the old locale extension syntax ("el@colCaseFirst=upper")
|
||||
* or in language tag syntax ("el-u-kf-upper").
|
||||
* See <a href="http://userguide.icu-project.org/collation/api">User Guide: Collation API</a>.
|
||||
* See <a href="https://unicode-org.github.io/icu/userguide/collation/api">User Guide: Collation API</a>.
|
||||
*
|
||||
* @param locale the desired locale.
|
||||
* @return Collator for the desired locale if it is created successfully.
|
||||
@@ -841,7 +841,7 @@ public abstract class Collator implements Comparator<Object>, Freezable<Collator
|
||||
* Starting with ICU 54, collation attributes can be specified via locale keywords as well,
|
||||
* in the old locale extension syntax ("el@colCaseFirst=upper", only with {@link ULocale})
|
||||
* or in language tag syntax ("el-u-kf-upper").
|
||||
* See <a href="http://userguide.icu-project.org/collation/api">User Guide: Collation API</a>.
|
||||
* See <a href="https://unicode-org.github.io/icu/userguide/collation/api">User Guide: Collation API</a>.
|
||||
*
|
||||
* @param locale the desired locale.
|
||||
* @return Collator for the desired locale if it is created successfully.
|
||||
@@ -1056,7 +1056,7 @@ public abstract class Collator implements Comparator<Object>, Freezable<Collator
|
||||
* applications who wish to cache collators, or otherwise reuse
|
||||
* collators when possible. The functional equivalent may change
|
||||
* over time. For more information, please see the <a
|
||||
* href="http://userguide.icu-project.org/locale#TOC-Locales-and-Services">
|
||||
* href="https://unicode-org.github.io/icu/userguide/locale#locales-and-services">
|
||||
* Locales and Services</a> section of the ICU User Guide.
|
||||
* @param keyword a particular keyword as enumerated by
|
||||
* getKeywords.
|
||||
|
||||
@@ -50,7 +50,7 @@ import com.ibm.icu.util.VersionInfo;
|
||||
* <p>A Collator is thread-safe only when frozen. See {{@link #isFrozen()} and {@link com.ibm.icu.util.Freezable}.
|
||||
*
|
||||
* <p>
|
||||
* Users are strongly encouraged to read the <a href="http://userguide.icu-project.org/collation">User
|
||||
* Users are strongly encouraged to read the <a href="https://unicode-org.github.io/icu/userguide/collation">User
|
||||
* Guide</a> for more information about the collation service before using this class.
|
||||
*
|
||||
* <p>
|
||||
@@ -67,8 +67,8 @@ import com.ibm.icu.util.VersionInfo;
|
||||
*
|
||||
* <p>
|
||||
* For information about the collation rule syntax and details about customization, please refer to the <a
|
||||
* href="http://userguide.icu-project.org/collation/customization">Collation customization</a> section of the
|
||||
* User Guide.
|
||||
* href="https://unicode-org.github.io/icu/userguide/collation/customization">Collation customization</a>
|
||||
* section of the User Guide.
|
||||
*
|
||||
* <p>
|
||||
* <strong>Note</strong> that there are some differences between the Collation rule syntax used in Java and ICU4J:
|
||||
@@ -193,7 +193,7 @@ public final class RuleBasedCollator extends Collator {
|
||||
* The collator will be based on the CLDR root collation, with the
|
||||
* attributes and re-ordering of the characters specified in the argument rules.
|
||||
* <p>
|
||||
* See the User Guide's section on <a href="http://userguide.icu-project.org/collation/customization">
|
||||
* See the User Guide's section on <a href="https://unicode-org.github.io/icu/userguide/collation/customization">
|
||||
* Collation Customization</a> for details on the rule syntax.
|
||||
*
|
||||
* @param rules
|
||||
@@ -570,7 +570,7 @@ public final class RuleBasedCollator extends Collator {
|
||||
/**
|
||||
* Sets the mode for the direction of SECONDARY weights to be used in French collation. The default value is false,
|
||||
* which treats SECONDARY weights in the order they appear. If set to true, the SECONDARY weights will be sorted
|
||||
* backwards. See the section on <a href="http://userguide.icu-project.org/collation/architecture">
|
||||
* backwards. See the section on <a href="https://unicode-org.github.io/icu/userguide/collation/architecture">
|
||||
* French collation</a> for more information.
|
||||
*
|
||||
* @param flag
|
||||
@@ -619,7 +619,7 @@ public final class RuleBasedCollator extends Collator {
|
||||
* first mode. A simple way to ignore accent differences in a string is to set the strength to PRIMARY and enable
|
||||
* case level.
|
||||
* <p>
|
||||
* See the section on <a href="http://userguide.icu-project.org/collation/architecture">case
|
||||
* See the section on <a href="https://unicode-org.github.io/icu/userguide/collation/architecture">case
|
||||
* level</a> for more information.
|
||||
*
|
||||
* @param flag
|
||||
@@ -963,7 +963,7 @@ public final class RuleBasedCollator extends Collator {
|
||||
*
|
||||
* <p>The root collation rules are an <i>approximation</i> of the root collator's sort order.
|
||||
* They are almost never used or useful at runtime and can be removed from the data.
|
||||
* See <a href="http://userguide.icu-project.org/collation/customization#TOC-Building-on-Existing-Locales">User Guide:
|
||||
* See <a href="https://unicode-org.github.io/icu/userguide/collation/customization#building-on-existing-locales">User Guide:
|
||||
* Collation Customization, Building on Existing Locales</a>
|
||||
*
|
||||
* <p>{@link #getRules()} should normally be used instead.
|
||||
|
||||
@@ -215,16 +215,10 @@ public class LongNameHandler
|
||||
UnitWidth width,
|
||||
PluralRules rules,
|
||||
MicroPropsGenerator parent) {
|
||||
if (unit.getType() == null || (perUnit != null && perUnit.getType() == null)) {
|
||||
// TODO(ICU-20941): Unsanctioned unit. Not yet fully supported. Set an
|
||||
// error code. Once we support not-built-in units here, unitRef may be
|
||||
// anything, but if not built-in, perUnit has to be "none".
|
||||
throw new UnsupportedOperationException("Unsanctioned units, not yet supported");
|
||||
}
|
||||
if (perUnit != null) {
|
||||
// Compound unit: first try to simplify (e.g., meters per second is its own unit).
|
||||
MeasureUnit simplified = MeasureUnit.resolveUnitPerUnit(unit, perUnit);
|
||||
if (simplified != null) {
|
||||
MeasureUnit simplified = unit.product(perUnit.reciprocal());
|
||||
if (simplified.getType() != null) {
|
||||
unit = simplified;
|
||||
} else {
|
||||
// No simplified form is available.
|
||||
@@ -232,6 +226,12 @@ public class LongNameHandler
|
||||
}
|
||||
}
|
||||
|
||||
if (unit.getType() == null) {
|
||||
// TODO(ICU-20941): Unsanctioned unit. Not yet fully supported.
|
||||
throw new UnsupportedOperationException("Unsanctioned unit, not yet supported: " +
|
||||
unit.getIdentifier());
|
||||
}
|
||||
|
||||
String[] simpleFormats = new String[ARRAY_LENGTH];
|
||||
getMeasureData(locale, unit, width, simpleFormats);
|
||||
// TODO(ICU4J): Reduce the number of object creations here?
|
||||
@@ -249,6 +249,13 @@ public class LongNameHandler
|
||||
UnitWidth width,
|
||||
PluralRules rules,
|
||||
MicroPropsGenerator parent) {
|
||||
if (unit.getType() == null || perUnit.getType() == null) {
|
||||
// TODO(ICU-20941): Unsanctioned unit. Not yet fully supported. Set an
|
||||
// error code.
|
||||
throw new UnsupportedOperationException(
|
||||
"Unsanctioned units, not yet supported: " + unit.getIdentifier() + "/" +
|
||||
perUnit.getIdentifier());
|
||||
}
|
||||
String[] primaryData = new String[ARRAY_LENGTH];
|
||||
getMeasureData(locale, unit, width, primaryData);
|
||||
String[] secondaryData = new String[ARRAY_LENGTH];
|
||||
|
||||
@@ -141,6 +141,8 @@ public class MixedUnitLongNameHandler
|
||||
* unit.
|
||||
*/
|
||||
private Modifier getMixedUnitModifier(DecimalQuantity quantity, MicroProps micros) {
|
||||
// If we don't have at least one mixedMeasure, the LongNameHandler would be
|
||||
// sufficient and we shouldn't be running MixedUnitLongNameHandler code:
|
||||
if (micros.mixedMeasures.size() == 0) {
|
||||
assert false : "Mixed unit: we must have more than one unit value";
|
||||
throw new UnsupportedOperationException();
|
||||
@@ -168,6 +170,11 @@ public class MixedUnitLongNameHandler
|
||||
|
||||
for (int i = 0; i < micros.mixedMeasures.size(); i++) {
|
||||
DecimalQuantity fdec = new DecimalQuantity_DualStorageBCD(micros.mixedMeasures.get(i).getNumber());
|
||||
if (i > 0 && fdec.isNegative()) {
|
||||
// If numbers are negative, only the first number needs to have its
|
||||
// negative sign formatted.
|
||||
fdec.negate();
|
||||
}
|
||||
StandardPlural pluralForm = fdec.getStandardPlural(rules);
|
||||
|
||||
String simpleFormat = LongNameHandler.getWithPlural(this.fMixedUnitData.get(i), pluralForm);
|
||||
@@ -179,6 +186,13 @@ public class MixedUnitLongNameHandler
|
||||
// TODO(icu-units#67): fix field positions
|
||||
}
|
||||
|
||||
// Reiterated: we have at least one mixedMeasure:
|
||||
assert micros.mixedMeasures.size() > 0;
|
||||
// Thus if negative, a negative has already been formatted:
|
||||
if (quantity.isNegative()) {
|
||||
quantity.negate();
|
||||
}
|
||||
|
||||
String[] finalSimpleFormats = this.fMixedUnitData.get(this.fMixedUnitData.size() - 1);
|
||||
StandardPlural finalPlural = RoundingUtils.getPluralSafe(micros.rounder, rules, quantity);
|
||||
String finalSimpleFormat = LongNameHandler.getWithPlural(finalSimpleFormats, finalPlural);
|
||||
|
||||
@@ -105,6 +105,11 @@ public class ComplexUnitsConverter {
|
||||
*/
|
||||
public List<Measure> convert(BigDecimal quantity, Precision rounder) {
|
||||
List<Measure> result = new ArrayList<>(unitConverters_.size());
|
||||
BigDecimal sign = BigDecimal.ONE;
|
||||
if (quantity.compareTo(BigDecimal.ZERO) < 0) {
|
||||
quantity = quantity.abs();
|
||||
sign = sign.negate();
|
||||
}
|
||||
|
||||
// For N converters:
|
||||
// - the first converter converts from the input unit to the largest
|
||||
@@ -179,9 +184,9 @@ public class ComplexUnitsConverter {
|
||||
// Package values into Measure instances in result:
|
||||
for (int i = 0, n = unitConverters_.size(); i < n; ++i) {
|
||||
if (i < n - 1) {
|
||||
result.add(new Measure(intValues.get(i), units_.get(i).build()));
|
||||
result.add(new Measure(intValues.get(i).multiply(sign), units_.get(i).build()));
|
||||
} else {
|
||||
result.add(new Measure(quantity, units_.get(i).build()));
|
||||
result.add(new Measure(quantity.multiply(sign), units_.get(i).build()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -96,8 +96,8 @@ public class ConversionRates {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param singleUnit
|
||||
* @return The bese units in the `SingleUnitImpl` with applying the dimensionality only and not the SI prefix.
|
||||
* @param singleUnit An instance of SingleUnitImpl.
|
||||
* @return The base units in the `SingleUnitImpl` with applying the dimensionality only and not the SI prefix.
|
||||
* <p>
|
||||
* NOTE:
|
||||
* This method is helpful when checking the convertibility because no need to check convertibility.
|
||||
@@ -184,6 +184,7 @@ public class ConversionRates {
|
||||
|
||||
public static class ConversionRateInfo {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private final String simpleUnit;
|
||||
private final String target;
|
||||
private final String conversionRate;
|
||||
|
||||
@@ -51,7 +51,7 @@ public class MeasureUnitImpl {
|
||||
*
|
||||
* @param identifier The unit identifier string.
|
||||
* @return A newly parsed object.
|
||||
* @throws <code>IllegalArgumentException</code> in case of incorrect/non-parsed identifier.
|
||||
* @throws IllegalArgumentException in case of incorrect/non-parsed identifier.
|
||||
*/
|
||||
public static MeasureUnitImpl forIdentifier(String identifier) {
|
||||
return UnitsParser.parseForIdentifier(identifier);
|
||||
@@ -66,11 +66,13 @@ public class MeasureUnitImpl {
|
||||
return result;
|
||||
}
|
||||
|
||||
public MeasureUnitImpl clone() {
|
||||
public MeasureUnitImpl copy() {
|
||||
MeasureUnitImpl result = new MeasureUnitImpl();
|
||||
result.complexity = this.complexity;
|
||||
result.identifier = this.identifier;
|
||||
result.singleUnits = (ArrayList<SingleUnitImpl>) this.singleUnits.clone();
|
||||
for (SingleUnitImpl single : this.singleUnits) {
|
||||
result.singleUnits.add(single.copy());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -103,7 +105,7 @@ public class MeasureUnitImpl {
|
||||
* @return a list of <code>MeasureUnitImpl</code>
|
||||
*/
|
||||
public ArrayList<MeasureUnitImpl> extractIndividualUnits() {
|
||||
ArrayList<MeasureUnitImpl> result = new ArrayList<MeasureUnitImpl>();
|
||||
ArrayList<MeasureUnitImpl> result = new ArrayList<>();
|
||||
if (this.getComplexity() == MeasureUnit.Complexity.MIXED) {
|
||||
// In case of mixed units, each single unit can be considered as a stand alone MeasureUnitImpl.
|
||||
for (SingleUnitImpl singleUnit :
|
||||
@@ -114,7 +116,7 @@ public class MeasureUnitImpl {
|
||||
return result;
|
||||
}
|
||||
|
||||
result.add(this.clone());
|
||||
result.add(this.copy());
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -162,7 +164,7 @@ public class MeasureUnitImpl {
|
||||
}
|
||||
|
||||
// Add a copy of singleUnit
|
||||
this.singleUnits.add(singleUnit.clone());
|
||||
this.singleUnits.add(singleUnit.copy());
|
||||
|
||||
// If the MeasureUnitImpl is `UMEASURE_UNIT_SINGLE` and after the appending a unit, the singleUnits are more
|
||||
// than one singleUnit. thus means the complexity should be `UMEASURE_UNIT_COMPOUND`
|
||||
@@ -191,7 +193,7 @@ public class MeasureUnitImpl {
|
||||
return new SingleUnitImpl();
|
||||
}
|
||||
if (this.singleUnits.size() == 1) {
|
||||
return this.singleUnits.get(0).clone();
|
||||
return this.singleUnits.get(0).copy();
|
||||
}
|
||||
|
||||
throw new UnsupportedOperationException();
|
||||
|
||||
@@ -33,7 +33,7 @@ public class SingleUnitImpl {
|
||||
*/
|
||||
private MeasureUnit.SIPrefix siPrefix = MeasureUnit.SIPrefix.ONE;
|
||||
|
||||
public SingleUnitImpl clone() {
|
||||
public SingleUnitImpl copy() {
|
||||
SingleUnitImpl result = new SingleUnitImpl();
|
||||
result.index = this.index;
|
||||
result.dimensionality = this.dimensionality;
|
||||
@@ -50,8 +50,6 @@ public class SingleUnitImpl {
|
||||
|
||||
/**
|
||||
* Generates an neutral identifier string for a single unit which means we do not include the dimension signal.
|
||||
*
|
||||
* @throws IllegalArgumentException
|
||||
*/
|
||||
public String getNeutralIdentifier() {
|
||||
StringBuilder result = new StringBuilder();
|
||||
@@ -70,6 +68,7 @@ public class SingleUnitImpl {
|
||||
result.append(posPower);
|
||||
result.append('-');
|
||||
} else {
|
||||
// TODO: IllegalArgumentException might not be appropriate here
|
||||
throw new IllegalArgumentException("Unit Identifier Syntax Error");
|
||||
}
|
||||
|
||||
|
||||
@@ -128,7 +128,7 @@ public class UnitConverter {
|
||||
assert (!factor.isEmpty());
|
||||
|
||||
// Remove all spaces in the factor
|
||||
factor.replaceAll("\\s+", "");
|
||||
factor = factor.replaceAll("\\s+", "");
|
||||
|
||||
String[] fractions = factor.split("/");
|
||||
assert (fractions.length == 1 || fractions.length == 2);
|
||||
@@ -153,9 +153,9 @@ public class UnitConverter {
|
||||
}
|
||||
|
||||
/**
|
||||
* Clone this <code>Factor</code>.
|
||||
* Copy this <code>Factor</code>.
|
||||
*/
|
||||
protected Factor clone() {
|
||||
protected Factor copy() {
|
||||
Factor result = new Factor();
|
||||
result.factorNum = this.factorNum;
|
||||
result.factorDen = this.factorDen;
|
||||
@@ -172,11 +172,9 @@ public class UnitConverter {
|
||||
|
||||
/**
|
||||
* Returns a single `BigDecimal` that represent the conversion rate after substituting all the constants.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public BigDecimal getConversionRate() {
|
||||
Factor resultCollector = this.clone();
|
||||
Factor resultCollector = this.copy();
|
||||
|
||||
resultCollector.substitute(new BigDecimal("0.3048"), this.CONSTANT_FT2M);
|
||||
resultCollector.substitute(new BigDecimal("411557987.0").divide(new BigDecimal("131002976.0"), DECIMAL128), this.CONSTANT_PI);
|
||||
@@ -200,7 +198,7 @@ public class UnitConverter {
|
||||
}
|
||||
|
||||
public Factor applySiPrefix(MeasureUnit.SIPrefix siPrefix) {
|
||||
Factor result = this.clone();
|
||||
Factor result = this.copy();
|
||||
if (siPrefix == MeasureUnit.SIPrefix.ONE) {
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ public class UnitsData {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param measureUnit
|
||||
* @param measureUnit An instance of MeasureUnitImpl.
|
||||
* @return the corresponding category.
|
||||
*/
|
||||
public String getCategory(MeasureUnitImpl measureUnit) {
|
||||
@@ -168,7 +168,7 @@ public class UnitsData {
|
||||
|
||||
@Override
|
||||
public void put(UResource.Key key, UResource.Value value, boolean noFallback) {
|
||||
assert (key.toString() == Constants.CATEGORY_TABLE_NAME);
|
||||
assert (key.toString().equals(Constants.CATEGORY_TABLE_NAME));
|
||||
assert (value.getType() == UResourceBundle.TABLE);
|
||||
|
||||
UResource.Table categoryTable = value.getTable();
|
||||
|
||||
@@ -86,7 +86,8 @@ public class UnitsRouter {
|
||||
ConverterPreference converterPreference = null;
|
||||
for (ConverterPreference itr : converterPreferences_) {
|
||||
converterPreference = itr;
|
||||
if (converterPreference.converter.greaterThanOrEqual(quantity, converterPreference.limit)) {
|
||||
if (converterPreference.converter.greaterThanOrEqual(quantity.abs(),
|
||||
converterPreference.limit)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,6 +127,7 @@ public class FormattedNumber implements FormattedValue {
|
||||
*
|
||||
* @return `MeasureUnit`.
|
||||
* @draft ICU 68
|
||||
* @provisional This API might change or be removed in a future release.
|
||||
*/
|
||||
public MeasureUnit getOutputUnit() {
|
||||
return this.outputUnit;
|
||||
|
||||
@@ -225,7 +225,7 @@ public abstract class NumberFormatterSettings<T extends NumberFormatterSettings<
|
||||
*
|
||||
* The default is HALF_EVEN. For more information on rounding mode, see the ICU userguide here:
|
||||
*
|
||||
* http://userguide.icu-project.org/formatparse/numbers/rounding-modes
|
||||
* https://unicode-org.github.io/icu/userguide/format_parse/numbers/rounding-modes
|
||||
*
|
||||
* @param roundingMode
|
||||
* The rounding mode to use.
|
||||
|
||||
@@ -12,6 +12,8 @@ import com.ibm.icu.impl.SoftCache;
|
||||
import com.ibm.icu.impl.StringSegment;
|
||||
import com.ibm.icu.impl.number.MacroProps;
|
||||
import com.ibm.icu.impl.number.RoundingUtils;
|
||||
import com.ibm.icu.impl.units.MeasureUnitImpl;
|
||||
import com.ibm.icu.impl.units.SingleUnitImpl;
|
||||
import com.ibm.icu.number.NumberFormatter.DecimalSeparatorDisplay;
|
||||
import com.ibm.icu.number.NumberFormatter.GroupingStrategy;
|
||||
import com.ibm.icu.number.NumberFormatter.SignDisplay;
|
||||
@@ -904,9 +906,6 @@ class NumberSkeletonImpl {
|
||||
if (macros.unit != null && GeneratorHelpers.unit(macros, sb)) {
|
||||
sb.append(' ');
|
||||
}
|
||||
if (macros.perUnit != null && GeneratorHelpers.perUnit(macros, sb)) {
|
||||
sb.append(' ');
|
||||
}
|
||||
if (macros.usage != null && GeneratorHelpers.usage(macros, sb)) {
|
||||
sb.append(' ');
|
||||
}
|
||||
@@ -1026,6 +1025,7 @@ class NumberSkeletonImpl {
|
||||
sb.append(currency.getCurrencyCode());
|
||||
}
|
||||
|
||||
// "measure-unit/" is deprecated in favour of "unit/".
|
||||
private static void parseMeasureUnitOption(StringSegment segment, MacroProps macros) {
|
||||
// NOTE: The category (type) of the unit is guaranteed to be a valid subtag (alphanumeric)
|
||||
// http://unicode.org/reports/tr35/#Validity_Data
|
||||
@@ -1048,12 +1048,7 @@ class NumberSkeletonImpl {
|
||||
throw new SkeletonSyntaxException("Unknown measure unit", segment);
|
||||
}
|
||||
|
||||
private static void generateMeasureUnitOption(MeasureUnit unit, StringBuilder sb) {
|
||||
sb.append(unit.getType());
|
||||
sb.append("-");
|
||||
sb.append(unit.getSubtype());
|
||||
}
|
||||
|
||||
// "per-measure-unit/" is deprecated in favour of "unit/".
|
||||
private static void parseMeasurePerUnitOption(StringSegment segment, MacroProps macros) {
|
||||
// A little bit of a hack: save the current unit (numerator), call the main measure unit
|
||||
// parsing code, put back the numerator unit, and put the new unit into per-unit.
|
||||
@@ -1068,13 +1063,44 @@ class NumberSkeletonImpl {
|
||||
* specified via a "unit/" concise skeleton.
|
||||
*/
|
||||
private static void parseIdentifierUnitOption(StringSegment segment, MacroProps macros) {
|
||||
MeasureUnit[] units = MeasureUnit.parseCoreUnitIdentifier(segment.asString());
|
||||
if (units == null) {
|
||||
throw new SkeletonSyntaxException("Invalid core unit identifier", segment);
|
||||
MeasureUnitImpl fullUnit;
|
||||
try {
|
||||
fullUnit = MeasureUnitImpl.forIdentifier(segment.asString());
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new SkeletonSyntaxException("Invalid unit stem", segment);
|
||||
}
|
||||
macros.unit = units[0];
|
||||
if (units.length == 2) {
|
||||
macros.perUnit = units[1];
|
||||
|
||||
// Mixed units can only be represented by full MeasureUnit instances, so we
|
||||
// don't split the denominator into macros.perUnit.
|
||||
if (fullUnit.getComplexity() == MeasureUnit.Complexity.MIXED) {
|
||||
macros.unit = fullUnit.build();
|
||||
return;
|
||||
}
|
||||
|
||||
// When we have a built-in unit (e.g. meter-per-second), we don't split it up
|
||||
MeasureUnit testBuiltin = fullUnit.build();
|
||||
if (testBuiltin.getType() != null) {
|
||||
macros.unit = testBuiltin;
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO(ICU-20941): Clean this up.
|
||||
for (SingleUnitImpl subUnit : fullUnit.getSingleUnits()) {
|
||||
if (subUnit.getDimensionality() > 0) {
|
||||
if (macros.unit == null) {
|
||||
macros.unit = subUnit.build();
|
||||
} else {
|
||||
macros.unit = macros.unit.product(subUnit.build());
|
||||
}
|
||||
} else {
|
||||
// It's okay to mutate fullUnit, we're throwing it away after this:
|
||||
subUnit.setDimensionality(subUnit.getDimensionality() * -1);
|
||||
if (macros.perUnit == null) {
|
||||
macros.perUnit = subUnit.build();
|
||||
} else {
|
||||
macros.perUnit = macros.perUnit.product(subUnit.build());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1468,24 +1494,17 @@ class NumberSkeletonImpl {
|
||||
} else if (macros.unit == MeasureUnit.PERMILLE) {
|
||||
sb.append("permille");
|
||||
return true;
|
||||
} else if (macros.unit.getType() != null) {
|
||||
sb.append("measure-unit/");
|
||||
BlueprintHelpers.generateMeasureUnitOption(macros.unit, sb);
|
||||
return true;
|
||||
} else {
|
||||
// TODO(icu-units#35): add support for not-built-in units.
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean perUnit(MacroProps macros, StringBuilder sb) {
|
||||
// Per-units are currently expected to be only MeasureUnits.
|
||||
if (macros.perUnit instanceof Currency) {
|
||||
throw new UnsupportedOperationException(
|
||||
"Cannot generate number skeleton with per-unit that is not a standard measure unit");
|
||||
} else {
|
||||
sb.append("per-measure-unit/");
|
||||
BlueprintHelpers.generateMeasureUnitOption(macros.perUnit, sb);
|
||||
MeasureUnit unit = macros.unit;
|
||||
if (macros.perUnit != null) {
|
||||
if (macros.perUnit instanceof Currency) {
|
||||
throw new UnsupportedOperationException(
|
||||
"Cannot generate number skeleton with per-unit that is not a standard measure unit");
|
||||
}
|
||||
unit = unit.product(macros.perUnit.reciprocal());
|
||||
}
|
||||
sb.append("unit/");
|
||||
sb.append(unit.getIdentifier());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -538,29 +538,34 @@ public abstract class DateFormat extends UFormat {
|
||||
/**
|
||||
* Hour Cycle
|
||||
* @draft ICU 67
|
||||
* @provisional This API might change or be removed in a future release.
|
||||
*/
|
||||
public enum HourCycle {
|
||||
/**
|
||||
* hour in am/pm (0~11)
|
||||
* @draft ICU 67
|
||||
* @provisional This API might change or be removed in a future release.
|
||||
*/
|
||||
HOUR_CYCLE_11,
|
||||
|
||||
/**
|
||||
* hour in am/pm (1~12)
|
||||
* @draft ICU 67
|
||||
* @provisional This API might change or be removed in a future release.
|
||||
*/
|
||||
HOUR_CYCLE_12,
|
||||
|
||||
/**
|
||||
* hour in day (0~23)
|
||||
* @draft ICU 67
|
||||
* @provisional This API might change or be removed in a future release.
|
||||
*/
|
||||
HOUR_CYCLE_23,
|
||||
|
||||
/**
|
||||
* hour in day (1~24)
|
||||
* @draft ICU 67
|
||||
* @provisional This API might change or be removed in a future release.
|
||||
*/
|
||||
HOUR_CYCLE_24;
|
||||
};
|
||||
@@ -2354,7 +2359,7 @@ public abstract class DateFormat extends UFormat {
|
||||
GregorianCalendar cal = new GregorianCalendar();
|
||||
CAL_FIELD_COUNT = cal.getFieldCount();
|
||||
CAL_FIELDS = new Field[CAL_FIELD_COUNT];
|
||||
FIELD_NAME_MAP = new HashMap<String, Field>(CAL_FIELD_COUNT);
|
||||
FIELD_NAME_MAP = new HashMap<>(CAL_FIELD_COUNT);
|
||||
}
|
||||
|
||||
// Java fields -------------------
|
||||
|
||||
@@ -1358,6 +1358,7 @@ public class DateTimePatternGenerator implements Freezable<DateTimePatternGenera
|
||||
/**
|
||||
* Return the default hour cycle.
|
||||
* @draft ICU 67
|
||||
* @provisional This API might change or be removed in a future release.
|
||||
*/
|
||||
public DateFormat.HourCycle getDefaultHourCycle() {
|
||||
switch(getDefaultHourFormatChar()) {
|
||||
|
||||
@@ -131,8 +131,8 @@ import com.ibm.icu.util.ULocale.Category;
|
||||
* <p>It is also possible to specify the <em>rounding mode</em> to use. The default rounding mode is
|
||||
* "half even", which rounds numbers to their closest increment, with ties broken in favor of
|
||||
* trailing numbers being even. For more information, see {@link #setRoundingMode} and <a
|
||||
* href="http://userguide.icu-project.org/formatparse/numbers/rounding-modes">the ICU User
|
||||
* Guide</a>.
|
||||
* href="https://unicode-org.github.io/icu/userguide/format_parse/numbers/rounding-modes">the ICU
|
||||
* User Guide</a>.
|
||||
*
|
||||
* <h3>Pattern Strings</h3>
|
||||
*
|
||||
@@ -1272,8 +1272,8 @@ public class DecimalFormat extends NumberFormat {
|
||||
* number, and rounds to the closest even number if at the midpoint.
|
||||
*
|
||||
* <p>For more detail on rounding modes, see <a
|
||||
* href="http://userguide.icu-project.org/formatparse/numbers/rounding-modes">the ICU User
|
||||
* Guide</a>.
|
||||
* href="https://unicode-org.github.io/icu/userguide/format_parse/numbers/rounding-modes">the ICU
|
||||
* User Guide</a>.
|
||||
*
|
||||
* <p>For backwards compatibility, the rounding mode is specified as an int argument, which can be
|
||||
* from either the constants in {@link BigDecimal} or the ordinal value of {@link RoundingMode}.
|
||||
|
||||
@@ -280,7 +280,7 @@ import com.ibm.icu.util.ULocale.Category;
|
||||
* or preformatted values, but not pattern strings or custom format objects.</p>
|
||||
*
|
||||
* <p>For more details, see the
|
||||
* <a href="http://userguide.icu-project.org/formatparse/messages">ICU User Guide</a>.</p>
|
||||
* <a href="https://unicode-org.github.io/icu/userguide/format_parse/messages">ICU User Guide</a>.</p>
|
||||
*
|
||||
* <h4>Usage Information</h4>
|
||||
*
|
||||
|
||||
@@ -62,7 +62,7 @@ import com.ibm.icu.util.ULocale.Category;
|
||||
* <p>
|
||||
* This class should not be subclassed.</p>
|
||||
* <p>
|
||||
* HebrewCalendar usually should be instantiated using
|
||||
* HebrewCalendar usually should be instantiated using
|
||||
* {@link com.ibm.icu.util.Calendar#getInstance(ULocale)} passing in a <code>ULocale</code>
|
||||
* with the tag <code>"@calendar=hebrew"</code>.</p>
|
||||
*
|
||||
@@ -82,33 +82,33 @@ public class HebrewCalendar extends Calendar {
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
|
||||
/**
|
||||
* Constant for Tishri, the 1st month of the Hebrew year.
|
||||
* @stable ICU 2.8
|
||||
/**
|
||||
* Constant for Tishri, the 1st month of the Hebrew year.
|
||||
* @stable ICU 2.8
|
||||
*/
|
||||
public static final int TISHRI = 0;
|
||||
|
||||
/**
|
||||
* Constant for Heshvan, the 2nd month of the Hebrew year.
|
||||
* @stable ICU 2.8
|
||||
* Constant for Heshvan, the 2nd month of the Hebrew year.
|
||||
* @stable ICU 2.8
|
||||
*/
|
||||
public static final int HESHVAN = 1;
|
||||
|
||||
/**
|
||||
* Constant for Kislev, the 3rd month of the Hebrew year.
|
||||
* @stable ICU 2.8
|
||||
* Constant for Kislev, the 3rd month of the Hebrew year.
|
||||
* @stable ICU 2.8
|
||||
*/
|
||||
public static final int KISLEV = 2;
|
||||
|
||||
/**
|
||||
* Constant for Tevet, the 4th month of the Hebrew year.
|
||||
* @stable ICU 2.8
|
||||
* Constant for Tevet, the 4th month of the Hebrew year.
|
||||
* @stable ICU 2.8
|
||||
*/
|
||||
public static final int TEVET = 3;
|
||||
|
||||
/**
|
||||
* Constant for Shevat, the 5th month of the Hebrew year.
|
||||
* @stable ICU 2.8
|
||||
* Constant for Shevat, the 5th month of the Hebrew year.
|
||||
* @stable ICU 2.8
|
||||
*/
|
||||
public static final int SHEVAT = 4;
|
||||
|
||||
@@ -120,45 +120,45 @@ public class HebrewCalendar extends Calendar {
|
||||
*/
|
||||
public static final int ADAR_1 = 5;
|
||||
|
||||
/**
|
||||
* Constant for the Adar, the 7th month of the Hebrew year.
|
||||
* @stable ICU 2.8
|
||||
/**
|
||||
* Constant for the Adar, the 7th month of the Hebrew year.
|
||||
* @stable ICU 2.8
|
||||
*/
|
||||
public static final int ADAR = 6;
|
||||
|
||||
/**
|
||||
* Constant for Nisan, the 8th month of the Hebrew year.
|
||||
* @stable ICU 2.8
|
||||
* Constant for Nisan, the 8th month of the Hebrew year.
|
||||
* @stable ICU 2.8
|
||||
*/
|
||||
public static final int NISAN = 7;
|
||||
|
||||
/**
|
||||
* Constant for Iyar, the 9th month of the Hebrew year.
|
||||
* @stable ICU 2.8
|
||||
* Constant for Iyar, the 9th month of the Hebrew year.
|
||||
* @stable ICU 2.8
|
||||
*/
|
||||
public static final int IYAR = 8;
|
||||
|
||||
/**
|
||||
* Constant for Sivan, the 10th month of the Hebrew year.
|
||||
* @stable ICU 2.8
|
||||
* Constant for Sivan, the 10th month of the Hebrew year.
|
||||
* @stable ICU 2.8
|
||||
*/
|
||||
public static final int SIVAN = 9;
|
||||
|
||||
/**
|
||||
* Constant for Tammuz, the 11th month of the Hebrew year.
|
||||
* @stable ICU 2.8
|
||||
* Constant for Tammuz, the 11th month of the Hebrew year.
|
||||
* @stable ICU 2.8
|
||||
*/
|
||||
public static final int TAMUZ = 10;
|
||||
|
||||
/**
|
||||
* Constant for Av, the 12th month of the Hebrew year.
|
||||
* @stable ICU 2.8
|
||||
* Constant for Av, the 12th month of the Hebrew year.
|
||||
* @stable ICU 2.8
|
||||
*/
|
||||
public static final int AV = 11;
|
||||
|
||||
/**
|
||||
* Constant for Elul, the 13th month of the Hebrew year.
|
||||
* @stable ICU 2.8
|
||||
* Constant for Elul, the 13th month of the Hebrew year.
|
||||
* @stable ICU 2.8
|
||||
*/
|
||||
public static final int ELUL = 12;
|
||||
|
||||
@@ -270,7 +270,7 @@ public class HebrewCalendar extends Calendar {
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
private static CalendarCache cache = new CalendarCache();
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Constructors...
|
||||
//-------------------------------------------------------------------------
|
||||
@@ -421,7 +421,7 @@ public class HebrewCalendar extends Calendar {
|
||||
/**
|
||||
* Add a signed amount to a specified field, using this calendar's rules.
|
||||
* For example, to add three days to the current date, you can call
|
||||
* <code>add(Calendar.DATE, 3)</code>.
|
||||
* <code>add(Calendar.DATE, 3)</code>.
|
||||
* <p>
|
||||
* When adding to certain fields, the values of other fields may conflict and
|
||||
* need to be changed. For example, when adding one to the {@link #MONTH MONTH} field
|
||||
@@ -445,10 +445,11 @@ public class HebrewCalendar extends Calendar {
|
||||
* to a field that cannot be handled by this method.
|
||||
* @stable ICU 2.8
|
||||
*/
|
||||
@Override
|
||||
public void add(int field, int amount)
|
||||
{
|
||||
switch (field) {
|
||||
case MONTH:
|
||||
case MONTH:
|
||||
{
|
||||
// We can't just do a set(MONTH, get(MONTH) + amount). The
|
||||
// reason is ADAR_1. Suppose amount is +2 and we land in
|
||||
@@ -492,7 +493,7 @@ public class HebrewCalendar extends Calendar {
|
||||
pinField(DAY_OF_MONTH);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
default:
|
||||
super.add(field, amount);
|
||||
break;
|
||||
@@ -504,7 +505,7 @@ public class HebrewCalendar extends Calendar {
|
||||
* example, to roll the current date up by three days, you can call
|
||||
* <code>roll(Calendar.DATE, 3)</code>. If the
|
||||
* field is rolled past its maximum allowable value, it will "wrap" back
|
||||
* to its minimum and continue rolling.
|
||||
* to its minimum and continue rolling.
|
||||
* For example, calling <code>roll(Calendar.DATE, 10)</code>
|
||||
* on a Hebrew calendar set to "25 Av 5758" will result in the date "5 Av 5758".
|
||||
* <p>
|
||||
@@ -531,6 +532,7 @@ public class HebrewCalendar extends Calendar {
|
||||
* to a field that cannot be handled by this method.
|
||||
* @stable ICU 2.8
|
||||
*/
|
||||
@Override
|
||||
public void roll(int field, int amount)
|
||||
{
|
||||
switch (field) {
|
||||
@@ -538,7 +540,7 @@ public class HebrewCalendar extends Calendar {
|
||||
{
|
||||
int month = get(MONTH);
|
||||
int year = get(YEAR);
|
||||
|
||||
|
||||
boolean leapYear = isLeapYear(year);
|
||||
int yearLength = monthsInYear(year);
|
||||
int newMonth = month + (amount % yearLength);
|
||||
@@ -570,14 +572,14 @@ public class HebrewCalendar extends Calendar {
|
||||
// "parts" (or halakim), which are 1/1080 of an hour, or 3 1/3 seconds.
|
||||
private static final long HOUR_PARTS = 1080;
|
||||
private static final long DAY_PARTS = 24*HOUR_PARTS;
|
||||
|
||||
|
||||
// An approximate value for the length of a lunar month.
|
||||
// It is used to calculate the approximate year and month of a given
|
||||
// absolute date.
|
||||
static private final int MONTH_DAYS = 29;
|
||||
static private final long MONTH_FRACT = 12*HOUR_PARTS + 793;
|
||||
static private final long MONTH_PARTS = MONTH_DAYS*DAY_PARTS + MONTH_FRACT;
|
||||
|
||||
|
||||
// The time of the new moon (in parts) on 1 Tishri, year 1 (the epoch)
|
||||
// counting from noon on the day before. BAHARAD is an abbreviation of
|
||||
// Bet (Monday), Hey (5 hours from sunset), Resh-Daled (204).
|
||||
@@ -606,10 +608,10 @@ public class HebrewCalendar extends Calendar {
|
||||
private static long startOfYear(int year)
|
||||
{
|
||||
long day = cache.get(year);
|
||||
|
||||
|
||||
if (day == CalendarCache.EMPTY) {
|
||||
// # of months before year
|
||||
int months = (int)floorDivide((235 * (long)year - 234), (long)19);
|
||||
int months = (int)floorDivide((235 * (long)year - 234), 19);
|
||||
|
||||
long frac = months * MONTH_FRACT + BAHARAD; // Fractional part of day #
|
||||
day = months * 29 + (frac / DAY_PARTS); // Whole # part of calculation
|
||||
@@ -707,6 +709,7 @@ public class HebrewCalendar extends Calendar {
|
||||
/**
|
||||
* @stable ICU 2.8
|
||||
*/
|
||||
@Override
|
||||
protected int handleGetLimit(int field, int limitType) {
|
||||
return LIMITS[field][limitType];
|
||||
}
|
||||
@@ -715,6 +718,7 @@ public class HebrewCalendar extends Calendar {
|
||||
* Returns the length of the given month in the given year
|
||||
* @stable ICU 2.8
|
||||
*/
|
||||
@Override
|
||||
protected int handleGetMonthLength(int extendedYear, int month) {
|
||||
// Resolve out-of-range months. This is necessary in order to
|
||||
// obtain the correct year. We correct to
|
||||
@@ -735,7 +739,7 @@ public class HebrewCalendar extends Calendar {
|
||||
case KISLEV:
|
||||
// These two month lengths can vary
|
||||
return MONTH_LENGTH[month][yearType(extendedYear)];
|
||||
|
||||
|
||||
default:
|
||||
// The rest are a fixed length
|
||||
return MONTH_LENGTH[month][0];
|
||||
@@ -746,6 +750,7 @@ public class HebrewCalendar extends Calendar {
|
||||
* Returns the number of days in the given Hebrew year
|
||||
* @stable ICU 2.8
|
||||
*/
|
||||
@Override
|
||||
protected int handleGetYearLength(int eyear) {
|
||||
return (int)(startOfYear(eyear+1) - startOfYear(eyear));
|
||||
}
|
||||
@@ -758,6 +763,7 @@ public class HebrewCalendar extends Calendar {
|
||||
* @internal
|
||||
* @deprecated This API is ICU internal only.
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
protected void validateField(int field) {
|
||||
if (field == MONTH && !isLeapYear(handleGetExtendedYear()) && internalGet(MONTH) == ADAR_1) {
|
||||
@@ -781,7 +787,7 @@ public class HebrewCalendar extends Calendar {
|
||||
* <li>DAY_OF_MONTH
|
||||
* <li>DAY_OF_YEAR
|
||||
* <li>EXTENDED_YEAR</ul>
|
||||
*
|
||||
*
|
||||
* Subclasses can refer to the DAY_OF_WEEK and DOW_LOCAL fields,
|
||||
* which will be set when this method is called. Subclasses can
|
||||
* also call the getGregorianXxx() methods to obtain Gregorian
|
||||
@@ -792,10 +798,11 @@ public class HebrewCalendar extends Calendar {
|
||||
* getFieldCount() - 1.
|
||||
* @stable ICU 2.8
|
||||
*/
|
||||
@Override
|
||||
protected void handleComputeFields(int julianDay) {
|
||||
long d = julianDay - 347997;
|
||||
long m = floorDivide((d * (long)DAY_PARTS), (long)MONTH_PARTS); // Months (approx)
|
||||
int year = (int)(floorDivide((19 * m + 234), (long)235) + 1); // Years (approx)
|
||||
long m = floorDivide((d * DAY_PARTS), MONTH_PARTS); // Months (approx)
|
||||
int year = (int)(floorDivide((19 * m + 234), 235) + 1); // Years (approx)
|
||||
long ys = startOfYear(year); // 1st day of year
|
||||
int dayOfYear = (int)(d - ys);
|
||||
|
||||
@@ -822,7 +829,7 @@ public class HebrewCalendar extends Calendar {
|
||||
internalSet(EXTENDED_YEAR, year);
|
||||
internalSet(MONTH, month);
|
||||
internalSet(DAY_OF_MONTH, dayOfMonth);
|
||||
internalSet(DAY_OF_YEAR, dayOfYear);
|
||||
internalSet(DAY_OF_YEAR, dayOfYear);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
@@ -832,6 +839,7 @@ public class HebrewCalendar extends Calendar {
|
||||
/**
|
||||
* @stable ICU 2.8
|
||||
*/
|
||||
@Override
|
||||
protected int handleGetExtendedYear() {
|
||||
int year;
|
||||
if (newerField(EXTENDED_YEAR, YEAR) == EXTENDED_YEAR) {
|
||||
@@ -846,6 +854,7 @@ public class HebrewCalendar extends Calendar {
|
||||
* Return JD of start of given month/year.
|
||||
* @stable ICU 2.8
|
||||
*/
|
||||
@Override
|
||||
protected int handleComputeMonthStart(int eyear, int month, boolean useMonth) {
|
||||
|
||||
// Resolve out-of-range months. This is necessary in order to
|
||||
@@ -879,6 +888,7 @@ public class HebrewCalendar extends Calendar {
|
||||
* {@inheritDoc}
|
||||
* @stable ICU 3.8
|
||||
*/
|
||||
@Override
|
||||
public String getType() {
|
||||
return "hebrew";
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@ import java.util.Set;
|
||||
import com.ibm.icu.impl.CollectionSet;
|
||||
import com.ibm.icu.impl.ICUData;
|
||||
import com.ibm.icu.impl.ICUResourceBundle;
|
||||
import com.ibm.icu.impl.Pair;
|
||||
import com.ibm.icu.impl.UResource;
|
||||
import com.ibm.icu.impl.units.MeasureUnitImpl;
|
||||
import com.ibm.icu.impl.units.SingleUnitImpl;
|
||||
@@ -358,7 +357,6 @@ public class MeasureUnit implements Serializable {
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @param measureUnitImpl
|
||||
* @deprecated Internal API for ICU use only.
|
||||
*/
|
||||
@Deprecated
|
||||
@@ -376,13 +374,13 @@ public class MeasureUnit implements Serializable {
|
||||
private MeasureUnit(MeasureUnitImpl measureUnitImpl) {
|
||||
type = null;
|
||||
subType = null;
|
||||
this.measureUnitImpl = measureUnitImpl.clone();
|
||||
this.measureUnitImpl = measureUnitImpl.copy();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get the type, such as "length"
|
||||
* Get the type, such as "length". May return null.
|
||||
*
|
||||
* @stable ICU 53
|
||||
*/
|
||||
@@ -392,7 +390,7 @@ public class MeasureUnit implements Serializable {
|
||||
|
||||
|
||||
/**
|
||||
* Get the subType, such as “foot”.
|
||||
* Get the subType, such as “foot”. May return null.
|
||||
*
|
||||
* @stable ICU 53
|
||||
*/
|
||||
@@ -703,47 +701,6 @@ public class MeasureUnit implements Serializable {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* For ICU use only.
|
||||
* @internal
|
||||
* @deprecated This API is ICU internal only.
|
||||
*/
|
||||
@Deprecated
|
||||
public static MeasureUnit[] parseCoreUnitIdentifier(String coreUnitIdentifier) {
|
||||
// First search for the whole code unit identifier as a subType
|
||||
MeasureUnit whole = findBySubType(coreUnitIdentifier);
|
||||
if (whole != null) {
|
||||
return new MeasureUnit[] { whole }; // found a numerator but not denominator
|
||||
}
|
||||
|
||||
// If not found, try breaking apart numerator and denominator
|
||||
int perIdx = coreUnitIdentifier.indexOf("-per-");
|
||||
if (perIdx == -1) {
|
||||
// String does not contain "-per-"
|
||||
return null;
|
||||
}
|
||||
String numeratorStr = coreUnitIdentifier.substring(0, perIdx);
|
||||
String denominatorStr = coreUnitIdentifier.substring(perIdx + 5);
|
||||
MeasureUnit numerator = findBySubType(numeratorStr);
|
||||
MeasureUnit denominator = findBySubType(denominatorStr);
|
||||
if (numerator != null && denominator != null) {
|
||||
return new MeasureUnit[] { numerator, denominator }; // found both a numerator and denominator
|
||||
}
|
||||
|
||||
// The numerator or denominator were invalid
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* For ICU use only.
|
||||
* @internal
|
||||
* @deprecated This API is ICU internal only.
|
||||
*/
|
||||
@Deprecated
|
||||
public static MeasureUnit resolveUnitPerUnit(MeasureUnit unit, MeasureUnit perUnit) {
|
||||
return unitPerUnitToSingleUnit.get(Pair.of(unit, perUnit));
|
||||
}
|
||||
|
||||
static final UnicodeSet ASCII = new UnicodeSet('a', 'z').freeze();
|
||||
static final UnicodeSet ASCII_HYPHEN_DIGITS = new UnicodeSet('-', '-', '0', '9', 'a', 'z').freeze();
|
||||
|
||||
@@ -2011,23 +1968,7 @@ public class MeasureUnit implements Serializable {
|
||||
*/
|
||||
public static final MeasureUnit TEASPOON = MeasureUnit.internalGetInstance("volume", "teaspoon");
|
||||
|
||||
private static HashMap<Pair<MeasureUnit, MeasureUnit>, MeasureUnit>unitPerUnitToSingleUnit =
|
||||
new HashMap<>();
|
||||
|
||||
static {
|
||||
unitPerUnitToSingleUnit.put(Pair.<MeasureUnit, MeasureUnit>of(MeasureUnit.LITER, MeasureUnit.KILOMETER), MeasureUnit.LITER_PER_KILOMETER);
|
||||
unitPerUnitToSingleUnit.put(Pair.<MeasureUnit, MeasureUnit>of(MeasureUnit.POUND, MeasureUnit.SQUARE_INCH), MeasureUnit.POUND_PER_SQUARE_INCH);
|
||||
unitPerUnitToSingleUnit.put(Pair.<MeasureUnit, MeasureUnit>of(MeasureUnit.PIXEL, MeasureUnit.CENTIMETER), MeasureUnit.PIXEL_PER_CENTIMETER);
|
||||
unitPerUnitToSingleUnit.put(Pair.<MeasureUnit, MeasureUnit>of(MeasureUnit.DOT, MeasureUnit.CENTIMETER), MeasureUnit.DOT_PER_CENTIMETER);
|
||||
unitPerUnitToSingleUnit.put(Pair.<MeasureUnit, MeasureUnit>of(MeasureUnit.MILE, MeasureUnit.HOUR), MeasureUnit.MILE_PER_HOUR);
|
||||
unitPerUnitToSingleUnit.put(Pair.<MeasureUnit, MeasureUnit>of(MeasureUnit.MILLIGRAM, MeasureUnit.DECILITER), MeasureUnit.MILLIGRAM_PER_DECILITER);
|
||||
unitPerUnitToSingleUnit.put(Pair.<MeasureUnit, MeasureUnit>of(MeasureUnit.MILE, MeasureUnit.GALLON_IMPERIAL), MeasureUnit.MILE_PER_GALLON_IMPERIAL);
|
||||
unitPerUnitToSingleUnit.put(Pair.<MeasureUnit, MeasureUnit>of(MeasureUnit.KILOMETER, MeasureUnit.HOUR), MeasureUnit.KILOMETER_PER_HOUR);
|
||||
unitPerUnitToSingleUnit.put(Pair.<MeasureUnit, MeasureUnit>of(MeasureUnit.MILE, MeasureUnit.GALLON), MeasureUnit.MILE_PER_GALLON);
|
||||
unitPerUnitToSingleUnit.put(Pair.<MeasureUnit, MeasureUnit>of(MeasureUnit.PIXEL, MeasureUnit.INCH), MeasureUnit.PIXEL_PER_INCH);
|
||||
unitPerUnitToSingleUnit.put(Pair.<MeasureUnit, MeasureUnit>of(MeasureUnit.DOT, MeasureUnit.INCH), MeasureUnit.DOT_PER_INCH);
|
||||
unitPerUnitToSingleUnit.put(Pair.<MeasureUnit, MeasureUnit>of(MeasureUnit.METER, MeasureUnit.SECOND), MeasureUnit.METER_PER_SECOND);
|
||||
}
|
||||
// unitPerUnitToSingleUnit no longer in use! TODO: remove from code-generation code.
|
||||
|
||||
// End generated MeasureUnit constants
|
||||
/* Private */
|
||||
@@ -2056,7 +1997,7 @@ public class MeasureUnit implements Serializable {
|
||||
private MeasureUnitImpl getCopyOfMeasureUnitImpl() {
|
||||
return this.measureUnitImpl == null ?
|
||||
MeasureUnitImpl.forIdentifier(getIdentifier()) :
|
||||
this.measureUnitImpl.clone();
|
||||
this.measureUnitImpl.copy();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1205,7 +1205,7 @@ abstract public class TimeZone implements Serializable, Cloneable, Freezable<Tim
|
||||
*
|
||||
* <p>This implementation utilizes <a href="http://unicode.org/cldr/charts/supplemental/zone_tzid.html">
|
||||
* Zone-Tzid mapping data</a>. The mapping data is updated time to time. To get the latest changes,
|
||||
* please read the ICU user guide section <a href="http://userguide.icu-project.org/datetime/timezone#TOC-Updating-the-Time-Zone-Data">
|
||||
* please read the ICU user guide section <a href="https://unicode-org.github.io/icu/userguide/datetime/timezone#updating-the-time-zone-data">
|
||||
* Updating the Time Zone Data</a>.
|
||||
*
|
||||
* @param id A system time zone ID
|
||||
@@ -1265,7 +1265,7 @@ abstract public class TimeZone implements Serializable, Cloneable, Freezable<Tim
|
||||
*
|
||||
* <p>This implementation utilizes <a href="http://unicode.org/cldr/charts/supplemental/zone_tzid.html">
|
||||
* Zone-Tzid mapping data</a>. The mapping data is updated time to time. To get the latest changes,
|
||||
* please read the ICU user guide section <a href="http://userguide.icu-project.org/datetime/timezone#TOC-Updating-the-Time-Zone-Data">
|
||||
* please read the ICU user guide section <a href="https://unicode-org.github.io/icu/userguide/datetime/timezone#updating-the-time-zone-data">
|
||||
* Updating the Time Zone Data</a>.
|
||||
*
|
||||
* @param winid A Windows time zone ID
|
||||
|
||||
@@ -502,6 +502,7 @@ public final class ULocale implements Serializable, Comparable<ULocale> {
|
||||
* @param locale the ULocale to canonicalize
|
||||
* @return the ULocale created from the canonical version of the ULocale.
|
||||
* @draft ICU 67
|
||||
* @provisional This API might change or be removed in a future release.
|
||||
*/
|
||||
public static ULocale createCanonical(ULocale locale) {
|
||||
return createCanonical(locale.getName());
|
||||
@@ -1544,7 +1545,7 @@ public final class ULocale implements Serializable, Comparable<ULocale> {
|
||||
} else {
|
||||
replacedRegion = replacement.get(0);
|
||||
}
|
||||
assert this.region != replacedRegion;
|
||||
assert !this.region.equals(replacedRegion);
|
||||
this.region = replacedRegion;
|
||||
// The region is changed by data in territory alias.
|
||||
return true;
|
||||
@@ -1557,7 +1558,7 @@ public final class ULocale implements Serializable, Comparable<ULocale> {
|
||||
// Found no replacement data for this script.
|
||||
return false;
|
||||
}
|
||||
assert this.script != replacement;
|
||||
assert !this.script.equals(replacement);
|
||||
this.script = replacement;
|
||||
// The script is changed by data in script alias.
|
||||
return true;
|
||||
@@ -1628,7 +1629,6 @@ public final class ULocale implements Serializable, Comparable<ULocale> {
|
||||
}
|
||||
}
|
||||
|
||||
boolean knownCanonicalized = false;
|
||||
String name = parser.getName();
|
||||
if (!isKnownCanonicalizedLocale(name)) {
|
||||
AliasReplacer replacer = new AliasReplacer(
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<p>This package includes Java Locale Service Provider implementation.
|
||||
There are no public ICU4J consumer APIs provided in this package.
|
||||
See the ICU user guide section
|
||||
<a href="http://userguide.icu-project.org/icu4j-locale-service-provider">ICU4J Locale Service Provider</a>
|
||||
<a href="https://unicode-org.github.io/icu/userguide/icu4j-locale-service-provider">ICU4J Locale Service Provider</a>
|
||||
for the details.
|
||||
</p>
|
||||
</body>
|
||||
|
||||
@@ -234,10 +234,10 @@ public class JapaneseTest extends CalendarTestFmwk {
|
||||
|
||||
@Test
|
||||
public void TestForceGannenNumbering() {
|
||||
final String jCalShortPattern = "y/M/d"; // Note: just 'y' doesn't work here.
|
||||
final String jCalGannenDate = "1/5/9"; // A date in the above format after the accession date for Heisei [1989-] era (Heisei year 1 Jan 8)
|
||||
// or Reiwa [2019-] era (Reiwa year 1 May 1). If before the accession date,
|
||||
// the year will be in the previous era.
|
||||
// final String jCalShortPattern = "y/M/d"; // Note: just 'y' doesn't work here.
|
||||
// final String jCalGannenDate = "1/5/9"; // A date in the above format after the accession date for Heisei [1989-] era (Heisei year 1 Jan 8)
|
||||
// // or Reiwa [2019-] era (Reiwa year 1 May 1). If before the accession date,
|
||||
// // the year will be in the previous era.
|
||||
ULocale loc = new ULocale("ja_JP@calendar=japanese");
|
||||
Date refDate = new Date(600336000000L); // 1989 Jan 9 Monday = Heisei 1
|
||||
final String patText = "Gy年M月d日";
|
||||
|
||||
@@ -732,7 +732,7 @@ public class DateIntervalFormatTest extends TestFmwk {
|
||||
// Note that from_data/to_data are specified using era names from root, for the calendar specified by locale.
|
||||
String[] DATA = {
|
||||
"GGGGG y MM dd HH:mm:ss", // pattern for from_data/to_data
|
||||
|
||||
|
||||
// This test is for tickets ICU-21154, ICU-21155, and ICU-21156 and is intended to verify
|
||||
// that all of the special skeleton characters for hours and day periods work as expected
|
||||
// with date intervals:
|
||||
@@ -748,7 +748,7 @@ public class DateIntervalFormatTest extends TestFmwk {
|
||||
// baseline (h and H)
|
||||
"en", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "hh", "12 \\u2013 1 AM",
|
||||
"de", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "HH", "00\\u201301 Uhr",
|
||||
|
||||
|
||||
// k and K (ICU-21154 and ICU-21156)
|
||||
"en", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "KK", "0 \\u2013 1 AM",
|
||||
"de", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "kk", "24\\u201301 Uhr",
|
||||
@@ -758,7 +758,7 @@ public class DateIntervalFormatTest extends TestFmwk {
|
||||
"en", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "ha", "12 \\u2013 1 AM",
|
||||
"en", "CE 2010 09 27 10:00:00", "CE 2010 09 27 12:00:00", "haaaaa", "10 a \\u2013 12 p",
|
||||
"en", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "haaaaa", "12 \\u2013 1 a",
|
||||
|
||||
|
||||
// j (ICU-21155)
|
||||
"en", "CE 2010 09 27 10:00:00", "CE 2010 09 27 13:00:00", "jj", "10 AM \\u2013 1 PM",
|
||||
"en", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "jj", "12 \\u2013 1 AM",
|
||||
@@ -768,20 +768,20 @@ public class DateIntervalFormatTest extends TestFmwk {
|
||||
"de", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "jj", "00\\u201301 Uhr",
|
||||
"de", "CE 2010 09 27 10:00:00", "CE 2010 09 27 13:00:00", "jjjjj", "10\\u201313 Uhr",
|
||||
"de", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "jjjjj", "00\\u201301 Uhr",
|
||||
|
||||
|
||||
// b and B
|
||||
"en", "CE 2010 09 27 10:00:00", "CE 2010 09 27 12:00:00", "hb", "10 AM \\u2013 12 noon",
|
||||
"en", "CE 2010 09 27 10:00:00", "CE 2010 09 27 12:00:00", "hbbbbb", "10 a \\u2013 12 n",
|
||||
"en", "CE 2010 09 27 13:00:00", "CE 2010 09 27 14:00:00", "hb", "1 \\u2013 2 PM",
|
||||
"en", "CE 2010 09 27 10:00:00", "CE 2010 09 27 13:00:00", "hB", "10 in the morning \\u2013 1 in the afternoon",
|
||||
"en", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "hB", "12 \\u2013 1 at night",
|
||||
|
||||
|
||||
// J
|
||||
"en", "CE 2010 09 27 10:00:00", "CE 2010 09 27 13:00:00", "J", "10 \\u2013 1",
|
||||
"en", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "J", "12 \\u2013 1",
|
||||
"de", "CE 2010 09 27 10:00:00", "CE 2010 09 27 13:00:00", "J", "10\\u201313 Uhr",
|
||||
"de", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "J", "00\\u201301 Uhr",
|
||||
|
||||
|
||||
// C
|
||||
// (for English and German, C should do the same thing as j)
|
||||
"en", "CE 2010 09 27 10:00:00", "CE 2010 09 27 13:00:00", "CC", "10 AM \\u2013 1 PM",
|
||||
@@ -2187,6 +2187,7 @@ public class DateIntervalFormatTest extends TestFmwk {
|
||||
ULocale.AvailableType.WITH_LEGACY_ALIASES)) {
|
||||
// Only test 1/5 of the locale in quick mode.
|
||||
if (quick && (count++ % 5 > 0)) continue;
|
||||
@SuppressWarnings("unused")
|
||||
DateIntervalFormat fmt = DateIntervalFormat.getInstance("dMMMMy", locale);
|
||||
for (String calendar : Calendar.getKeywordValuesForLocale(
|
||||
"calendar", locale, false)) {
|
||||
|
||||
@@ -2652,7 +2652,7 @@ public class MeasureUnitTest extends TestFmwk {
|
||||
// This fails unless we resolve to MeasureUnit.POUND_PER_SQUARE_INCH
|
||||
assertEquals("", "50 psi",
|
||||
fmt.formatMeasurePerUnit(
|
||||
new Measure(50, MeasureUnit.POUND),
|
||||
new Measure(50, MeasureUnit.POUND_FORCE),
|
||||
MeasureUnit.SQUARE_INCH,
|
||||
new StringBuilder(),
|
||||
new FieldPosition(0)).toString());
|
||||
|
||||
@@ -241,13 +241,14 @@ public class UnitsTest {
|
||||
}
|
||||
|
||||
String codePage = "UTF-8";
|
||||
BufferedReader f = TestUtil.getDataReader("cldr/units/unitsTest.txt", codePage);
|
||||
ArrayList<TestCase> tests = new ArrayList<>();
|
||||
while (true) {
|
||||
String line = f.readLine();
|
||||
if (line == null) break;
|
||||
if (line.isEmpty() || line.startsWith("#")) continue;
|
||||
tests.add(new TestCase(line));
|
||||
try (BufferedReader f = TestUtil.getDataReader("cldr/units/unitsTest.txt", codePage)) {
|
||||
while (true) {
|
||||
String line = f.readLine();
|
||||
if (line == null) break;
|
||||
if (line.isEmpty() || line.startsWith("#")) continue;
|
||||
tests.add(new TestCase(line));
|
||||
}
|
||||
}
|
||||
|
||||
ConversionRates conversionRates = new ConversionRates();
|
||||
@@ -297,6 +298,7 @@ public class UnitsTest {
|
||||
/**
|
||||
* Test Case Data
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
String category;
|
||||
String usage;
|
||||
String region;
|
||||
@@ -349,13 +351,15 @@ public class UnitsTest {
|
||||
|
||||
// Read Test data from the unitPreferencesTest
|
||||
String codePage = "UTF-8";
|
||||
BufferedReader f = TestUtil.getDataReader("cldr/units/unitPreferencesTest.txt", codePage);
|
||||
ArrayList<TestCase> tests = new ArrayList<>();
|
||||
while (true) {
|
||||
String line = f.readLine();
|
||||
if (line == null) break;
|
||||
if (line.isEmpty() || line.startsWith("#")) continue;
|
||||
tests.add(new TestCase(line));
|
||||
|
||||
try (BufferedReader f = TestUtil.getDataReader("cldr/units/unitPreferencesTest.txt", codePage)) {
|
||||
while (true) {
|
||||
String line = f.readLine();
|
||||
if (line == null) break;
|
||||
if (line.isEmpty() || line.startsWith("#")) continue;
|
||||
tests.add(new TestCase(line));
|
||||
}
|
||||
}
|
||||
|
||||
for (TestCase testCase :
|
||||
|
||||
+240
-39
@@ -536,6 +536,23 @@ public class NumberFormatterApiTest extends TestFmwk {
|
||||
"0.0088 meters",
|
||||
"0 meters");
|
||||
|
||||
// // TODO(ICU-20941): Support formatting for not-built-in units
|
||||
// assertFormatDescending(
|
||||
// "Hectometers",
|
||||
// "measure-unit/length-hectometer",
|
||||
// "unit/hectometer",
|
||||
// NumberFormatter.with().unit(MeasureUnit.forIdentifier("hectometer")),
|
||||
// ULocale.ENGLISH,
|
||||
// "87,650 hm",
|
||||
// "8,765 ham",
|
||||
// "876.5 hm",
|
||||
// "87.65 hm",
|
||||
// "8.765 hm",
|
||||
// "0.8765 hm",
|
||||
// "0.08765 hm",
|
||||
// "0.008765 hm",
|
||||
// "0 hm");
|
||||
|
||||
assertFormatSingleMeasure(
|
||||
"Meters with Measure Input",
|
||||
"unit-width-full-name",
|
||||
@@ -655,11 +672,10 @@ public class NumberFormatterApiTest extends TestFmwk {
|
||||
ULocale.forLanguageTag("es-MX"),
|
||||
5,
|
||||
"5 a\u00F1os");
|
||||
|
||||
// TODO(icu-units#35): skeleton generation.
|
||||
|
||||
assertFormatSingle(
|
||||
"Mixed unit",
|
||||
null,
|
||||
"unit/yard-and-foot-and-inch",
|
||||
"unit/yard-and-foot-and-inch",
|
||||
NumberFormatter.with()
|
||||
.unit(MeasureUnit.forIdentifier("yard-and-foot-and-inch")),
|
||||
@@ -667,10 +683,9 @@ public class NumberFormatterApiTest extends TestFmwk {
|
||||
3.65,
|
||||
"3 yd, 1 ft, 11.4 in");
|
||||
|
||||
// TODO(icu-units#35): skeleton generation.
|
||||
assertFormatSingle(
|
||||
"Mixed unit, Scientific",
|
||||
null,
|
||||
"unit/yard-and-foot-and-inch E0",
|
||||
"unit/yard-and-foot-and-inch E0",
|
||||
NumberFormatter.with()
|
||||
.unit(MeasureUnit.forIdentifier("yard-and-foot-and-inch"))
|
||||
@@ -679,10 +694,9 @@ public class NumberFormatterApiTest extends TestFmwk {
|
||||
3.65,
|
||||
"3 yd, 1 ft, 1.14E1 in");
|
||||
|
||||
// TODO(icu-units#35): skeleton generation.
|
||||
assertFormatSingle(
|
||||
"Mixed Unit (Narrow Version)",
|
||||
null,
|
||||
"unit/metric-ton-and-kilogram-and-gram unit-width-narrow",
|
||||
"unit/metric-ton-and-kilogram-and-gram unit-width-narrow",
|
||||
NumberFormatter.with()
|
||||
.unit(MeasureUnit.forIdentifier("metric-ton-and-kilogram-and-gram"))
|
||||
@@ -691,10 +705,9 @@ public class NumberFormatterApiTest extends TestFmwk {
|
||||
4.28571,
|
||||
"4t 285kg 710g");
|
||||
|
||||
// TODO(icu-units#35): skeleton generation.
|
||||
assertFormatSingle(
|
||||
"Mixed Unit (Short Version)",
|
||||
null,
|
||||
"unit/metric-ton-and-kilogram-and-gram unit-width-short",
|
||||
"unit/metric-ton-and-kilogram-and-gram unit-width-short",
|
||||
NumberFormatter.with()
|
||||
.unit(MeasureUnit.forIdentifier("metric-ton-and-kilogram-and-gram"))
|
||||
@@ -703,10 +716,9 @@ public class NumberFormatterApiTest extends TestFmwk {
|
||||
4.28571,
|
||||
"4 t, 285 kg, 710 g");
|
||||
|
||||
// TODO(icu-units#35): skeleton generation.
|
||||
assertFormatSingle(
|
||||
"Mixed Unit (Full Name Version)",
|
||||
null,
|
||||
"unit/metric-ton-and-kilogram-and-gram unit-width-full-name",
|
||||
"unit/metric-ton-and-kilogram-and-gram unit-width-full-name",
|
||||
NumberFormatter.with()
|
||||
.unit(MeasureUnit.forIdentifier("metric-ton-and-kilogram-and-gram"))
|
||||
@@ -717,8 +729,8 @@ public class NumberFormatterApiTest extends TestFmwk {
|
||||
|
||||
assertFormatSingle(
|
||||
"Testing \"1 foot 12 inches\"",
|
||||
null,
|
||||
"unit/foot-and-inch",
|
||||
"unit/foot-and-inch @### unit-width-full-name",
|
||||
"unit/foot-and-inch @### unit-width-full-name",
|
||||
NumberFormatter.with()
|
||||
.unit(MeasureUnit.forIdentifier("foot-and-inch"))
|
||||
.precision(Precision.maxSignificantDigits(4))
|
||||
@@ -726,6 +738,24 @@ public class NumberFormatterApiTest extends TestFmwk {
|
||||
new ULocale("en-US"),
|
||||
1.9999,
|
||||
"2 feet, 0 inches");
|
||||
|
||||
assertFormatSingle(
|
||||
"Negative numbers: temperature",
|
||||
"measure-unit/temperature-celsius",
|
||||
"unit/celsius",
|
||||
NumberFormatter.with().unit(MeasureUnit.forIdentifier("celsius")),
|
||||
new ULocale("nl-NL"),
|
||||
-6.5,
|
||||
"-6,5\u00B0C");
|
||||
|
||||
assertFormatSingle(
|
||||
"Negative numbers: time",
|
||||
"unit/hour-and-minute-and-second",
|
||||
"unit/hour-and-minute-and-second",
|
||||
NumberFormatter.with().unit(MeasureUnit.forIdentifier("hour-and-minute-and-second")),
|
||||
new ULocale("de-DE"),
|
||||
-1.24,
|
||||
"-1 Std., 14 Min. und 24 Sek.");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -733,7 +763,7 @@ public class NumberFormatterApiTest extends TestFmwk {
|
||||
assertFormatDescending(
|
||||
"Meters Per Second Short (unit that simplifies) and perUnit method",
|
||||
"measure-unit/length-meter per-measure-unit/duration-second",
|
||||
"~unit/meter-per-second", // does not round-trip to the full skeleton above
|
||||
"unit/meter-per-second",
|
||||
NumberFormatter.with().unit(MeasureUnit.METER).perUnit(MeasureUnit.SECOND),
|
||||
ULocale.ENGLISH,
|
||||
"87,650 m/s",
|
||||
@@ -746,16 +776,21 @@ public class NumberFormatterApiTest extends TestFmwk {
|
||||
"0.008765 m/s",
|
||||
"0 m/s");
|
||||
|
||||
// TODO(icu-units#35): does not normalize as desired: while "unit/*" does
|
||||
// get split into unit/perUnit, ".unit(*)" and "measure-unit/*" don't:
|
||||
assertFormatSingle(
|
||||
"Built-in unit, meter-per-second",
|
||||
assertFormatDescending(
|
||||
"Meters Per Second Short, built-in m/s",
|
||||
"measure-unit/speed-meter-per-second",
|
||||
"~unit/meter-per-second",
|
||||
"unit/meter-per-second",
|
||||
NumberFormatter.with().unit(MeasureUnit.METER_PER_SECOND),
|
||||
new ULocale("en-GB"),
|
||||
2.4,
|
||||
"2.4 m/s");
|
||||
ULocale.ENGLISH,
|
||||
"87,650 m/s",
|
||||
"8,765 m/s",
|
||||
"876.5 m/s",
|
||||
"87.65 m/s",
|
||||
"8.765 m/s",
|
||||
"0.8765 m/s",
|
||||
"0.08765 m/s",
|
||||
"0.008765 m/s",
|
||||
"0 m/s");
|
||||
|
||||
assertFormatDescending(
|
||||
"Pounds Per Square Mile Short (secondary unit has per-format)",
|
||||
@@ -806,23 +841,57 @@ public class NumberFormatterApiTest extends TestFmwk {
|
||||
// "0.008765 J/fur",
|
||||
// "0 J/fur");
|
||||
|
||||
// TODO(icu-units#59): THIS UNIT TEST DEMONSTRATES UNDESIRABLE BEHAVIOUR!
|
||||
// When specifying built-in types, one can give both a unit and a perUnit.
|
||||
// Resolving to a built-in unit does not always work.
|
||||
//
|
||||
// (Unit-testing philosophy: do we leave this enabled to demonstrate current
|
||||
// behaviour, and changing behaviour in the future? Or comment it out to
|
||||
// avoid asserting this is "correct"?)
|
||||
assertFormatDescending(
|
||||
"Pounds per Square Inch: composed",
|
||||
"measure-unit/force-pound-force per-measure-unit/area-square-inch",
|
||||
"unit/pound-force-per-square-inch",
|
||||
NumberFormatter.with().unit(MeasureUnit.POUND_FORCE).perUnit(MeasureUnit.SQUARE_INCH),
|
||||
ULocale.ENGLISH,
|
||||
"87,650 psi",
|
||||
"8,765 psi",
|
||||
"876.5 psi",
|
||||
"87.65 psi",
|
||||
"8.765 psi",
|
||||
"0.8765 psi",
|
||||
"0.08765 psi",
|
||||
"0.008765 psi",
|
||||
"0 psi");
|
||||
|
||||
assertFormatDescending(
|
||||
"Pounds per Square Inch: built-in",
|
||||
"measure-unit/force-pound-force per-measure-unit/area-square-inch",
|
||||
"unit/pound-force-per-square-inch",
|
||||
NumberFormatter.with().unit(MeasureUnit.POUND_PER_SQUARE_INCH),
|
||||
ULocale.ENGLISH,
|
||||
"87,650 psi",
|
||||
"8,765 psi",
|
||||
"876.5 psi",
|
||||
"87.65 psi",
|
||||
"8.765 psi",
|
||||
"0.8765 psi",
|
||||
"0.08765 psi",
|
||||
"0.008765 psi",
|
||||
"0 psi");
|
||||
|
||||
assertFormatSingle(
|
||||
"DEMONSTRATING BAD BEHAVIOUR, TODO(icu-units#59)",
|
||||
"measure-unit/speed-meter-per-second per-measure-unit/duration-second",
|
||||
"m/s/s simplifies to m/s^2",
|
||||
"measure-unit/speed-meter-per-second per-measure-unit/duration-second",
|
||||
"unit/meter-per-square-second",
|
||||
NumberFormatter.with()
|
||||
.unit(MeasureUnit.METER_PER_SECOND)
|
||||
.perUnit(MeasureUnit.SECOND),
|
||||
new ULocale("en-GB"),
|
||||
2.4,
|
||||
"2.4 m/s/s");
|
||||
"2.4 m/s\u00B2");
|
||||
|
||||
assertFormatSingle(
|
||||
"Negative numbers: acceleration",
|
||||
"measure-unit/acceleration-meter-per-square-second",
|
||||
"unit/meter-per-second-second",
|
||||
NumberFormatter.with().unit(MeasureUnit.forIdentifier("meter-per-pow2-second")),
|
||||
new ULocale("af-ZA"),
|
||||
-9.81,
|
||||
"-9,81 m/s\u00B2");
|
||||
|
||||
// Testing the rejection of invalid specifications
|
||||
|
||||
@@ -841,21 +910,124 @@ public class NumberFormatterApiTest extends TestFmwk {
|
||||
// Pass
|
||||
}
|
||||
|
||||
// .perUnit() may only be passed a built-in type, "square-second" is not a
|
||||
// built-in type.
|
||||
// .perUnit() may only be passed a built-in type, or something that
|
||||
// combines to a built-in type together with .unit().
|
||||
nf = NumberFormatter.with()
|
||||
.unit(MeasureUnit.METER)
|
||||
.unit(MeasureUnit.FURLONG)
|
||||
.perUnit(MeasureUnit.forIdentifier("square-second"))
|
||||
.locale(new ULocale("en-GB"));
|
||||
|
||||
try {
|
||||
nf.format(2.4d);
|
||||
fail("Expected failure, got: " + nf.format(2.4d) + ".");
|
||||
} catch (UnsupportedOperationException e) {
|
||||
// pass
|
||||
}
|
||||
// As above, "square-second" is not a built-in type, however this time,
|
||||
// meter-per-square-second is a built-in type.
|
||||
assertFormatSingle(
|
||||
"meter per square-second works as a composed unit",
|
||||
"measure-unit/speed-meter-per-second per-measure-unit/duration-second",
|
||||
"unit/meter-per-square-second",
|
||||
NumberFormatter.with()
|
||||
.unit(MeasureUnit.METER)
|
||||
.perUnit(MeasureUnit.forIdentifier("square-second")),
|
||||
new ULocale("en-GB"),
|
||||
2.4,
|
||||
"2.4 m/s\u00B2");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void unitSkeletons() {
|
||||
Object[][] cases = {
|
||||
{"old-form built-in compound unit", //
|
||||
"measure-unit/speed-meter-per-second", //
|
||||
"unit/meter-per-second"},
|
||||
|
||||
{"old-form compound construction, converts to built-in", //
|
||||
"measure-unit/length-meter per-measure-unit/duration-second", //
|
||||
"unit/meter-per-second"},
|
||||
|
||||
{"old-form compound construction which does not simplify to a built-in", //
|
||||
"measure-unit/energy-joule per-measure-unit/length-meter", //
|
||||
"unit/joule-per-meter"},
|
||||
|
||||
{"old-form compound-compound ugliness resolves neatly", //
|
||||
"measure-unit/speed-meter-per-second per-measure-unit/duration-second", //
|
||||
"unit/meter-per-square-second"},
|
||||
|
||||
{"short-form built-in units stick with the built-in", //
|
||||
"unit/meter-per-second", //
|
||||
"unit/meter-per-second"},
|
||||
|
||||
{"short-form compound units stay as is", //
|
||||
"unit/square-meter-per-square-meter", //
|
||||
"unit/square-meter-per-square-meter"},
|
||||
|
||||
{"short-form compound units stay as is", //
|
||||
"unit/joule-per-furlong", //
|
||||
"unit/joule-per-furlong"},
|
||||
|
||||
{"short-form that doesn't consist of built-in units", //
|
||||
"unit/hectometer-per-second", //
|
||||
"unit/hectometer-per-second"},
|
||||
|
||||
{"short-form that doesn't consist of built-in units", //
|
||||
"unit/meter-per-hectosecond", //
|
||||
"unit/meter-per-hectosecond"},
|
||||
|
||||
// // TODO: binary prefixes not supported yet!
|
||||
// {"Round-trip example from icu-units#35", //
|
||||
// "unit/kibijoule-per-furlong", //
|
||||
// "unit/kibijoule-per-furlong"},
|
||||
};
|
||||
for (Object[] cas : cases) {
|
||||
String msg = (String)cas[0];
|
||||
String inputSkeleton = (String)cas[1];
|
||||
String normalizedSkeleton = (String)cas[2];
|
||||
UnlocalizedNumberFormatter nf = NumberFormatter.forSkeleton(inputSkeleton);
|
||||
assertEquals(msg, normalizedSkeleton, nf.toSkeleton());
|
||||
}
|
||||
|
||||
Object[][] failCases = {
|
||||
{"Parsing measure-unit/* results in failure if not built-in unit",
|
||||
"measure-unit/hectometer", //
|
||||
true, //
|
||||
false},
|
||||
|
||||
{"Parsing per-measure-unit/* results in failure if not built-in unit",
|
||||
"measure-unit/meter per-measure-unit/hectosecond", //
|
||||
true, //
|
||||
false},
|
||||
};
|
||||
for (Object[] cas : failCases) {
|
||||
String msg = (String)cas[0];
|
||||
String inputSkeleton = (String)cas[1];
|
||||
boolean forSkeletonExpectFailure = (boolean)cas[2];
|
||||
boolean toSkeletonExpectFailure = (boolean)cas[3];
|
||||
UnlocalizedNumberFormatter nf = null;
|
||||
try {
|
||||
nf = NumberFormatter.forSkeleton(inputSkeleton);
|
||||
if (forSkeletonExpectFailure) {
|
||||
fail("forSkeleton() should have failed: " + msg);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
if (!forSkeletonExpectFailure) {
|
||||
fail("forSkeleton() should not have failed: " + msg);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
nf.toSkeleton();
|
||||
if (toSkeletonExpectFailure) {
|
||||
fail("toSkeleton() should have failed: " + msg);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
if (!toSkeletonExpectFailure) {
|
||||
fail("toSkeleton() should not have failed: " + msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void unitUsage() {
|
||||
@@ -1091,6 +1263,15 @@ public class NumberFormatterApiTest extends TestFmwk {
|
||||
"8,765E0 square metres",
|
||||
"0E0 square centimetres");
|
||||
|
||||
assertFormatSingle(
|
||||
"Negative numbers: minute-and-second",
|
||||
"measure-unit/duration-second usage/media",
|
||||
"unit/second usage/media",
|
||||
NumberFormatter.with().unit(MeasureUnit.SECOND).usage("media"),
|
||||
new ULocale("nl-NL"),
|
||||
-77.7,
|
||||
"-1 min, 18 sec");
|
||||
|
||||
assertFormatSingle(
|
||||
"Rounding Mode propagates: rounding down",
|
||||
"usage/road measure-unit/length-centimeter rounding-mode-floor",
|
||||
@@ -1120,7 +1301,6 @@ public class NumberFormatterApiTest extends TestFmwk {
|
||||
// to see divide-by-zero behaviour.
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void unitUsageErrorCodes() {
|
||||
UnlocalizedNumberFormatter unloc_formatter;
|
||||
@@ -3372,11 +3552,11 @@ public class NumberFormatterApiTest extends TestFmwk {
|
||||
}
|
||||
|
||||
{
|
||||
String message = "Measure unit field position with prefix and suffix";
|
||||
String message = "Measure unit field position with prefix and suffix, composed m/s";
|
||||
FormattedNumber result = assertFormatSingle(
|
||||
message,
|
||||
"measure-unit/length-meter per-measure-unit/duration-second unit-width-full-name",
|
||||
"~unit/meter-per-second unit-width-full-name", // does not round-trip to the full skeleton above
|
||||
"measure-unit/length-meter per-measure-unit/duration-second unit-width-full-name",
|
||||
NumberFormatter.with().unit(MeasureUnit.METER).perUnit(MeasureUnit.SECOND).unitWidth(UnitWidth.FULL_NAME),
|
||||
new ULocale("ky"), // locale with the interesting data
|
||||
68,
|
||||
@@ -3392,6 +3572,27 @@ public class NumberFormatterApiTest extends TestFmwk {
|
||||
expectedFieldPositions);
|
||||
}
|
||||
|
||||
{
|
||||
String message = "Measure unit field position with prefix and suffix, built-in m/s";
|
||||
FormattedNumber result = assertFormatSingle(
|
||||
message,
|
||||
"measure-unit/speed-meter-per-second unit-width-full-name",
|
||||
"unit/meter-per-second unit-width-full-name",
|
||||
NumberFormatter.with().unit(MeasureUnit.METER_PER_SECOND).unitWidth(UnitWidth.FULL_NAME),
|
||||
new ULocale("ky"), // locale with the interesting data
|
||||
68,
|
||||
"секундасына 68 метр");
|
||||
Object[][] expectedFieldPositions = new Object[][] {
|
||||
// field, begin index, end index
|
||||
{NumberFormat.Field.MEASURE_UNIT, 0, 11},
|
||||
{NumberFormat.Field.INTEGER, 12, 14},
|
||||
{NumberFormat.Field.MEASURE_UNIT, 15, 19}};
|
||||
assertNumberFieldPositions(
|
||||
message,
|
||||
result,
|
||||
expectedFieldPositions);
|
||||
}
|
||||
|
||||
{
|
||||
String message = "Measure unit field position with inner spaces";
|
||||
FormattedNumber result = assertFormatSingle(
|
||||
|
||||
@@ -326,11 +326,11 @@ public class NumberSkeletonTest {
|
||||
{ "scientific/*ee", "scientific/+ee" },
|
||||
{ "integer-width/*00", "integer-width/+00" },
|
||||
};
|
||||
|
||||
|
||||
for (String[] cas : cases) {
|
||||
String star = cas[0];
|
||||
String plus = cas[1];
|
||||
|
||||
|
||||
String normalized = NumberFormatter.forSkeleton(plus)
|
||||
.toSkeleton();
|
||||
assertEquals("Plus should normalize to star", star, normalized);
|
||||
@@ -404,6 +404,7 @@ public class NumberSkeletonTest {
|
||||
String skeleton = "measure-unit/";
|
||||
skeleton += cas1[0] + "-" + cas1[1] + " per-measure-unit/" + cas2[0] + "-" + cas2[1];
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
String actual = NumberFormatter.forSkeleton(skeleton).locale(arabic).format(5142.3)
|
||||
.toString();
|
||||
// Just make sure it won't throw exception
|
||||
|
||||
@@ -1895,6 +1895,7 @@ public class RBBITestMonkey extends TestFmwk {
|
||||
|
||||
// Helper function for formatting error output.
|
||||
// Display a code point in "\\uxxxx" or "\Uxxxxxxxx" format
|
||||
@SuppressWarnings("unused")
|
||||
private static void appendCharToBuf(StringBuffer dest, int c, int fieldLen) {
|
||||
String hexChars = "0123456789abcdef";
|
||||
if (c < 0x10000) {
|
||||
@@ -1927,6 +1928,7 @@ public class RBBITestMonkey extends TestFmwk {
|
||||
StringBuffer testText = new StringBuffer();
|
||||
int numCharClasses;
|
||||
List chClasses;
|
||||
@SuppressWarnings("unused")
|
||||
int expectedCount = 0;
|
||||
boolean[] expectedBreaks = new boolean[TESTSTRINGLEN*2 + 1];
|
||||
boolean[] forwardBreaks = new boolean[TESTSTRINGLEN*2 + 1];
|
||||
@@ -2201,13 +2203,13 @@ public class RBBITestMonkey extends TestFmwk {
|
||||
|
||||
// BMP or SMP character in hex
|
||||
if (c >= 0x10000) {
|
||||
buffer.append("\\U").append(String.format("%08x", (int) c));
|
||||
buffer.append("\\U").append(String.format("%08x", c));
|
||||
} else {
|
||||
buffer.append(" \\u").append(String.format("%04x", (int) c));
|
||||
buffer.append(" \\u").append(String.format("%04x", c));
|
||||
}
|
||||
|
||||
buffer.append(
|
||||
String.format(String.format(" %%-%ds", (int) classNameSize),
|
||||
String.format(String.format(" %%-%ds", classNameSize),
|
||||
mk.classNameFromCodepoint(c)))
|
||||
.append(String.format(" %-40s", mk.getAppliedRule(ci)))
|
||||
.append(String.format(" %-40s\n", UCharacter.getExtendedName(c)));
|
||||
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Loaded 100 of 186 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user