Merge lp:~zorba-coders/zorba/bug-1123162 into lp:zorba
- bug-1123162
- Merge into trunk
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Matthias Brantner | ||||
Approved revision: | 11331 | ||||
Merged at revision: | 11302 | ||||
Proposed branch: | lp:~zorba-coders/zorba/bug-1123162 | ||||
Merge into: | lp:zorba | ||||
Diff against target: |
5539 lines (+2779/-934) 156 files modified
ChangeLog (+3/-0) include/zorba/dynamic_context.h (+15/-0) include/zorba/locale.h (+1/-1) include/zorba/pregenerated/diagnostic_list.h (+2/-2) include/zorba/time.h (+68/-0) modules/org/expath/ns/file.xq.src/file.cpp (+1/-1) modules/w3c/pregenerated/xqt-errors.xq (+5/-5) modules/xqxq/xqxq.xq.src/xqxq.cpp (+1/-1) src/api/dynamiccontextimpl.cpp (+11/-0) src/api/dynamiccontextimpl.h (+6/-0) src/context/dynamic_context.cpp (+2/-0) src/context/dynamic_context.h (+10/-0) src/diagnostics/diagnostic_en.xml (+39/-9) src/diagnostics/pregenerated/diagnostic_list.cpp (+4/-4) src/diagnostics/pregenerated/dict_en.cpp (+12/-2) src/diagnostics/pregenerated/dict_zed_keys.h (+10/-0) src/functions/func_durations_dates_times_impl.cpp (+1/-0) src/runtime/CMakeLists.txt (+1/-0) src/runtime/durations_dates_times/DurationsDatesTimesImpl.cpp (+0/-560) src/runtime/durations_dates_times/DurationsDatesTimesImpl.h (+5/-46) src/runtime/durations_dates_times/format_dateTime.cpp (+1377/-0) src/runtime/durations_dates_times/format_dateTime.h (+81/-0) src/runtime/visitors/printer_visitor_impl.cpp (+1/-0) src/unit_tests/CMakeLists.txt (+1/-0) src/unit_tests/test_time.cpp (+118/-0) src/unit_tests/unit_test_list.h (+1/-0) src/unit_tests/unit_tests.cpp (+1/-0) src/util/ascii_util.h (+54/-0) src/util/stream_util.cpp (+31/-0) src/util/stream_util.h (+14/-0) src/util/time_util.cpp (+152/-14) src/util/time_util.h (+170/-25) src/util/unicode_util.cpp (+18/-0) src/util/unicode_util.h (+17/-0) src/util/utf8_string.h (+25/-0) src/util/utf8_util.cpp (+32/-0) src/util/utf8_util.h (+67/-0) src/zorbatypes/datetime.h (+0/-9) src/zorbatypes/datetime/datetimetype.cpp (+85/-151) src/zorbautils/locale.cpp (+205/-0) src/zorbautils/locale.h (+9/-0) test/fots/CMakeLists.txt (+0/-66) test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncYearMonth1.xml.res (+0/-1) test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncYearMonth2.xml.res (+0/-1) test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-D.xml.res (+1/-0) test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-D01.xml.res (+1/-0) test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-D1o.xml.res (+1/-0) test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-DW-1.xml.res (+1/-0) test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-DWo-1.xml.res (+1/-0) test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-DWw.xml.res (+1/-0) test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-DWwo.xml.res (+1/-0) test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-Dw-2.xml.res (+1/-0) test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-Dwo-2.xml.res (+1/-0) test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-FN-1.xml.res (+1/-0) test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-FN-3.xml.res (+1/-0) test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-FNn-1.xml.res (+1/-0) test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-FNn-2.xml.res (+1/-0) test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-Fn-2.xml.res (+1/-0) test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-Fn-4.xml.res (+1/-0) test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-M.xml.res (+1/-1) test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-M01.xml.res (+1/-1) test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-MN-1.xml.res (+1/-1) test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-MNn.xml.res (+1/-1) test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-Mn-2.xml.res (+1/-1) test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-Y-2-2.xml.res (+1/-1) test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-Y-M01-D01.xml.res (+1/-1) test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-Y-Thai-1.xml.res (+1/-0) test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-Y-Thai-2.xml.res (+1/-0) test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-Y.xml.res (+1/-1) test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-YI-1.xml.res (+1/-0) test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-Yi-2.xml.res (+1/-0) test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-chars.xml.res (+1/-1) test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-whitespace.xml.res (+1/-1) test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-dateTime-01.xml.res (+1/-1) test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-H-1.xml.res (+1/-0) test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-P-1.xml.res (+1/-0) test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-P-2.xml.res (+1/-0) test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-P-3.xml.res (+1/-0) test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-Z0-1.xml.res (+1/-0) test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-Z0-2.xml.res (+1/-0) test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-Z0000.xml.res (+1/-0) test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-Z00_00.xml.res (+1/-0) test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-Z00_00t-1.xml.res (+1/-0) test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-Z00_00t-2.xml.res (+1/-0) test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-Z0_00.xml.res (+1/-0) test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-ZN-CST.xml.res (+1/-0) test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-ZN-EST.xml.res (+1/-0) test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-ZN-GMT.xml.res (+1/-0) test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-ZN-MST.xml.res (+1/-0) test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-ZN-PST.xml.res (+1/-0) test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-ZZ-1.xml.res (+1/-0) test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-ZZ-2.xml.res (+1/-0) test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-h-2.xml.res (+1/-0) test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-z.xml.res (+1/-0) test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncYearMonth1.xq (+0/-1) test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncYearMonth2.xq (+0/-1) test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-BadComponent.spec (+1/-0) test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-BadComponent.xq (+1/-0) test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-CharExpected-1.spec (+1/-0) test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-CharExpected-1.xq (+1/-0) test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-D.xq (+2/-0) test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-D01.xq (+2/-0) test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-DW-1.xq (+1/-0) test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-DWw.xq (+1/-0) test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-Dw-2.xq (+1/-0) test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-FN-1.xq (+1/-0) test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-FN-3.xq (+1/-0) test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-FNn-1.xq (+1/-0) test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-FNn-2.xq (+1/-0) test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-Fn-2.xq (+1/-0) test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-Fn-4.xq (+1/-0) test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-M.xq (+2/-2) test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-M01.xq (+2/-2) test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-MN-1.xq (+1/-1) test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-MNn.xq (+1/-1) test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-Mn-2.xq (+1/-1) test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-NoAdjacentGroupSep.spec (+1/-0) test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-NoAdjacentGroupSep.xq (+1/-0) test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-NoComponent.spec (+1/-0) test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-NoComponent.xq (+1/-0) test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-NoGroupSepAtEnd.spec (+1/-0) test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-NoGroupSepAtEnd.xq (+1/-0) test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-NoGroupSepAtStart.spec (+1/-0) test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-NoGroupSepAtStart.xq (+1/-0) test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-NoOptDigitAfterMandatory.spec (+1/-0) test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-NoOptDigitAfterMandatory.xq (+1/-0) test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-Y-2-2.xq (+2/-2) test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-Y-M01-D01.xq (+3/-3) test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-Y-Thai-1.xq (+1/-0) test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-Y-Thai-2.xq (+1/-0) test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-Y.xq (+1/-2) test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-YI-1.xq (+1/-0) test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-Yi-2.xq (+1/-0) test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-chars.xq (+2/-2) test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-whitespace.xq (+4/-4) test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-dateTime-01.xq (+3/-3) test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-H-1.xq (+1/-0) test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-P-1.xq (+1/-0) test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-P-2.xq (+1/-0) test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-P-3.xq (+1/-0) test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-Z0-1.xq (+1/-0) test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-Z0-2.xq (+1/-0) test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-Z0000.xq (+1/-0) test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-Z00_00.xq (+1/-0) test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-Z00_00t-1.xq (+1/-0) test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-Z00_00t-2.xq (+1/-0) test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-Z0_00.xq (+1/-0) test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-ZN-CST.xq (+1/-0) test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-ZN-EST.xq (+1/-0) test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-ZN-GMT.xq (+1/-0) test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-ZN-MST.xq (+1/-0) test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-ZN-PST.xq (+1/-0) test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-ZZ-1.xq (+1/-0) test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-ZZ-2.xq (+1/-0) test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-h-2.xq (+1/-0) test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-z.xq (+1/-0) |
||||
To merge this branch: | bzr merge lp:~zorba-coders/zorba/bug-1123162 | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Matthias Brantner | Approve | ||
Sorin Marian Nasoi | Approve | ||
Nicolae Brinza | Approve | ||
Paul J. Lucas | Approve | ||
Review via email: mp+154529@code.launchpad.net |
Commit message
Fixed many date/time formatting bugs by completely rewriting the code; added basic support for multiple calendar systems; added default countries-
Description of the change
Fixed many date/time formatting bugs by completely rewriting the code; added basic support for multiple calendar systems; added default countries-
Paul J. Lucas (paul-lucas) : | # |
Zorba Build Bot (zorba-buildbot) wrote : | # |
Zorba Build Bot (zorba-buildbot) wrote : | # |
The attempt to merge lp:~zorba-coders/zorba/bug-1123162 into lp:zorba failed. Below is the output from the failed tests.
CMake Error at /home/ceej/
Validation queue job bug-1123162-2013-03-
final status was:
Undetermined, probably an error - please email <email address hidden> with the
number of this job!
Error in read script: /home/ceej/
Chris Hillery (ceejatec) wrote : | # |
Sorry, I killed this merge, because until https:/
Zorba Build Bot (zorba-buildbot) wrote : | # |
Validation queue starting for merge proposal.
Log at: http://
Zorba Build Bot (zorba-buildbot) wrote : | # |
The attempt to merge lp:~zorba-coders/zorba/bug-1123162 into lp:zorba failed. Below is the output from the failed tests.
CMake Error at /home/ceej/
Validation queue job bug-1123162-2013-03-
final status was:
16 tests did not succeed - changes not commited.
Error in read script: /home/ceej/
Zorba Build Bot (zorba-buildbot) wrote : | # |
Validation queue starting for merge proposal.
Log at: http://
Zorba Build Bot (zorba-buildbot) wrote : | # |
Validation queue job bug-1123162-2013-03-
All tests succeeded!
Zorba Build Bot (zorba-buildbot) wrote : | # |
Voting does not meet specified criteria. Required: Approve > 1, Disapprove < 1, Needs Fixing < 1, Pending < 1, Needs Information < 1, Resubmit < 1. Got: 1 Approve.
Nicolae Brinza (nbrinza) : | # |
Sorin Marian Nasoi (sorin.marian.nasoi) : | # |
Matthias Brantner (matthias-brantner) : | # |
Zorba Build Bot (zorba-buildbot) wrote : | # |
Validation queue starting for merge proposal.
Log at: http://
Zorba Build Bot (zorba-buildbot) wrote : | # |
Validation queue job bug-1123162-2013-03-
All tests succeeded!
Preview Diff
1 | === modified file 'ChangeLog' | |||
2 | --- ChangeLog 2013-03-20 22:28:21 +0000 | |||
3 | +++ ChangeLog 2013-03-21 16:00:34 +0000 | |||
4 | @@ -14,6 +14,8 @@ | |||
5 | 14 | * In store API, added ability to specify a stream's originating URI (file) | 14 | * In store API, added ability to specify a stream's originating URI (file) |
6 | 15 | for streamable strings and base64Binary. | 15 | for streamable strings and base64Binary. |
7 | 16 | * Added millis-to-dateTime() function in datetime module. | 16 | * Added millis-to-dateTime() function in datetime module. |
8 | 17 | * Added setCalendar(), getCalendar(), setLocale(), and getLocale() to | ||
9 | 18 | DynamicContext class in C++ API. | ||
10 | 17 | * fn:trace outputs "empty-sequence()" if the input is the empty-sequence. | 19 | * fn:trace outputs "empty-sequence()" if the input is the empty-sequence. |
11 | 18 | * Allow multiple default function namespaces. | 20 | * Allow multiple default function namespaces. |
12 | 19 | * Added xqxq:variable-value function. | 21 | * Added xqxq:variable-value function. |
13 | @@ -33,6 +35,7 @@ | |||
14 | 33 | * Fixed bug #1095889 (Improve error message for xml-parsing error). | 35 | * Fixed bug #1095889 (Improve error message for xml-parsing error). |
15 | 34 | * Fixed bug in index join rule (no index join if inner clause has positional var). | 36 | * Fixed bug in index join rule (no index join if inner clause has positional var). |
16 | 35 | * Fixed bug in index join rule (copy var ids after cloning index domain expr). | 37 | * Fixed bug in index join rule (copy var ids after cloning index domain expr). |
17 | 38 | * Fixed bug #1123162 (FOTS: formatting dates and times failures) | ||
18 | 36 | * Added missing wrapper expressions around some variable references. | 39 | * Added missing wrapper expressions around some variable references. |
19 | 37 | * Fixed bug in the throwing of error XQTY0086 during node construction. | 40 | * Fixed bug in the throwing of error XQTY0086 during node construction. |
20 | 38 | * Fixed bug #1148335 (where-clause expression was not always reset when it should be) | 41 | * Fixed bug #1148335 (where-clause expression was not always reset when it should be) |
21 | 39 | 42 | ||
22 | === modified file 'include/zorba/dynamic_context.h' | |||
23 | --- include/zorba/dynamic_context.h 2013-03-08 04:26:02 +0000 | |||
24 | +++ include/zorba/dynamic_context.h 2013-03-21 16:00:34 +0000 | |||
25 | @@ -22,6 +22,7 @@ | |||
26 | 22 | 22 | ||
27 | 23 | #include <zorba/config.h> | 23 | #include <zorba/config.h> |
28 | 24 | #include <zorba/locale.h> | 24 | #include <zorba/locale.h> |
29 | 25 | #include <zorba/time.h> | ||
30 | 25 | #include <zorba/api_shared_types.h> | 26 | #include <zorba/api_shared_types.h> |
31 | 26 | #include <zorba/static_context_consts.h> | 27 | #include <zorba/static_context_consts.h> |
32 | 27 | #include <zorba/xmldatamanager.h> | 28 | #include <zorba/xmldatamanager.h> |
33 | @@ -268,6 +269,20 @@ | |||
34 | 268 | getLocale( locale::iso639_1::type *aLang, | 269 | getLocale( locale::iso639_1::type *aLang, |
35 | 269 | locale::iso3166_1::type *aCountry ) const = 0; | 270 | locale::iso3166_1::type *aCountry ) const = 0; |
36 | 270 | 271 | ||
37 | 272 | /** \brief Sets the calendar. | ||
38 | 273 | * | ||
39 | 274 | * @param aCalendar The calendar to use. | ||
40 | 275 | */ | ||
41 | 276 | virtual void | ||
42 | 277 | setCalendar( time::calendar::type aCalendar ) = 0; | ||
43 | 278 | |||
44 | 279 | /** \brief Gets the current calendar. | ||
45 | 280 | * | ||
46 | 281 | * @return the current calendar. | ||
47 | 282 | */ | ||
48 | 283 | virtual time::calendar::type | ||
49 | 284 | getCalendar() const = 0; | ||
50 | 285 | |||
51 | 271 | /** \brief Add a name-value pair to this context. | 286 | /** \brief Add a name-value pair to this context. |
52 | 272 | * The value can be accessed in the evaluate method | 287 | * The value can be accessed in the evaluate method |
53 | 273 | * of external functions (see ContextualExternalFunction). | 288 | * of external functions (see ContextualExternalFunction). |
54 | 274 | 289 | ||
55 | === modified file 'include/zorba/locale.h' | |||
56 | --- include/zorba/locale.h 2013-03-08 04:26:02 +0000 | |||
57 | +++ include/zorba/locale.h 2013-03-21 16:00:34 +0000 | |||
58 | @@ -263,7 +263,7 @@ | |||
59 | 263 | BZ, ///< Belize | 263 | BZ, ///< Belize |
60 | 264 | CA, ///< Canada | 264 | CA, ///< Canada |
61 | 265 | CC, ///< Cocos Islands | 265 | CC, ///< Cocos Islands |
63 | 266 | CD, ///< Congo | 266 | CD, ///< Congo, the Democratic Republic of the |
64 | 267 | CF, ///< Central African Republic | 267 | CF, ///< Central African Republic |
65 | 268 | CG, ///< Congo | 268 | CG, ///< Congo |
66 | 269 | CH, ///< Switzerland | 269 | CH, ///< Switzerland |
67 | 270 | 270 | ||
68 | === modified file 'include/zorba/pregenerated/diagnostic_list.h' | |||
69 | --- include/zorba/pregenerated/diagnostic_list.h 2013-03-06 10:37:33 +0000 | |||
70 | +++ include/zorba/pregenerated/diagnostic_list.h 2013-03-21 16:00:34 +0000 | |||
71 | @@ -192,9 +192,9 @@ | |||
72 | 192 | 192 | ||
73 | 193 | extern ZORBA_DLL_PUBLIC XQueryErrorCode XTDE1310; | 193 | extern ZORBA_DLL_PUBLIC XQueryErrorCode XTDE1310; |
74 | 194 | 194 | ||
76 | 195 | extern ZORBA_DLL_PUBLIC XQueryErrorCode XTDE1340; | 195 | extern ZORBA_DLL_PUBLIC XQueryErrorCode FOFD1340; |
77 | 196 | 196 | ||
79 | 197 | extern ZORBA_DLL_PUBLIC XQueryErrorCode XTDE1350; | 197 | extern ZORBA_DLL_PUBLIC XQueryErrorCode FOFD1350; |
80 | 198 | 198 | ||
81 | 199 | #if !defined(ZORBA_NO_FULL_TEXT) | 199 | #if !defined(ZORBA_NO_FULL_TEXT) |
82 | 200 | extern ZORBA_DLL_PUBLIC XQueryErrorCode FTST0008; | 200 | extern ZORBA_DLL_PUBLIC XQueryErrorCode FTST0008; |
83 | 201 | 201 | ||
84 | === added file 'include/zorba/time.h' | |||
85 | --- include/zorba/time.h 1970-01-01 00:00:00 +0000 | |||
86 | +++ include/zorba/time.h 2013-03-21 16:00:34 +0000 | |||
87 | @@ -0,0 +1,68 @@ | |||
88 | 1 | /* | ||
89 | 2 | * Copyright 2006-2008 The FLWOR Foundation. | ||
90 | 3 | * | ||
91 | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
92 | 5 | * you may not use this file except in compliance with the License. | ||
93 | 6 | * You may obtain a copy of the License at | ||
94 | 7 | * | ||
95 | 8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
96 | 9 | * | ||
97 | 10 | * Unless required by applicable law or agreed to in writing, software | ||
98 | 11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
99 | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
100 | 13 | * See the License for the specific language governing permissions and | ||
101 | 14 | * limitations under the License. | ||
102 | 15 | */ | ||
103 | 16 | |||
104 | 17 | #ifndef ZORBA_TIME_API_H | ||
105 | 18 | #define ZORBA_TIME_API_H | ||
106 | 19 | |||
107 | 20 | namespace zorba { | ||
108 | 21 | namespace time { | ||
109 | 22 | |||
110 | 23 | /////////////////////////////////////////////////////////////////////////////// | ||
111 | 24 | |||
112 | 25 | /** | ||
113 | 26 | * XQuery 3.0 F&O: 9.8.4.3: The calendars listed below were known to be in use | ||
114 | 27 | * during the last hundred years. | ||
115 | 28 | */ | ||
116 | 29 | namespace calendar { | ||
117 | 30 | enum type { | ||
118 | 31 | unknown, | ||
119 | 32 | AD, ///< Anno Domini (Christian Era) | ||
120 | 33 | AH, ///< Anno Hegirae (Muhammedan Era) | ||
121 | 34 | AM, ///< Anno Mundi (Jewish Calendar) | ||
122 | 35 | AME, ///< Mauludi Era (solar years since Mohammed's birth) | ||
123 | 36 | AP, ///< Anno Persici | ||
124 | 37 | AS, ///< Aji Saka Era (Java) | ||
125 | 38 | BE, ///< Buddhist Era | ||
126 | 39 | CB, ///< Cooch Behar Era | ||
127 | 40 | CE, ///< Common Era | ||
128 | 41 | CL, ///< Chinese Lunar Era | ||
129 | 42 | CS, ///< Chula Sakarat Era | ||
130 | 43 | EE, ///< Ethiopian Era | ||
131 | 44 | FE, ///< Fasli Era | ||
132 | 45 | ISO, ///< ISO 8601 calendar | ||
133 | 46 | JE, ///< Japanese Calendar | ||
134 | 47 | KE, ///< Khalsa Era (Sikh calendar) | ||
135 | 48 | KY, ///< Kali Yuga | ||
136 | 49 | ME, ///< Malabar Era | ||
137 | 50 | MS, ///< Monarchic Solar Era | ||
138 | 51 | OS, ///< Old Style (Julian Calendar) | ||
139 | 52 | RS, ///< Rattanakosin (Bangkok) Era | ||
140 | 53 | SE, ///< Saka Era | ||
141 | 54 | SH, ///< Mohammedan Solar Era (Iran) | ||
142 | 55 | SS, ///< Saka Samvat | ||
143 | 56 | TE, ///< Tripurabda Era | ||
144 | 57 | VE, ///< Vikrama Era | ||
145 | 58 | VS ///< Vikrama Samvat Era | ||
146 | 59 | }; | ||
147 | 60 | |||
148 | 61 | } // namespace calendar | ||
149 | 62 | |||
150 | 63 | /////////////////////////////////////////////////////////////////////////////// | ||
151 | 64 | |||
152 | 65 | } // namespace time | ||
153 | 66 | } // namespace zorba | ||
154 | 67 | #endif /* ZORBA_TIME_API_H */ | ||
155 | 68 | /* vim:set et sw=2 ts=2: */ | ||
156 | 0 | 69 | ||
157 | === modified file 'modules/org/expath/ns/file.xq.src/file.cpp' | |||
158 | --- modules/org/expath/ns/file.xq.src/file.cpp 2013-03-06 02:54:03 +0000 | |||
159 | +++ modules/org/expath/ns/file.xq.src/file.cpp 2013-03-21 16:00:34 +0000 | |||
160 | @@ -657,7 +657,7 @@ | |||
161 | 657 | int | 657 | int |
162 | 658 | LastModifiedFunction::getGmtOffset() | 658 | LastModifiedFunction::getGmtOffset() |
163 | 659 | { | 659 | { |
165 | 660 | time_t t = time(0); | 660 | time_t t = ::time(0); |
166 | 661 | struct tm* data; | 661 | struct tm* data; |
167 | 662 | data = localtime(&t); | 662 | data = localtime(&t); |
168 | 663 | data->tm_isdst = 0; | 663 | data->tm_isdst = 0; |
169 | 664 | 664 | ||
170 | === modified file 'modules/w3c/pregenerated/xqt-errors.xq' | |||
171 | --- modules/w3c/pregenerated/xqt-errors.xq 2013-03-06 10:37:33 +0000 | |||
172 | +++ modules/w3c/pregenerated/xqt-errors.xq 2013-03-21 16:00:34 +0000 | |||
173 | @@ -861,17 +861,17 @@ | |||
174 | 861 | : | 861 | : |
175 | 862 | : @see http://www.w3.org/2005/xqt-errors | 862 | : @see http://www.w3.org/2005/xqt-errors |
176 | 863 | :) | 863 | :) |
178 | 864 | declare variable $err:XTDE1340 as xs:QName := fn:QName($err:NS, "err:XTDE1340"); | 864 | declare variable $err:FOFD1340 as xs:QName := fn:QName($err:NS, "err:FOFD1340"); |
179 | 865 | 865 | ||
180 | 866 | (:~ | 866 | (:~ |
181 | 867 | : | 867 | : |
185 | 868 | : It is a non-recoverable dynamic error if a component specifier within the | 868 | : It is a non-recoverable dynamic error if a component specifier within |
186 | 869 | : picture refers to components that are not available in the given type of | 869 | : the picture refers to components that are not available in the given |
187 | 870 | : \c $value. | 870 | : type of $value. |
188 | 871 | : | 871 | : |
189 | 872 | : @see http://www.w3.org/2005/xqt-errors | 872 | : @see http://www.w3.org/2005/xqt-errors |
190 | 873 | :) | 873 | :) |
192 | 874 | declare variable $err:XTDE1350 as xs:QName := fn:QName($err:NS, "err:XTDE1350"); | 874 | declare variable $err:FOFD1350 as xs:QName := fn:QName($err:NS, "err:FOFD1350"); |
193 | 875 | 875 | ||
194 | 876 | (:~ | 876 | (:~ |
195 | 877 | : | 877 | : |
196 | 878 | 878 | ||
197 | === modified file 'modules/xqxq/xqxq.xq.src/xqxq.cpp' | |||
198 | --- modules/xqxq/xqxq.xq.src/xqxq.cpp 2013-02-22 17:09:54 +0000 | |||
199 | +++ modules/xqxq/xqxq.xq.src/xqxq.cpp 2013-03-21 16:00:34 +0000 | |||
200 | @@ -238,7 +238,7 @@ | |||
201 | 238 | : | 238 | : |
202 | 239 | theModule(aModule) | 239 | theModule(aModule) |
203 | 240 | { | 240 | { |
205 | 241 | srand(time(NULL)); | 241 | srand(::time(NULL)); |
206 | 242 | } | 242 | } |
207 | 243 | 243 | ||
208 | 244 | 244 | ||
209 | 245 | 245 | ||
210 | === modified file 'src/api/dynamiccontextimpl.cpp' | |||
211 | --- src/api/dynamiccontextimpl.cpp 2013-03-08 04:26:02 +0000 | |||
212 | +++ src/api/dynamiccontextimpl.cpp 2013-03-21 16:00:34 +0000 | |||
213 | @@ -691,6 +691,17 @@ | |||
214 | 691 | /****************************************************************************//** | 691 | /****************************************************************************//** |
215 | 692 | 692 | ||
216 | 693 | ********************************************************************************/ | 693 | ********************************************************************************/ |
217 | 694 | void DynamicContextImpl::setCalendar( time::calendar::type aCalendar ) { | ||
218 | 695 | theCtx->set_calendar( aCalendar ); | ||
219 | 696 | } | ||
220 | 697 | |||
221 | 698 | time::calendar::type DynamicContextImpl::getCalendar() const { | ||
222 | 699 | return theCtx->get_calendar(); | ||
223 | 700 | } | ||
224 | 701 | |||
225 | 702 | /****************************************************************************//** | ||
226 | 703 | |||
227 | 704 | ********************************************************************************/ | ||
228 | 694 | bool DynamicContextImpl::addExternalFunctionParam( | 705 | bool DynamicContextImpl::addExternalFunctionParam( |
229 | 695 | const String& aName, | 706 | const String& aName, |
230 | 696 | void* aValue) | 707 | void* aValue) |
231 | 697 | 708 | ||
232 | === modified file 'src/api/dynamiccontextimpl.h' | |||
233 | --- src/api/dynamiccontextimpl.h 2013-03-08 04:26:02 +0000 | |||
234 | +++ src/api/dynamiccontextimpl.h 2013-03-21 16:00:34 +0000 | |||
235 | @@ -151,6 +151,12 @@ | |||
236 | 151 | getLocale( locale::iso639_1::type *aLang, | 151 | getLocale( locale::iso639_1::type *aLang, |
237 | 152 | locale::iso3166_1::type *aCountry ) const; | 152 | locale::iso3166_1::type *aCountry ) const; |
238 | 153 | 153 | ||
239 | 154 | virtual void | ||
240 | 155 | setCalendar( time::calendar::type aCalendar ); | ||
241 | 156 | |||
242 | 157 | virtual time::calendar::type | ||
243 | 158 | getCalendar() const; | ||
244 | 159 | |||
245 | 154 | virtual bool | 160 | virtual bool |
246 | 155 | addExternalFunctionParam(const String& aName, void* aValue); | 161 | addExternalFunctionParam(const String& aName, void* aValue); |
247 | 156 | 162 | ||
248 | 157 | 163 | ||
249 | === modified file 'src/context/dynamic_context.cpp' | |||
250 | --- src/context/dynamic_context.cpp 2013-03-12 17:03:31 +0000 | |||
251 | +++ src/context/dynamic_context.cpp 2013-03-21 16:00:34 +0000 | |||
252 | @@ -137,6 +137,7 @@ | |||
253 | 137 | reset_current_date_time(); | 137 | reset_current_date_time(); |
254 | 138 | theLang = locale::get_host_lang(); | 138 | theLang = locale::get_host_lang(); |
255 | 139 | theCountry = locale::get_host_country(); | 139 | theCountry = locale::get_host_country(); |
256 | 140 | theCalendar = time::calendar::get_default(); | ||
257 | 140 | } | 141 | } |
258 | 141 | else | 142 | else |
259 | 142 | { | 143 | { |
260 | @@ -145,6 +146,7 @@ | |||
261 | 145 | theDefaultCollectionUri = parent->theDefaultCollectionUri; | 146 | theDefaultCollectionUri = parent->theDefaultCollectionUri; |
262 | 146 | theLang = parent->theLang; | 147 | theLang = parent->theLang; |
263 | 147 | theCountry = parent->theCountry; | 148 | theCountry = parent->theCountry; |
264 | 149 | theCalendar = parent->theCalendar; | ||
265 | 148 | } | 150 | } |
266 | 149 | } | 151 | } |
267 | 150 | 152 | ||
268 | 151 | 153 | ||
269 | === modified file 'src/context/dynamic_context.h' | |||
270 | --- src/context/dynamic_context.h 2013-03-12 17:03:31 +0000 | |||
271 | +++ src/context/dynamic_context.h 2013-03-21 16:00:34 +0000 | |||
272 | @@ -18,6 +18,7 @@ | |||
273 | 18 | #define ZORBA_DYNAMIC_CONTEXT_H | 18 | #define ZORBA_DYNAMIC_CONTEXT_H |
274 | 19 | 19 | ||
275 | 20 | #include <zorba/external_function_parameter.h> | 20 | #include <zorba/external_function_parameter.h> |
276 | 21 | #include <zorba/time.h> | ||
277 | 21 | 22 | ||
278 | 22 | #include "zorbautils/hashmap_zstring.h" | 23 | #include "zorbautils/hashmap_zstring.h" |
279 | 23 | #include "zorbautils/hashmap_itemp.h" | 24 | #include "zorbautils/hashmap_itemp.h" |
280 | @@ -141,6 +142,7 @@ | |||
281 | 141 | 142 | ||
282 | 142 | locale::iso639_1::type theLang; | 143 | locale::iso639_1::type theLang; |
283 | 143 | locale::iso3166_1::type theCountry; | 144 | locale::iso3166_1::type theCountry; |
284 | 145 | time::calendar::type theCalendar; | ||
285 | 144 | 146 | ||
286 | 145 | public: | 147 | public: |
287 | 146 | double theDocLoadingUserTime; | 148 | double theDocLoadingUserTime; |
288 | @@ -189,6 +191,14 @@ | |||
289 | 189 | *country = theCountry; | 191 | *country = theCountry; |
290 | 190 | } | 192 | } |
291 | 191 | 193 | ||
292 | 194 | void set_calendar( time::calendar::type calendar ) { | ||
293 | 195 | theCalendar = calendar; | ||
294 | 196 | } | ||
295 | 197 | |||
296 | 198 | time::calendar::type get_calendar() const { | ||
297 | 199 | return theCalendar; | ||
298 | 200 | } | ||
299 | 201 | |||
300 | 192 | const std::vector<VarValue>& get_variables() const { return theVarValues; } | 202 | const std::vector<VarValue>& get_variables() const { return theVarValues; } |
301 | 193 | 203 | ||
302 | 194 | void add_variable(ulong varid, store::Item_t& value); | 204 | void add_variable(ulong varid, store::Item_t& value); |
303 | 195 | 205 | ||
304 | === modified file 'src/diagnostics/diagnostic_en.xml' | |||
305 | --- src/diagnostics/diagnostic_en.xml 2013-03-16 20:44:27 +0000 | |||
306 | +++ src/diagnostics/diagnostic_en.xml 2013-03-21 16:00:34 +0000 | |||
307 | @@ -1012,21 +1012,51 @@ | |||
308 | 1012 | <value>"$1": picture string does not satisfy format-number() function rules</value> | 1012 | <value>"$1": picture string does not satisfy format-number() function rules</value> |
309 | 1013 | </diagnostic> | 1013 | </diagnostic> |
310 | 1014 | 1014 | ||
312 | 1015 | <diagnostic code="XTDE1340"> | 1015 | <diagnostic code="FOFD1340"> |
313 | 1016 | <comment> | 1016 | <comment> |
316 | 1017 | It is a non-recoverable dynamic error if the syntax of the picture is | 1017 | It is a non-recoverable dynamic error if the syntax of the picture is |
317 | 1018 | incorrect. | 1018 | incorrect. |
318 | 1019 | </comment> | 1019 | </comment> |
320 | 1020 | <value>"$1": invalid picture string for date/time</value> | 1020 | <value>"$1": invalid picture string for date/time${: 2}</value> |
321 | 1021 | <entry key="BadComponent_3"> | ||
322 | 1022 | <value>'$3': invalid component specifier</value> | ||
323 | 1023 | </entry> | ||
324 | 1024 | <entry key="BadWidthModifier"> | ||
325 | 1025 | <value>invalid width modifier</value> | ||
326 | 1026 | </entry> | ||
327 | 1027 | <entry key="DigitNotSameFamily_34"> | ||
328 | 1028 | <value>"$3": digit not from same digit family as $4</value> | ||
329 | 1029 | </entry> | ||
330 | 1030 | <entry key="MultipleComponent_3"> | ||
331 | 1031 | <value>'$3': multiple component specifiers between []</value> | ||
332 | 1032 | </entry> | ||
333 | 1033 | <entry key="MustBeOneMandatoryDigit"> | ||
334 | 1034 | <value>there must be at least one mandatory-digit-sign</value> | ||
335 | 1035 | </entry> | ||
336 | 1036 | <entry key="NoComponent"> | ||
337 | 1037 | <value>component specifier expected between []</value> | ||
338 | 1038 | </entry> | ||
339 | 1039 | <entry key="NoAdjacentGroupSep_3"> | ||
340 | 1040 | <value>"$3": grouping separator must not be adjacent to others</value> | ||
341 | 1041 | </entry> | ||
342 | 1042 | <entry key="NoGroupSepAtStart_3"> | ||
343 | 1043 | <value>"$3": grouping separator illegal at start of decimal-digit-pattern</value> | ||
344 | 1044 | </entry> | ||
345 | 1045 | <entry key="NoGroupSepAtEnd_3"> | ||
346 | 1046 | <value>"$3": grouping separator illegal at end of decimal-digit-pattern</value> | ||
347 | 1047 | </entry> | ||
348 | 1048 | <entry key="NoOptDigitAfterMandatory"> | ||
349 | 1049 | <value>"#": optional-digit-sign must precede all mandatory-digit-signs</value> | ||
350 | 1050 | </entry> | ||
351 | 1021 | </diagnostic> | 1051 | </diagnostic> |
352 | 1022 | 1052 | ||
354 | 1023 | <diagnostic code="XTDE1350"> | 1053 | <diagnostic code="FOFD1350"> |
355 | 1024 | <comment> | 1054 | <comment> |
359 | 1025 | It is a non-recoverable dynamic error if a component specifier within the | 1055 | It is a non-recoverable dynamic error if a component specifier within |
360 | 1026 | picture refers to components that are not available in the given type of | 1056 | the picture refers to components that are not available in the given |
361 | 1027 | \c $value. | 1057 | type of $value. |
362 | 1028 | </comment> | 1058 | </comment> |
364 | 1029 | <value>component specifier not available</value> | 1059 | <value>"$1": component specifier not available</value> |
365 | 1030 | </diagnostic> | 1060 | </diagnostic> |
366 | 1031 | 1061 | ||
367 | 1032 | <!--////////// XQuery Full-Text Errors /////////////////////////////////--> | 1062 | <!--////////// XQuery Full-Text Errors /////////////////////////////////--> |
368 | 1033 | 1063 | ||
369 | === modified file 'src/diagnostics/pregenerated/diagnostic_list.cpp' | |||
370 | --- src/diagnostics/pregenerated/diagnostic_list.cpp 2013-03-06 10:37:33 +0000 | |||
371 | +++ src/diagnostics/pregenerated/diagnostic_list.cpp 2013-03-21 16:00:34 +0000 | |||
372 | @@ -271,10 +271,10 @@ | |||
373 | 271 | XQueryErrorCode XTDE1310( "XTDE1310" ); | 271 | XQueryErrorCode XTDE1310( "XTDE1310" ); |
374 | 272 | 272 | ||
375 | 273 | 273 | ||
380 | 274 | XQueryErrorCode XTDE1340( "XTDE1340" ); | 274 | XQueryErrorCode FOFD1340( "FOFD1340" ); |
381 | 275 | 275 | ||
382 | 276 | 276 | ||
383 | 277 | XQueryErrorCode XTDE1350( "XTDE1350" ); | 277 | XQueryErrorCode FOFD1350( "FOFD1350" ); |
384 | 278 | 278 | ||
385 | 279 | 279 | ||
386 | 280 | #if !defined(ZORBA_NO_FULL_TEXT) | 280 | #if !defined(ZORBA_NO_FULL_TEXT) |
387 | 281 | 281 | ||
388 | === modified file 'src/diagnostics/pregenerated/dict_en.cpp' | |||
389 | --- src/diagnostics/pregenerated/dict_en.cpp 2013-03-16 20:44:27 +0000 | |||
390 | +++ src/diagnostics/pregenerated/dict_en.cpp 2013-03-21 16:00:34 +0000 | |||
391 | @@ -53,6 +53,8 @@ | |||
392 | 53 | { "FODT0002", "overflow/underflow in duration operation" }, | 53 | { "FODT0002", "overflow/underflow in duration operation" }, |
393 | 54 | { "FODT0003", "\"$1\": invalid timezone value (in seconds)" }, | 54 | { "FODT0003", "\"$1\": invalid timezone value (in seconds)" }, |
394 | 55 | { "FOER0000", "unidentifier error" }, | 55 | { "FOER0000", "unidentifier error" }, |
395 | 56 | { "FOFD1340", "\"$1\": invalid picture string for date/time${: 2}" }, | ||
396 | 57 | { "FOFD1350", "\"$1\": component specifier not available" }, | ||
397 | 56 | { "FOFI0001", "\"$1\": not castable to xs:language" }, | 58 | { "FOFI0001", "\"$1\": not castable to xs:language" }, |
398 | 57 | { "FOFI0002", "invalid argument in format-integer: $1" }, | 59 | { "FOFI0002", "invalid argument in format-integer: $1" }, |
399 | 58 | { "FONS0004", "\"$1\": no namespace found for prefix" }, | 60 | { "FONS0004", "\"$1\": no namespace found for prefix" }, |
400 | @@ -270,8 +272,6 @@ | |||
401 | 270 | { "XSST0009", "\"break loop\" statement not inside while statement" }, | 272 | { "XSST0009", "\"break loop\" statement not inside while statement" }, |
402 | 271 | { "XSST0010", "\"continue loop\" statement not inside while statement" }, | 273 | { "XSST0010", "\"continue loop\" statement not inside while statement" }, |
403 | 272 | { "XTDE1310", "\"$1\": picture string does not satisfy format-number() function rules" }, | 274 | { "XTDE1310", "\"$1\": picture string does not satisfy format-number() function rules" }, |
404 | 273 | { "XTDE1340", "\"$1\": invalid picture string for date/time" }, | ||
405 | 274 | { "XTDE1350", "component specifier not available" }, | ||
406 | 275 | { "XUDY0009", "node has no parent in \"replace\" expression (without \"value of\")" }, | 275 | { "XUDY0009", "node has no parent in \"replace\" expression (without \"value of\")" }, |
407 | 276 | { "XUDY0014", "\"modify\" can not modify node not created by \"copy\"" }, | 276 | { "XUDY0014", "\"modify\" can not modify node not created by \"copy\"" }, |
408 | 277 | { "XUDY0015", "node is target of multiple \"rename\" expressions in same query" }, | 277 | { "XUDY0015", "node is target of multiple \"rename\" expressions in same query" }, |
409 | @@ -613,6 +613,16 @@ | |||
410 | 613 | { "~FOCA0002_BadLexicalQName_2", "\"$2\": value is not a valid lexical QName" }, | 613 | { "~FOCA0002_BadLexicalQName_2", "\"$2\": value is not a valid lexical QName" }, |
411 | 614 | { "~FOCA0002_NoCastTo_234", "\"$2\": value of type $3 is not castable to type $4" }, | 614 | { "~FOCA0002_NoCastTo_234", "\"$2\": value of type $3 is not castable to type $4" }, |
412 | 615 | { "~FOCA0002_NoURIforPrefix_2", "no namespace URI provided for prefix in lexical QName \"$2\"" }, | 615 | { "~FOCA0002_NoURIforPrefix_2", "no namespace URI provided for prefix in lexical QName \"$2\"" }, |
413 | 616 | { "~FOFD1340_BadComponent_3", "'$3': invalid component specifier" }, | ||
414 | 617 | { "~FOFD1340_BadWidthModifier", "invalid width modifier" }, | ||
415 | 618 | { "~FOFD1340_DigitNotSameFamily_34", "\"$3\": digit not from same digit family as $4" }, | ||
416 | 619 | { "~FOFD1340_MultipleComponent_3", "'$3': multiple component specifiers between []" }, | ||
417 | 620 | { "~FOFD1340_MustBeOneMandatoryDigit", "there must be at least one mandatory-digit-sign" }, | ||
418 | 621 | { "~FOFD1340_NoAdjacentGroupSep_3", "\"$3\": grouping separator must not be adjacent to others" }, | ||
419 | 622 | { "~FOFD1340_NoComponent", "component specifier expected between []" }, | ||
420 | 623 | { "~FOFD1340_NoGroupSepAtEnd_3", "\"$3\": grouping separator illegal at end of decimal-digit-pattern" }, | ||
421 | 624 | { "~FOFD1340_NoGroupSepAtStart_3", "\"$3\": grouping separator illegal at start of decimal-digit-pattern" }, | ||
422 | 625 | { "~FOFD1340_NoOptDigitAfterMandatory", "\"#\": optional-digit-sign must precede all mandatory-digit-signs" }, | ||
423 | 616 | { "~FORG0001_BadHexDigit_2", "'$2': invalid hexedecimal digit" }, | 626 | { "~FORG0001_BadHexDigit_2", "'$2': invalid hexedecimal digit" }, |
424 | 617 | { "~FORG0001_Base64BadChar_2", "'$2': invalid Base64 character" }, | 627 | { "~FORG0001_Base64BadChar_2", "'$2': invalid Base64 character" }, |
425 | 618 | { "~FORG0001_Base64Multiple4", "Base64 data must be a multiple of 4 bytes" }, | 628 | { "~FORG0001_Base64Multiple4", "Base64 data must be a multiple of 4 bytes" }, |
426 | 619 | 629 | ||
427 | === modified file 'src/diagnostics/pregenerated/dict_zed_keys.h' | |||
428 | --- src/diagnostics/pregenerated/dict_zed_keys.h 2013-03-16 20:44:27 +0000 | |||
429 | +++ src/diagnostics/pregenerated/dict_zed_keys.h 2013-03-21 16:00:34 +0000 | |||
430 | @@ -63,6 +63,16 @@ | |||
431 | 63 | #define ZED_XQDY0074_NotCastToQName "~XQDY0074_NotCastToQName" | 63 | #define ZED_XQDY0074_NotCastToQName "~XQDY0074_NotCastToQName" |
432 | 64 | #define ZED_XQDY0074_NoEmptyLocalname "~XQDY0074_NoEmptyLocalname" | 64 | #define ZED_XQDY0074_NoEmptyLocalname "~XQDY0074_NoEmptyLocalname" |
433 | 65 | #define ZED_XQDY0074_NameSapceConstructor "~XQDY0074_NameSapceConstructor" | 65 | #define ZED_XQDY0074_NameSapceConstructor "~XQDY0074_NameSapceConstructor" |
434 | 66 | #define ZED_FOFD1340_BadComponent_3 "~FOFD1340_BadComponent_3" | ||
435 | 67 | #define ZED_FOFD1340_BadWidthModifier "~FOFD1340_BadWidthModifier" | ||
436 | 68 | #define ZED_FOFD1340_DigitNotSameFamily_34 "~FOFD1340_DigitNotSameFamily_34" | ||
437 | 69 | #define ZED_FOFD1340_MultipleComponent_3 "~FOFD1340_MultipleComponent_3" | ||
438 | 70 | #define ZED_FOFD1340_MustBeOneMandatoryDigit "~FOFD1340_MustBeOneMandatoryDigit" | ||
439 | 71 | #define ZED_FOFD1340_NoComponent "~FOFD1340_NoComponent" | ||
440 | 72 | #define ZED_FOFD1340_NoAdjacentGroupSep_3 "~FOFD1340_NoAdjacentGroupSep_3" | ||
441 | 73 | #define ZED_FOFD1340_NoGroupSepAtStart_3 "~FOFD1340_NoGroupSepAtStart_3" | ||
442 | 74 | #define ZED_FOFD1340_NoGroupSepAtEnd_3 "~FOFD1340_NoGroupSepAtEnd_3" | ||
443 | 75 | #define ZED_FOFD1340_NoOptDigitAfterMandatory "~FOFD1340_NoOptDigitAfterMandatory" | ||
444 | 66 | #define ZED_FTST0009_BadStopWordsLang "~FTST0009_BadStopWordsLang" | 76 | #define ZED_FTST0009_BadStopWordsLang "~FTST0009_BadStopWordsLang" |
445 | 67 | #define ZED_FTST0009_BadStemmerLang "~FTST0009_BadStemmerLang" | 77 | #define ZED_FTST0009_BadStemmerLang "~FTST0009_BadStemmerLang" |
446 | 68 | #define ZED_FTST0009_BadThesaurusLang "~FTST0009_BadThesaurusLang" | 78 | #define ZED_FTST0009_BadThesaurusLang "~FTST0009_BadThesaurusLang" |
447 | 69 | 79 | ||
448 | === modified file 'src/functions/func_durations_dates_times_impl.cpp' | |||
449 | --- src/functions/func_durations_dates_times_impl.cpp 2013-02-07 17:24:36 +0000 | |||
450 | +++ src/functions/func_durations_dates_times_impl.cpp 2013-03-21 16:00:34 +0000 | |||
451 | @@ -19,6 +19,7 @@ | |||
452 | 19 | #include "functions/function_impl.h" | 19 | #include "functions/function_impl.h" |
453 | 20 | 20 | ||
454 | 21 | #include "runtime/durations_dates_times/DurationsDatesTimesImpl.h" | 21 | #include "runtime/durations_dates_times/DurationsDatesTimesImpl.h" |
455 | 22 | #include "runtime/durations_dates_times/format_dateTime.h" | ||
456 | 22 | #include "runtime/numerics/NumericsImpl.h" | 23 | #include "runtime/numerics/NumericsImpl.h" |
457 | 23 | #include "runtime/core/arithmetic_impl.h" | 24 | #include "runtime/core/arithmetic_impl.h" |
458 | 24 | #include "zorbamisc/ns_consts.h" | 25 | #include "zorbamisc/ns_consts.h" |
459 | 25 | 26 | ||
460 | === modified file 'src/runtime/CMakeLists.txt' | |||
461 | --- src/runtime/CMakeLists.txt 2013-02-07 17:24:36 +0000 | |||
462 | +++ src/runtime/CMakeLists.txt 2013-03-21 16:00:34 +0000 | |||
463 | @@ -125,6 +125,7 @@ | |||
464 | 125 | core/gflwor/outerfor_iterator.cpp | 125 | core/gflwor/outerfor_iterator.cpp |
465 | 126 | core/internal_operators.cpp | 126 | core/internal_operators.cpp |
466 | 127 | durations_dates_times/DurationsDatesTimesImpl.cpp | 127 | durations_dates_times/DurationsDatesTimesImpl.cpp |
467 | 128 | durations_dates_times/format_dateTime.cpp | ||
468 | 128 | indexing/doc_indexer.cpp | 129 | indexing/doc_indexer.cpp |
469 | 129 | indexing/index_ddl.cpp | 130 | indexing/index_ddl.cpp |
470 | 130 | json/common.cpp | 131 | json/common.cpp |
471 | 131 | 132 | ||
472 | === modified file 'src/runtime/durations_dates_times/DurationsDatesTimesImpl.cpp' | |||
473 | --- src/runtime/durations_dates_times/DurationsDatesTimesImpl.cpp 2013-02-28 11:15:32 +0000 | |||
474 | +++ src/runtime/durations_dates_times/DurationsDatesTimesImpl.cpp 2013-03-21 16:00:34 +0000 | |||
475 | @@ -45,8 +45,6 @@ | |||
476 | 45 | { | 45 | { |
477 | 46 | SERIALIZABLE_CLASS_VERSIONS(FnDateTimeConstructorIterator) | 46 | SERIALIZABLE_CLASS_VERSIONS(FnDateTimeConstructorIterator) |
478 | 47 | 47 | ||
479 | 48 | SERIALIZABLE_CLASS_VERSIONS(FnFormatDateTimeIterator) | ||
480 | 49 | |||
481 | 50 | SERIALIZABLE_CLASS_VERSIONS(FnAdjustToTimeZoneIterator_1) | 48 | SERIALIZABLE_CLASS_VERSIONS(FnAdjustToTimeZoneIterator_1) |
482 | 51 | 49 | ||
483 | 52 | SERIALIZABLE_CLASS_VERSIONS(FnAdjustToTimeZoneIterator_2) | 50 | SERIALIZABLE_CLASS_VERSIONS(FnAdjustToTimeZoneIterator_2) |
484 | @@ -54,19 +52,11 @@ | |||
485 | 54 | 52 | ||
486 | 55 | BINARY_ACCEPT(FnDateTimeConstructorIterator); | 53 | BINARY_ACCEPT(FnDateTimeConstructorIterator); |
487 | 56 | 54 | ||
488 | 57 | NARY_ACCEPT(FnFormatDateTimeIterator); | ||
489 | 58 | |||
490 | 59 | UNARY_ACCEPT(FnAdjustToTimeZoneIterator_1); | 55 | UNARY_ACCEPT(FnAdjustToTimeZoneIterator_1); |
491 | 60 | 56 | ||
492 | 61 | BINARY_ACCEPT(FnAdjustToTimeZoneIterator_2); | 57 | BINARY_ACCEPT(FnAdjustToTimeZoneIterator_2); |
493 | 62 | 58 | ||
494 | 63 | 59 | ||
495 | 64 | static void skip_whitespace(zstring& str, ascii::size_type& position, int delta = 0) | ||
496 | 65 | { | ||
497 | 66 | while (position+delta < str.size() && ascii::is_space(str[position+delta])) | ||
498 | 67 | position++; | ||
499 | 68 | } | ||
500 | 69 | |||
501 | 70 | bool FnDateTimeConstructorIterator::nextImpl(store::Item_t& result, PlanState& planState) const | 60 | bool FnDateTimeConstructorIterator::nextImpl(store::Item_t& result, PlanState& planState) const |
502 | 71 | { | 61 | { |
503 | 72 | store::Item_t item0; | 62 | store::Item_t item0; |
504 | @@ -199,555 +189,5 @@ | |||
505 | 199 | STACK_END(state); | 189 | STACK_END(state); |
506 | 200 | } | 190 | } |
507 | 201 | 191 | ||
508 | 202 | |||
509 | 203 | /** | ||
510 | 204 | *______________________________________________________________________ | ||
511 | 205 | * | ||
512 | 206 | * fn:format-dateTime() | ||
513 | 207 | * | ||
514 | 208 | *_______________________________________________________________________*/ | ||
515 | 209 | |||
516 | 210 | class Modifier | ||
517 | 211 | { | ||
518 | 212 | public: | ||
519 | 213 | zstring presentation_modifier; | ||
520 | 214 | zstring second_modifier; | ||
521 | 215 | |||
522 | 216 | // for min_width and max_width | ||
523 | 217 | // -3 means an error in the picture | ||
524 | 218 | // -2 means width modifiers are not specified | ||
525 | 219 | // -1 means '*' | ||
526 | 220 | // >=0 means explicitly specified width | ||
527 | 221 | long min_width_modifier; | ||
528 | 222 | long max_width_modifier; | ||
529 | 223 | |||
530 | 224 | Modifier() | ||
531 | 225 | : | ||
532 | 226 | presentation_modifier(""), | ||
533 | 227 | second_modifier(""), | ||
534 | 228 | min_width_modifier(-2), | ||
535 | 229 | max_width_modifier(-2) | ||
536 | 230 | { | ||
537 | 231 | }; | ||
538 | 232 | }; | ||
539 | 233 | |||
540 | 234 | |||
541 | 235 | static void format_number(zstring& str, long number, Modifier& modifier) | ||
542 | 236 | { | ||
543 | 237 | // Presentation modifier can be: | ||
544 | 238 | // 'Ww', "Nn', 'W', 'w', 'N', 'n' | ||
545 | 239 | // 'i', 'I', '1', '00...01' | ||
546 | 240 | // the modifier will not be checked if it is supported or not | ||
547 | 241 | zstring temp; | ||
548 | 242 | |||
549 | 243 | if (modifier.presentation_modifier.size() > 0 && modifier.presentation_modifier[0] == '0') | ||
550 | 244 | { | ||
551 | 245 | ztd::to_string(number, &temp); | ||
552 | 246 | while (temp.size() < modifier.presentation_modifier.size()) | ||
553 | 247 | temp = "0" + temp; | ||
554 | 248 | } | ||
555 | 249 | else // "1" or fallback | ||
556 | 250 | { | ||
557 | 251 | ztd::to_string(number, &temp); | ||
558 | 252 | } | ||
559 | 253 | |||
560 | 254 | if (modifier.second_modifier == "o") | ||
561 | 255 | { | ||
562 | 256 | if ((number % 10) == 1 && (number % 100) != 11) | ||
563 | 257 | temp.append("st"); | ||
564 | 258 | else if ((number % 10) == 2 && (number % 100) != 12) | ||
565 | 259 | temp.append("nd"); | ||
566 | 260 | else if ((number % 10) == 3 && (number % 100) != 13) | ||
567 | 261 | temp.append("rd"); | ||
568 | 262 | else | ||
569 | 263 | temp.append("th"); | ||
570 | 264 | } | ||
571 | 265 | |||
572 | 266 | if (modifier.min_width_modifier >= 0) | ||
573 | 267 | while (temp.size() < (unsigned int)modifier.min_width_modifier) | ||
574 | 268 | temp = "0" + temp; | ||
575 | 269 | |||
576 | 270 | str.append(temp.c_str()); | ||
577 | 271 | } | ||
578 | 272 | |||
579 | 273 | |||
580 | 274 | static void format_string_width( | ||
581 | 275 | zstring& destination, | ||
582 | 276 | zstring& source, | ||
583 | 277 | Modifier& modifier) | ||
584 | 278 | { | ||
585 | 279 | zstring temp = source; | ||
586 | 280 | while (modifier.max_width_modifier > 0 && temp.size() < (unsigned int)modifier.max_width_modifier) | ||
587 | 281 | temp.append(" "); | ||
588 | 282 | destination.append(temp.c_str()); | ||
589 | 283 | } | ||
590 | 284 | |||
591 | 285 | |||
592 | 286 | static bool format_string( | ||
593 | 287 | zstring& destination, | ||
594 | 288 | zstring& source, | ||
595 | 289 | Modifier& modifier) | ||
596 | 290 | { | ||
597 | 291 | zstring temp; | ||
598 | 292 | if (modifier.presentation_modifier == "n") | ||
599 | 293 | { | ||
600 | 294 | zstring newcase = source; | ||
601 | 295 | ascii::to_lower(newcase); | ||
602 | 296 | temp.append(newcase); | ||
603 | 297 | } | ||
604 | 298 | else if (modifier.presentation_modifier == "N") | ||
605 | 299 | { | ||
606 | 300 | zstring newcase = source; | ||
607 | 301 | ascii::to_upper(newcase); | ||
608 | 302 | temp.append(newcase); | ||
609 | 303 | } | ||
610 | 304 | else if (modifier.presentation_modifier == "Nn") | ||
611 | 305 | { | ||
612 | 306 | zstring newcase; | ||
613 | 307 | |||
614 | 308 | newcase = source.substr(0, 1); | ||
615 | 309 | ascii::to_upper(newcase); | ||
616 | 310 | temp.append(newcase); | ||
617 | 311 | |||
618 | 312 | newcase = source.substr(1,source.size()-1); | ||
619 | 313 | ascii::to_lower(newcase); | ||
620 | 314 | temp.append(newcase); | ||
621 | 315 | } | ||
622 | 316 | else | ||
623 | 317 | return false; | ||
624 | 318 | |||
625 | 319 | format_string_width(destination, temp, modifier); | ||
626 | 320 | return true; | ||
627 | 321 | } | ||
628 | 322 | |||
629 | 323 | |||
630 | 324 | static bool format_string( | ||
631 | 325 | zstring& destination, | ||
632 | 326 | const char* source, | ||
633 | 327 | Modifier& modifier) | ||
634 | 328 | { | ||
635 | 329 | zstring temp(source); | ||
636 | 330 | return format_string(destination, temp, modifier); | ||
637 | 331 | } | ||
638 | 332 | |||
639 | 333 | |||
640 | 334 | static void format_component( | ||
641 | 335 | zstring& destination, | ||
642 | 336 | long number, | ||
643 | 337 | zstring& source, | ||
644 | 338 | Modifier& modifier) | ||
645 | 339 | { | ||
646 | 340 | if (!format_string(destination, source, modifier)) | ||
647 | 341 | format_number(destination, number, modifier); | ||
648 | 342 | } | ||
649 | 343 | |||
650 | 344 | |||
651 | 345 | static void output_year( | ||
652 | 346 | zstring& destination, | ||
653 | 347 | long number, | ||
654 | 348 | Modifier& modifier) | ||
655 | 349 | { | ||
656 | 350 | format_number(destination, number, modifier); | ||
657 | 351 | |||
658 | 352 | if (modifier.max_width_modifier >= 0) | ||
659 | 353 | { | ||
660 | 354 | if ((unsigned int)modifier.max_width_modifier > destination.size()) | ||
661 | 355 | modifier.max_width_modifier = destination.size(); | ||
662 | 356 | |||
663 | 357 | destination = destination.substr(destination.size() - modifier.max_width_modifier, modifier.max_width_modifier); | ||
664 | 358 | } | ||
665 | 359 | } | ||
666 | 360 | |||
667 | 361 | |||
668 | 362 | static void output_month( | ||
669 | 363 | zstring& destination, | ||
670 | 364 | long number, | ||
671 | 365 | Modifier& modifier) | ||
672 | 366 | { | ||
673 | 367 | static const char* month[12] = { "january", "february", "march", "april", "may", "june", "july", "august", "september", "october", "november", "december"}; | ||
674 | 368 | zstring temp(month[number-1]); | ||
675 | 369 | if (modifier.max_width_modifier > 0 && (unsigned int)modifier.max_width_modifier < temp.size()) | ||
676 | 370 | temp = temp.substr(0, modifier.max_width_modifier); | ||
677 | 371 | |||
678 | 372 | format_component(destination, number, temp, modifier); | ||
679 | 373 | } | ||
680 | 374 | |||
681 | 375 | |||
682 | 376 | static void output_day_of_week( | ||
683 | 377 | zstring& destination, | ||
684 | 378 | long number, | ||
685 | 379 | Modifier& modifier) | ||
686 | 380 | { | ||
687 | 381 | static const char* day[7] = { "sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday"}; | ||
688 | 382 | zstring temp(day[number]); | ||
689 | 383 | if (modifier.max_width_modifier > 0 && (unsigned int)modifier.max_width_modifier < temp.size()) | ||
690 | 384 | temp = temp.substr(0, modifier.max_width_modifier); | ||
691 | 385 | |||
692 | 386 | if (modifier.presentation_modifier.size() == 0) | ||
693 | 387 | modifier.presentation_modifier = "n"; // Default for day of week is "n" | ||
694 | 388 | |||
695 | 389 | format_component(destination, number, temp, modifier); | ||
696 | 390 | } | ||
697 | 391 | |||
698 | 392 | |||
699 | 393 | static void parse_presentation_modifier( | ||
700 | 394 | zstring& str, | ||
701 | 395 | ascii::size_type& position, | ||
702 | 396 | zstring& result) | ||
703 | 397 | { | ||
704 | 398 | result = ""; | ||
705 | 399 | |||
706 | 400 | skip_whitespace(str, position, 1); | ||
707 | 401 | |||
708 | 402 | if (position+1 >= str.size()) | ||
709 | 403 | return; | ||
710 | 404 | |||
711 | 405 | zstring modifier = ""; | ||
712 | 406 | |||
713 | 407 | if (str[position+1] == '1' || str[position+1] == 'i' || str[position+1] == 'I' | ||
714 | 408 | || str[position+1] == 'a' || str[position+1] == 'A' | ||
715 | 409 | || str[position+1] == 'w' || str[position+1] == 'W' | ||
716 | 410 | || str[position+1] == 'n' || str[position+1] == 'N' ) | ||
717 | 411 | { | ||
718 | 412 | modifier.append(str, position+1, 1); | ||
719 | 413 | position++; | ||
720 | 414 | |||
721 | 415 | skip_whitespace(str, position, 1); | ||
722 | 416 | |||
723 | 417 | if (position+1 < str.size() && | ||
724 | 418 | ((modifier[0] == 'W' && str[position+1] == 'w') | ||
725 | 419 | || | ||
726 | 420 | (modifier[0] == 'N' && str[position+1] == 'n'))) | ||
727 | 421 | { | ||
728 | 422 | modifier.append(str, position+1, 1); | ||
729 | 423 | position++; | ||
730 | 424 | } | ||
731 | 425 | } | ||
732 | 426 | else if (str[position+1] == '0') | ||
733 | 427 | { | ||
734 | 428 | ascii::size_type start = position; | ||
735 | 429 | while (position+1 < str.size() && (str[position+1] == '0' || ascii::is_space(str[position+1]))) | ||
736 | 430 | { | ||
737 | 431 | if (str[position+1] == '0') | ||
738 | 432 | modifier.append(str, position+1, 1); | ||
739 | 433 | position++; | ||
740 | 434 | } | ||
741 | 435 | |||
742 | 436 | if (position+1 >= str.size() || str[position+1] != '1') | ||
743 | 437 | { | ||
744 | 438 | position = start; | ||
745 | 439 | return; | ||
746 | 440 | } | ||
747 | 441 | |||
748 | 442 | modifier.append(str, position+1, 1); | ||
749 | 443 | position++; | ||
750 | 444 | } | ||
751 | 445 | |||
752 | 446 | result = modifier; | ||
753 | 447 | } | ||
754 | 448 | |||
755 | 449 | |||
756 | 450 | static void parse_second_modifier( | ||
757 | 451 | zstring& str, | ||
758 | 452 | ascii::size_type& position, | ||
759 | 453 | zstring& result) | ||
760 | 454 | { | ||
761 | 455 | result = ""; | ||
762 | 456 | |||
763 | 457 | skip_whitespace(str, position, 1); | ||
764 | 458 | |||
765 | 459 | if (position+1 >= str.size()) | ||
766 | 460 | return; | ||
767 | 461 | |||
768 | 462 | position++; | ||
769 | 463 | if (str[position] == 't') | ||
770 | 464 | result = "t"; | ||
771 | 465 | else if (str[position] == 'o') | ||
772 | 466 | result = "o"; | ||
773 | 467 | else | ||
774 | 468 | position--; | ||
775 | 469 | } | ||
776 | 470 | |||
777 | 471 | |||
778 | 472 | // for min_width and max_width | ||
779 | 473 | // -3 means an error in the picture | ||
780 | 474 | // -2 means width modifiers are not specified | ||
781 | 475 | // -1 means '*' | ||
782 | 476 | // >=0 means explicitly specified width | ||
783 | 477 | static void parse_width_modifier( | ||
784 | 478 | zstring& str, | ||
785 | 479 | ascii::size_type& position, | ||
786 | 480 | long& min_width, | ||
787 | 481 | long& max_width) | ||
788 | 482 | { | ||
789 | 483 | min_width = -2; | ||
790 | 484 | max_width = -2; | ||
791 | 485 | |||
792 | 486 | skip_whitespace(str, position, 1); | ||
793 | 487 | |||
794 | 488 | if (position+1 >= str.size() || str[position+1] != ',') | ||
795 | 489 | return; | ||
796 | 490 | |||
797 | 491 | position++; | ||
798 | 492 | skip_whitespace(str, position, 1); | ||
799 | 493 | |||
800 | 494 | // The min_width must be present if there is a comma symbol | ||
801 | 495 | min_width = -3; | ||
802 | 496 | if (position+1 >= str.size()) | ||
803 | 497 | return; | ||
804 | 498 | |||
805 | 499 | if (str[position+1] == '*') | ||
806 | 500 | { | ||
807 | 501 | min_width = -1; | ||
808 | 502 | position++; | ||
809 | 503 | } | ||
810 | 504 | else | ||
811 | 505 | { | ||
812 | 506 | if (parse_long(str.data(), str.size(), position, min_width, -1, -1, 1)) | ||
813 | 507 | min_width = -3; | ||
814 | 508 | } | ||
815 | 509 | |||
816 | 510 | skip_whitespace(str, position, 1); | ||
817 | 511 | |||
818 | 512 | if (position+1 >= str.size() || str[position+1] != '-') | ||
819 | 513 | return; | ||
820 | 514 | |||
821 | 515 | position++; | ||
822 | 516 | skip_whitespace(str, position, 1); | ||
823 | 517 | |||
824 | 518 | if (position+1 < str.size() && str[position+1] == '*') | ||
825 | 519 | { | ||
826 | 520 | max_width = -1; | ||
827 | 521 | position++; | ||
828 | 522 | } | ||
829 | 523 | else | ||
830 | 524 | { | ||
831 | 525 | if (parse_long(str.data(), str.size(), position, max_width, -1, -1, 1)) | ||
832 | 526 | min_width = -3; | ||
833 | 527 | } | ||
834 | 528 | } | ||
835 | 529 | |||
836 | 530 | |||
837 | 531 | static int get_data_type(char component) | ||
838 | 532 | { | ||
839 | 533 | switch (component) | ||
840 | 534 | { | ||
841 | 535 | case 'Y': | ||
842 | 536 | return DateTime::YEAR_DATA; | ||
843 | 537 | case 'M': | ||
844 | 538 | return DateTime::MONTH_DATA; | ||
845 | 539 | case 'D': | ||
846 | 540 | return DateTime::DAY_DATA; | ||
847 | 541 | case 'd': // day in year | ||
848 | 542 | return DateTime::DAY_DATA; | ||
849 | 543 | case 'F': // day of week | ||
850 | 544 | return DateTime::DAY_DATA; | ||
851 | 545 | case 'W': // week in year | ||
852 | 546 | return DateTime::DAY_DATA; | ||
853 | 547 | case 'w': // week in month | ||
854 | 548 | return DateTime::DAY_DATA; | ||
855 | 549 | case 'H': // hour in day (24 hours) | ||
856 | 550 | return DateTime::HOUR_DATA; | ||
857 | 551 | case 'h': // hour in half-day (12 hours) | ||
858 | 552 | return DateTime::HOUR_DATA; | ||
859 | 553 | case 'P': // am/pm marker | ||
860 | 554 | return DateTime::HOUR_DATA; | ||
861 | 555 | case 'm': | ||
862 | 556 | return DateTime::MINUTE_DATA; | ||
863 | 557 | case 's': | ||
864 | 558 | return DateTime::SECONDS_DATA; | ||
865 | 559 | case 'f': // fractional seconds | ||
866 | 560 | return DateTime::FRACSECONDS_DATA; | ||
867 | 561 | case 'Z': // timezone as a time offset from UTC, or if an alphabetic modifier is present the conventional name of a timezone (such as PST) | ||
868 | 562 | return -1; | ||
869 | 563 | case 'z': // timezone as a time offset using GMT, for example GMT+1 | ||
870 | 564 | return -1; | ||
871 | 565 | case 'C': // calendar: the name or abbreviation of a calendar name | ||
872 | 566 | return -1; | ||
873 | 567 | case 'E': // era: the name of a baseline for the numbering of years, for example the reign of a monarch | ||
874 | 568 | return -1; | ||
875 | 569 | default: | ||
876 | 570 | return -1; | ||
877 | 571 | } | ||
878 | 572 | } | ||
879 | 573 | |||
880 | 574 | |||
881 | 575 | bool FnFormatDateTimeIterator::nextImpl( | ||
882 | 576 | store::Item_t& result, | ||
883 | 577 | PlanState& planState) const | ||
884 | 578 | { | ||
885 | 579 | bool variable_marker; | ||
886 | 580 | zstring pictureString, resultString; | ||
887 | 581 | store::Item_t dateTimeItem, picture; | ||
888 | 582 | PlanIteratorState* state; | ||
889 | 583 | DEFAULT_STACK_INIT(PlanIteratorState, state, planState); | ||
890 | 584 | |||
891 | 585 | if (!consumeNext(dateTimeItem, theChildren[0].getp(), planState)) | ||
892 | 586 | { | ||
893 | 587 | // Got void -- returning void | ||
894 | 588 | STACK_PUSH(false, state); | ||
895 | 589 | } | ||
896 | 590 | else | ||
897 | 591 | { | ||
898 | 592 | consumeNext(picture, theChildren[1].getp(), planState); | ||
899 | 593 | |||
900 | 594 | pictureString = picture->getStringValue().str(); | ||
901 | 595 | resultString = ""; | ||
902 | 596 | variable_marker = false; | ||
903 | 597 | |||
904 | 598 | for (ascii::size_type i = 0; i < pictureString.size(); i++) | ||
905 | 599 | { | ||
906 | 600 | if (!variable_marker) | ||
907 | 601 | { | ||
908 | 602 | if (pictureString[i] == '[') | ||
909 | 603 | { | ||
910 | 604 | // check for quoted "[[" | ||
911 | 605 | if (i<pictureString.size()-1 && pictureString[i+1] == '[') | ||
912 | 606 | i++; | ||
913 | 607 | else | ||
914 | 608 | { | ||
915 | 609 | variable_marker = true; | ||
916 | 610 | continue; | ||
917 | 611 | } | ||
918 | 612 | } | ||
919 | 613 | else if (pictureString[i] == ']') | ||
920 | 614 | { | ||
921 | 615 | // check for quoted "]]" | ||
922 | 616 | if (i<pictureString.size()-1 && pictureString[i+1] == ']') | ||
923 | 617 | i++; | ||
924 | 618 | } | ||
925 | 619 | |||
926 | 620 | resultString.append(pictureString, i, 1); | ||
927 | 621 | } | ||
928 | 622 | else // variable_marker == true | ||
929 | 623 | { | ||
930 | 624 | char component = 0; | ||
931 | 625 | Modifier modifier; | ||
932 | 626 | |||
933 | 627 | switch (pictureString[i]) | ||
934 | 628 | { | ||
935 | 629 | case 'Y': case 'M': case 'D': case 'd': case 'F': case 'W': case 'w': | ||
936 | 630 | case 'H': case 'h': case 'P': case 'm': case 's': case 'f': | ||
937 | 631 | case 'Z': case 'z': case 'C': case 'E': | ||
938 | 632 | component = pictureString[i]; | ||
939 | 633 | break; | ||
940 | 634 | |||
941 | 635 | case ' ': case '\f': case '\n': case '\r': case '\t': case '\v': | ||
942 | 636 | continue; // ignore whitespace | ||
943 | 637 | break; | ||
944 | 638 | |||
945 | 639 | case ']': | ||
946 | 640 | variable_marker = false; | ||
947 | 641 | break; | ||
948 | 642 | |||
949 | 643 | default: | ||
950 | 644 | throw XQUERY_EXCEPTION( | ||
951 | 645 | err::XTDE1340, ERROR_PARAMS( pictureString ), ERROR_LOC( loc ) | ||
952 | 646 | ); | ||
953 | 647 | } | ||
954 | 648 | |||
955 | 649 | if (variable_marker == false) | ||
956 | 650 | continue; | ||
957 | 651 | |||
958 | 652 | parse_presentation_modifier(pictureString, i, modifier.presentation_modifier); | ||
959 | 653 | |||
960 | 654 | parse_second_modifier(pictureString, i, modifier.second_modifier); | ||
961 | 655 | |||
962 | 656 | parse_width_modifier(pictureString, | ||
963 | 657 | i, | ||
964 | 658 | modifier.min_width_modifier, | ||
965 | 659 | modifier.max_width_modifier); | ||
966 | 660 | |||
967 | 661 | // min_width_modifier is -3, there was an error in the picture | ||
968 | 662 | if (modifier.min_width_modifier == -3) | ||
969 | 663 | throw XQUERY_EXCEPTION( | ||
970 | 664 | err::XTDE1340, ERROR_PARAMS( pictureString ), ERROR_LOC( loc ) | ||
971 | 665 | ); | ||
972 | 666 | |||
973 | 667 | int data_type = get_data_type(component); | ||
974 | 668 | if (data_type != -1 && (!DateTime::FACET_MEMBERS[facet_type][data_type])) | ||
975 | 669 | throw XQUERY_EXCEPTION(err::XTDE1350, ERROR_LOC(loc)); | ||
976 | 670 | |||
977 | 671 | switch (component) | ||
978 | 672 | { | ||
979 | 673 | case 'Y': | ||
980 | 674 | output_year(resultString, std::abs(dateTimeItem->getDateTimeValue().getYear()), modifier); | ||
981 | 675 | break; | ||
982 | 676 | case 'M': | ||
983 | 677 | output_month(resultString, dateTimeItem->getDateTimeValue().getMonth(), modifier); | ||
984 | 678 | break; | ||
985 | 679 | case 'D': | ||
986 | 680 | format_number(resultString, dateTimeItem->getDateTimeValue().getDay(), modifier); | ||
987 | 681 | break; | ||
988 | 682 | case 'd': // day in year | ||
989 | 683 | format_number(resultString, dateTimeItem->getDateTimeValue().getDayOfYear(), modifier); | ||
990 | 684 | break; | ||
991 | 685 | case 'F': // day of week | ||
992 | 686 | output_day_of_week(resultString, dateTimeItem->getDateTimeValue().getDayOfWeek(), modifier); | ||
993 | 687 | break; | ||
994 | 688 | case 'W': // week in year | ||
995 | 689 | format_number(resultString, dateTimeItem->getDateTimeValue().getWeekInYear(), modifier); | ||
996 | 690 | break; | ||
997 | 691 | case 'w': // week in month | ||
998 | 692 | format_number(resultString, dateTimeItem->getDateTimeValue().getWeekInMonth(), modifier); | ||
999 | 693 | break; | ||
1000 | 694 | case 'H': // hour in day (24 hours) | ||
1001 | 695 | format_number(resultString, dateTimeItem->getDateTimeValue().getHours(), modifier); | ||
1002 | 696 | break; | ||
1003 | 697 | case 'h': // hour in half-day (12 hours) | ||
1004 | 698 | // Convert hour from: 0 1 ... 12 13 ... 23 0 | ||
1005 | 699 | // to: 12 1 ... 12 1 ... 11 12 | ||
1006 | 700 | format_number(resultString, 1 + (11 + dateTimeItem->getDateTimeValue().getHours()) % 12, | ||
1007 | 701 | modifier); | ||
1008 | 702 | break; | ||
1009 | 703 | case 'P': // am/pm marker | ||
1010 | 704 | if (modifier.presentation_modifier.empty()) | ||
1011 | 705 | modifier.presentation_modifier = "n"; // Default for the AM/PM marker is "n" | ||
1012 | 706 | format_string(resultString, dateTimeItem->getDateTimeValue().getHours() >= 12 ? "pm" : "am", modifier); | ||
1013 | 707 | break; | ||
1014 | 708 | case 'm': | ||
1015 | 709 | if (modifier.presentation_modifier.empty()) | ||
1016 | 710 | modifier.presentation_modifier.append("01"); | ||
1017 | 711 | format_number(resultString, dateTimeItem->getDateTimeValue().getMinutes(), modifier); | ||
1018 | 712 | break; | ||
1019 | 713 | case 's': | ||
1020 | 714 | if (modifier.presentation_modifier.empty()) | ||
1021 | 715 | modifier.presentation_modifier.append("01"); | ||
1022 | 716 | format_number(resultString, dateTimeItem->getDateTimeValue().getIntSeconds(), modifier); | ||
1023 | 717 | break; | ||
1024 | 718 | case 'f': // fractional seconds | ||
1025 | 719 | format_number(resultString, (long)(dateTimeItem->getDateTimeValue().getFractionalSeconds()*1000.0/DateTime::FRAC_SECONDS_UPPER_LIMIT), | ||
1026 | 720 | modifier); | ||
1027 | 721 | break; | ||
1028 | 722 | case 'Z': // timezone as a time offset from UTC, or if an alphabetic modifier is present the conventional name of a timezone (such as PST) | ||
1029 | 723 | // deliberate fall-through | ||
1030 | 724 | case 'z': // timezone as a time offset using GMT, for example GMT+1 | ||
1031 | 725 | { | ||
1032 | 726 | zstring temp = "gmt"; | ||
1033 | 727 | temp += dateTimeItem->getDateTimeValue().getTimezone().toString(); | ||
1034 | 728 | format_string(resultString, temp.c_str(), modifier); | ||
1035 | 729 | } | ||
1036 | 730 | break; | ||
1037 | 731 | case 'C': // calendar: the name or abbreviation of a calendar name | ||
1038 | 732 | if (modifier.presentation_modifier.empty()) | ||
1039 | 733 | modifier.presentation_modifier.append("n"); | ||
1040 | 734 | format_string(resultString, "gregorian", modifier); | ||
1041 | 735 | break; | ||
1042 | 736 | case 'E': // era: the name of a baseline for the numbering of years, for example the reign of a monarch | ||
1043 | 737 | if (modifier.presentation_modifier.empty()) | ||
1044 | 738 | modifier.presentation_modifier.append("n"); | ||
1045 | 739 | format_string(resultString, dateTimeItem->getDateTimeValue().getYear() < 0 ? "ad" : "bc", modifier); | ||
1046 | 740 | break; | ||
1047 | 741 | } // switch | ||
1048 | 742 | } // if (!variable_marker) | ||
1049 | 743 | |||
1050 | 744 | } // for | ||
1051 | 745 | |||
1052 | 746 | STACK_PUSH(GENV_ITEMFACTORY->createString(result, resultString), state); | ||
1053 | 747 | } | ||
1054 | 748 | |||
1055 | 749 | STACK_END (state); | ||
1056 | 750 | } | ||
1057 | 751 | |||
1058 | 752 | } // namespace zorba | 192 | } // namespace zorba |
1059 | 753 | /* vim:set et sw=2 ts=2: */ | 193 | /* vim:set et sw=2 ts=2: */ |
1060 | 754 | 194 | ||
1061 | === modified file 'src/runtime/durations_dates_times/DurationsDatesTimesImpl.h' | |||
1062 | --- src/runtime/durations_dates_times/DurationsDatesTimesImpl.h 2013-02-07 17:24:36 +0000 | |||
1063 | +++ src/runtime/durations_dates_times/DurationsDatesTimesImpl.h 2013-03-21 16:00:34 +0000 | |||
1064 | @@ -24,53 +24,12 @@ | |||
1065 | 24 | #include "runtime/base/unarybase.h" | 24 | #include "runtime/base/unarybase.h" |
1066 | 25 | #include "runtime/base/narybase.h" | 25 | #include "runtime/base/narybase.h" |
1067 | 26 | 26 | ||
1068 | 27 | namespace zorba { | ||
1069 | 27 | 28 | ||
1072 | 28 | namespace zorba | 29 | /////////////////////////////////////////////////////////////////////////////// |
1071 | 29 | { | ||
1073 | 30 | 30 | ||
1074 | 31 | BINARY_ITER(FnDateTimeConstructorIterator); | 31 | BINARY_ITER(FnDateTimeConstructorIterator); |
1075 | 32 | 32 | ||
1076 | 33 | |||
1077 | 34 | // XQuery 3.0 DateTime formatting | ||
1078 | 35 | class FnFormatDateTimeIterator : public NaryBaseIterator<FnFormatDateTimeIterator, | ||
1079 | 36 | PlanIteratorState > | ||
1080 | 37 | { | ||
1081 | 38 | private: | ||
1082 | 39 | DateTime::FACET_TYPE facet_type; | ||
1083 | 40 | |||
1084 | 41 | public: | ||
1085 | 42 | SERIALIZABLE_CLASS(FnFormatDateTimeIterator); | ||
1086 | 43 | |||
1087 | 44 | SERIALIZABLE_CLASS_CONSTRUCTOR2T( | ||
1088 | 45 | FnFormatDateTimeIterator, | ||
1089 | 46 | NaryBaseIterator<FnFormatDateTimeIterator, PlanIteratorState >); | ||
1090 | 47 | |||
1091 | 48 | void serialize(::zorba::serialization::Archiver &ar) | ||
1092 | 49 | { | ||
1093 | 50 | serialize_baseclass(ar, | ||
1094 | 51 | (NaryBaseIterator<FnFormatDateTimeIterator, PlanIteratorState >*)this); | ||
1095 | 52 | |||
1096 | 53 | SERIALIZE_ENUM(DateTime::FACET_TYPE, facet_type); | ||
1097 | 54 | } | ||
1098 | 55 | |||
1099 | 56 | public: | ||
1100 | 57 | FnFormatDateTimeIterator( | ||
1101 | 58 | static_context* sctx, | ||
1102 | 59 | const QueryLoc& loc, | ||
1103 | 60 | std::vector<PlanIter_t>& aChildren, | ||
1104 | 61 | DateTime::FACET_TYPE a_facet_type = DateTime::DATETIME_FACET) | ||
1105 | 62 | : | ||
1106 | 63 | NaryBaseIterator<FnFormatDateTimeIterator, PlanIteratorState>(sctx, loc, aChildren), | ||
1107 | 64 | facet_type(a_facet_type) | ||
1108 | 65 | { | ||
1109 | 66 | } | ||
1110 | 67 | |||
1111 | 68 | void accept(PlanIterVisitor& v) const; | ||
1112 | 69 | |||
1113 | 70 | bool nextImpl(store::Item_t& result, PlanState& aPlanState) const; | ||
1114 | 71 | }; | ||
1115 | 72 | |||
1116 | 73 | |||
1117 | 74 | /* | 33 | /* |
1118 | 75 | 10.7 Timezone Adjustment Functions on Dates and Time Values | 34 | 10.7 Timezone Adjustment Functions on Dates and Time Values |
1119 | 76 | */ | 35 | */ |
1120 | @@ -88,14 +47,14 @@ | |||
1121 | 88 | */ | 47 | */ |
1122 | 89 | BINARY_ITER(FnAdjustToTimeZoneIterator_2); | 48 | BINARY_ITER(FnAdjustToTimeZoneIterator_2); |
1123 | 90 | 49 | ||
1124 | 50 | /////////////////////////////////////////////////////////////////////////////// | ||
1125 | 51 | |||
1126 | 91 | } // namespace zorba | 52 | } // namespace zorba |
1127 | 92 | 53 | ||
1130 | 93 | #endif | 54 | #endif /* ZORBA_RUNTIME_DURATIONSDATESTIMES */ |
1129 | 94 | |||
1131 | 95 | /* | 55 | /* |
1132 | 96 | * Local variables: | 56 | * Local variables: |
1133 | 97 | * mode: c++ | 57 | * mode: c++ |
1134 | 98 | * End: | 58 | * End: |
1135 | 99 | */ | 59 | */ |
1136 | 100 | |||
1137 | 101 | /* vim:set et sw=2 ts=2: */ | 60 | /* vim:set et sw=2 ts=2: */ |
1138 | 102 | 61 | ||
1139 | === added file 'src/runtime/durations_dates_times/format_dateTime.cpp' | |||
1140 | --- src/runtime/durations_dates_times/format_dateTime.cpp 1970-01-01 00:00:00 +0000 | |||
1141 | +++ src/runtime/durations_dates_times/format_dateTime.cpp 2013-03-21 16:00:34 +0000 | |||
1142 | @@ -0,0 +1,1377 @@ | |||
1143 | 1 | /* | ||
1144 | 2 | * Copyright 2006-2008 The FLWOR Foundation. | ||
1145 | 3 | * | ||
1146 | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
1147 | 5 | * you may not use this file except in compliance with the License. | ||
1148 | 6 | * You may obtain a copy of the License at | ||
1149 | 7 | * | ||
1150 | 8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
1151 | 9 | * | ||
1152 | 10 | * Unless required by applicable law or agreed to in writing, software | ||
1153 | 11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
1154 | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
1155 | 13 | * See the License for the specific language governing permissions and | ||
1156 | 14 | * limitations under the License. | ||
1157 | 15 | */ | ||
1158 | 16 | |||
1159 | 17 | #include "stdafx.h" | ||
1160 | 18 | |||
1161 | 19 | // standard | ||
1162 | 20 | #include <algorithm> | ||
1163 | 21 | #include <cctype> | ||
1164 | 22 | #include <cmath> | ||
1165 | 23 | #include <cstdlib> | ||
1166 | 24 | #include <functional> | ||
1167 | 25 | #include <iomanip> | ||
1168 | 26 | #include <iostream> | ||
1169 | 27 | #include <sstream> | ||
1170 | 28 | |||
1171 | 29 | // Zorba | ||
1172 | 30 | #include "context/dynamic_context.h" | ||
1173 | 31 | #include "context/static_context.h" | ||
1174 | 32 | #include "runtime/core/arithmetic_impl.h" | ||
1175 | 33 | #include "runtime/visitors/planiter_visitor.h" | ||
1176 | 34 | #include "store/api/item.h" | ||
1177 | 35 | #include "store/api/item_factory.h" | ||
1178 | 36 | #include "store/api/store.h" | ||
1179 | 37 | #include "system/globalenv.h" | ||
1180 | 38 | #include "util/ascii_util.h" | ||
1181 | 39 | #include "util/stream_util.h" | ||
1182 | 40 | #include "util/string_util.h" | ||
1183 | 41 | #include "util/time_util.h" | ||
1184 | 42 | #include "util/utf8_util.h" | ||
1185 | 43 | #include "zorbatypes/datetime.h" | ||
1186 | 44 | #include "zorbatypes/datetime/parse.h" | ||
1187 | 45 | #include "zorbatypes/duration.h" | ||
1188 | 46 | #include "zorbatypes/zstring.h" | ||
1189 | 47 | #include "zorbautils/locale.h" | ||
1190 | 48 | |||
1191 | 49 | // local | ||
1192 | 50 | #include "format_dateTime.h" | ||
1193 | 51 | |||
1194 | 52 | using namespace std; | ||
1195 | 53 | using namespace zorba::locale; | ||
1196 | 54 | using namespace zorba::time; | ||
1197 | 55 | |||
1198 | 56 | namespace zorba { | ||
1199 | 57 | |||
1200 | 58 | SERIALIZABLE_CLASS_VERSIONS(FnFormatDateTimeIterator) | ||
1201 | 59 | NARY_ACCEPT(FnFormatDateTimeIterator); | ||
1202 | 60 | |||
1203 | 61 | /////////////////////////////////////////////////////////////////////////////// | ||
1204 | 62 | |||
1205 | 63 | /** | ||
1206 | 64 | * Holds presentation modifier data. | ||
1207 | 65 | */ | ||
1208 | 66 | struct modifier { | ||
1209 | 67 | enum first_type { | ||
1210 | 68 | arabic, // '1' : 0 1 2 ... 10 11 12 ... | ||
1211 | 69 | alpha, // 'a' : a b c ... z aa ab ac ... | ||
1212 | 70 | ALPHA, // 'A' : A B C ... Z AA AB AC ... | ||
1213 | 71 | roman, // 'i' : i ii iii iv v vi vii viii ix x ... | ||
1214 | 72 | ROMAN, // 'I' : I II III IV V VI VII VIII IX X ... | ||
1215 | 73 | name, // 'n' : name | ||
1216 | 74 | Name, // 'Nn': Name | ||
1217 | 75 | NAME, // 'N' : NAME | ||
1218 | 76 | words, // 'w' : one two three four ... | ||
1219 | 77 | Words, // 'Ww': One Two Three Four ... | ||
1220 | 78 | WORDS, // 'W' : ONE TWO THREE FOUR ... | ||
1221 | 79 | military_tz // 'Z' : A B C ... J ... X Y Z | ||
1222 | 80 | }; | ||
1223 | 81 | |||
1224 | 82 | enum second_co_type { | ||
1225 | 83 | no_second_co, | ||
1226 | 84 | cardinal, // 'c': 7 or seven | ||
1227 | 85 | ordinal // 'o': 7th or seventh | ||
1228 | 86 | }; | ||
1229 | 87 | |||
1230 | 88 | enum second_at_type { | ||
1231 | 89 | no_second_at, | ||
1232 | 90 | alphabetic, // 'a' | ||
1233 | 91 | traditional // 't' | ||
1234 | 92 | }; | ||
1235 | 93 | |||
1236 | 94 | typedef unsigned width_type; | ||
1237 | 95 | |||
1238 | 96 | struct { | ||
1239 | 97 | bool parsed; | ||
1240 | 98 | first_type type; | ||
1241 | 99 | zstring format; | ||
1242 | 100 | bool has_grouping_separators; | ||
1243 | 101 | unicode::code_point zero; | ||
1244 | 102 | } first; | ||
1245 | 103 | |||
1246 | 104 | struct { | ||
1247 | 105 | second_co_type co_type; | ||
1248 | 106 | zstring co_string; | ||
1249 | 107 | second_at_type at_type; | ||
1250 | 108 | } second; | ||
1251 | 109 | |||
1252 | 110 | width_type min_width; | ||
1253 | 111 | width_type max_width; | ||
1254 | 112 | |||
1255 | 113 | // | ||
1256 | 114 | // This stuff isn't part of the "presentation modifier" as discussed in the | ||
1257 | 115 | // XQuery3.0 F&O spec, but this is a convenient place to put it nonetheless. | ||
1258 | 116 | // | ||
1259 | 117 | iso639_1::type lang; | ||
1260 | 118 | bool lang_is_fallback; | ||
1261 | 119 | iso3166_1::type country; | ||
1262 | 120 | calendar::type cal; | ||
1263 | 121 | bool cal_is_fallback; | ||
1264 | 122 | |||
1265 | 123 | void append_if_fallback_lang( zstring *s ) const { | ||
1266 | 124 | if ( lang_is_fallback ) { | ||
1267 | 125 | // | ||
1268 | 126 | // XQuery 3.0 F&O: 9.8.4.3: If the fallback representation uses a | ||
1269 | 127 | // different language from that requested, the output string must | ||
1270 | 128 | // identify the language actually used, for example by prefixing the | ||
1271 | 129 | // string with [Language: Y] (where Y is the language actually used) | ||
1272 | 130 | // localized in an implementation-dependent way. | ||
1273 | 131 | // | ||
1274 | 132 | ostringstream oss; | ||
1275 | 133 | // TODO: localize "Language" | ||
1276 | 134 | oss << "[Language: " << lang << ']'; | ||
1277 | 135 | *s += oss.str(); | ||
1278 | 136 | } | ||
1279 | 137 | } | ||
1280 | 138 | |||
1281 | 139 | bool gt_max_width( width_type n ) const { | ||
1282 | 140 | return max_width > 0 && n > max_width; | ||
1283 | 141 | } | ||
1284 | 142 | |||
1285 | 143 | zstring const& left_pad_zero( zstring *s ) const { | ||
1286 | 144 | if ( min_width ) | ||
1287 | 145 | utf8::left_pad( s, min_width, first.zero ); | ||
1288 | 146 | return *s; | ||
1289 | 147 | } | ||
1290 | 148 | |||
1291 | 149 | zstring const& right_pad_space( zstring *s ) const { | ||
1292 | 150 | if ( min_width ) | ||
1293 | 151 | utf8::right_pad( s, min_width, ' ' ); | ||
1294 | 152 | return *s; | ||
1295 | 153 | } | ||
1296 | 154 | |||
1297 | 155 | void set_default_width( width_type width ) { | ||
1298 | 156 | if ( !(first.parsed || min_width || max_width) ) | ||
1299 | 157 | min_width = max_width = width; | ||
1300 | 158 | } | ||
1301 | 159 | |||
1302 | 160 | modifier() { | ||
1303 | 161 | first.parsed = false; | ||
1304 | 162 | first.type = arabic; | ||
1305 | 163 | first.has_grouping_separators = false; | ||
1306 | 164 | first.zero = '0'; | ||
1307 | 165 | second.co_type = cardinal; | ||
1308 | 166 | second.at_type = no_second_at; | ||
1309 | 167 | min_width = max_width = 0; | ||
1310 | 168 | }; | ||
1311 | 169 | }; | ||
1312 | 170 | |||
1313 | 171 | /////////////////////////////////////////////////////////////////////////////// | ||
1314 | 172 | |||
1315 | 173 | zstring alpha( unsigned n, bool capital ) { | ||
1316 | 174 | zstring result; | ||
1317 | 175 | if ( n ) { | ||
1318 | 176 | char const c = capital ? 'A' : 'a'; | ||
1319 | 177 | while ( n ) { | ||
1320 | 178 | unsigned const m = n - 1; | ||
1321 | 179 | result.insert( (zstring::size_type)0, 1, c + m % 26 ); | ||
1322 | 180 | n = m / 26; | ||
1323 | 181 | } | ||
1324 | 182 | } else | ||
1325 | 183 | result = "0"; | ||
1326 | 184 | return result; | ||
1327 | 185 | } | ||
1328 | 186 | |||
1329 | 187 | /////////////////////////////////////////////////////////////////////////////// | ||
1330 | 188 | |||
1331 | 189 | namespace english_impl { | ||
1332 | 190 | |||
1333 | 191 | // Based on code from: | ||
1334 | 192 | // http://www.cprogramming.com/challenges/integer-to-english-sol.html | ||
1335 | 193 | |||
1336 | 194 | static string const ones[][2] = { | ||
1337 | 195 | { "", "" }, | ||
1338 | 196 | { "one", "first" }, | ||
1339 | 197 | { "two", "second" }, | ||
1340 | 198 | { "three", "third" }, | ||
1341 | 199 | { "four", "fourth" }, | ||
1342 | 200 | { "five", "fifth" }, | ||
1343 | 201 | { "six", "sixth" }, | ||
1344 | 202 | { "seven", "seventh" }, | ||
1345 | 203 | { "eight", "eighth" }, | ||
1346 | 204 | { "nine", "ninth" }, | ||
1347 | 205 | { "ten", "tenth" }, | ||
1348 | 206 | { "eleven", "eleventh" }, | ||
1349 | 207 | { "twelve", "twelveth" }, | ||
1350 | 208 | { "thirteen", "thirteenth" }, | ||
1351 | 209 | { "fourteen", "fourteenth" }, | ||
1352 | 210 | { "fifteen", "fifteenth" }, | ||
1353 | 211 | { "sixteen", "sixteenth" }, | ||
1354 | 212 | { "seventeen", "seventeenth" }, | ||
1355 | 213 | { "eighteen", "eighteenth" }, | ||
1356 | 214 | { "nineteen", "nineteenth" } | ||
1357 | 215 | }; | ||
1358 | 216 | |||
1359 | 217 | static zstring const tens[][2] = { | ||
1360 | 218 | { "", "" }, | ||
1361 | 219 | { "", "" }, | ||
1362 | 220 | { "twenty", "twentieth" }, | ||
1363 | 221 | { "thirty", "thirtieth" }, | ||
1364 | 222 | { "forty", "fortieth" }, | ||
1365 | 223 | { "fifty", "fiftieth" }, | ||
1366 | 224 | { "sixty", "sixtieth" }, | ||
1367 | 225 | { "seventy", "seventieth" }, | ||
1368 | 226 | { "eighty", "eighteenth" }, | ||
1369 | 227 | { "ninety", "ninetieth" } | ||
1370 | 228 | }; | ||
1371 | 229 | |||
1372 | 230 | // Enough entries to print English for 64-bit integers. | ||
1373 | 231 | static zstring const big[][2] = { | ||
1374 | 232 | { "", "" }, | ||
1375 | 233 | { "thousand", "thousandth" }, | ||
1376 | 234 | { "million", "millionth" }, | ||
1377 | 235 | { "billion", "billionth" }, | ||
1378 | 236 | { "trillion", "trillionth" }, | ||
1379 | 237 | { "quadrillion", "quadrillionth" }, | ||
1380 | 238 | { "quintillion", "quintillionth" } | ||
1381 | 239 | }; | ||
1382 | 240 | |||
1383 | 241 | inline zstring if_space( zstring const &s ) { | ||
1384 | 242 | return s.empty() ? "" : ' ' + s; | ||
1385 | 243 | } | ||
1386 | 244 | |||
1387 | 245 | static zstring hundreds( int64_t n, bool ordinal ) { | ||
1388 | 246 | if ( n < 20 ) | ||
1389 | 247 | return ones[ n ][ ordinal ]; | ||
1390 | 248 | zstring const tmp( if_space( ones[ n % 10 ][ ordinal ] ) ); | ||
1391 | 249 | return tens[ n / 10 ][ ordinal && tmp.empty() ] + tmp; | ||
1392 | 250 | } | ||
1393 | 251 | |||
1394 | 252 | } // namespace english_impl | ||
1395 | 253 | |||
1396 | 254 | /** | ||
1397 | 255 | * Converts a signed integer to English, e.g, 42 becomes "forty two". | ||
1398 | 256 | * | ||
1399 | 257 | * @param n The integer to convert. | ||
1400 | 258 | * @param ordinal If \c true, ordinal words ("forty second") are returned. | ||
1401 | 259 | * @return Returns \a n in English. | ||
1402 | 260 | */ | ||
1403 | 261 | static zstring english( int64_t n, bool ordinal = false ) { | ||
1404 | 262 | using namespace english_impl; | ||
1405 | 263 | |||
1406 | 264 | if ( !n ) | ||
1407 | 265 | return ordinal ? "zeroth" : "zero"; | ||
1408 | 266 | |||
1409 | 267 | bool const negative = n < 0; | ||
1410 | 268 | if ( negative ) | ||
1411 | 269 | n = -n; | ||
1412 | 270 | |||
1413 | 271 | int big_count = 0; | ||
1414 | 272 | bool big_ordinal = ordinal; | ||
1415 | 273 | zstring r; | ||
1416 | 274 | |||
1417 | 275 | while ( n ) { | ||
1418 | 276 | if ( int64_t const m = n % 1000 ) { | ||
1419 | 277 | zstring s; | ||
1420 | 278 | if ( m < 100 ) | ||
1421 | 279 | s = hundreds( m, ordinal ); | ||
1422 | 280 | else { | ||
1423 | 281 | zstring const tmp( if_space( hundreds( m % 100, ordinal ) ) ); | ||
1424 | 282 | s = ones[ m / 100 ][0] + ' ' | ||
1425 | 283 | + (ordinal && tmp.empty() ? "hundredth" : "hundred") + tmp; | ||
1426 | 284 | } | ||
1427 | 285 | zstring const tmp( if_space( r ) ); | ||
1428 | 286 | r = s + if_space( big[ big_count ][ big_ordinal && tmp.empty() ] + tmp ); | ||
1429 | 287 | big_ordinal = false; | ||
1430 | 288 | } | ||
1431 | 289 | n /= 1000; | ||
1432 | 290 | ++big_count; | ||
1433 | 291 | ordinal = false; | ||
1434 | 292 | } | ||
1435 | 293 | |||
1436 | 294 | if ( negative ) | ||
1437 | 295 | r = "negative " + r; | ||
1438 | 296 | return r; | ||
1439 | 297 | } | ||
1440 | 298 | |||
1441 | 299 | /////////////////////////////////////////////////////////////////////////////// | ||
1442 | 300 | |||
1443 | 301 | static bool is_grouping_separator( unicode::code_point cp ) { | ||
1444 | 302 | using namespace unicode; | ||
1445 | 303 | // | ||
1446 | 304 | // XQuery 3.0 F&O: 4.6.1: a grouping-separator-sign is a non-alphanumeric | ||
1447 | 305 | // character, that is a character whose Unicode category is other than Nd, | ||
1448 | 306 | // Nl, No, Lu, Ll, Lt, Lm or Lo. | ||
1449 | 307 | // | ||
1450 | 308 | return !( is_category( cp, Nd ) | ||
1451 | 309 | || is_category( cp, Nl ) | ||
1452 | 310 | || is_category( cp, No ) | ||
1453 | 311 | || is_category( cp, Lu ) | ||
1454 | 312 | || is_category( cp, Ll ) | ||
1455 | 313 | || is_category( cp, Lt ) | ||
1456 | 314 | || is_category( cp, Lm ) | ||
1457 | 315 | || is_category( cp, Lo ) | ||
1458 | 316 | ); | ||
1459 | 317 | } | ||
1460 | 318 | |||
1461 | 319 | /////////////////////////////////////////////////////////////////////////////// | ||
1462 | 320 | |||
1463 | 321 | /** | ||
1464 | 322 | * Returns the English ordinal suffix for an integer, e.g., "st" for 1, "nd" | ||
1465 | 323 | * for 2, etc. | ||
1466 | 324 | * | ||
1467 | 325 | * @param n The integer to return the ordinal suffix for. | ||
1468 | 326 | * @return Returns said suffix. | ||
1469 | 327 | */ | ||
1470 | 328 | static char const* ordinal( int n ) { | ||
1471 | 329 | n = std::abs( n ); | ||
1472 | 330 | switch ( n % 100 ) { | ||
1473 | 331 | case 11: | ||
1474 | 332 | case 12: | ||
1475 | 333 | case 13: | ||
1476 | 334 | break; | ||
1477 | 335 | default: | ||
1478 | 336 | switch ( n % 10 ) { | ||
1479 | 337 | case 1: return "st"; | ||
1480 | 338 | case 2: return "nd"; | ||
1481 | 339 | case 3: return "rd"; | ||
1482 | 340 | } | ||
1483 | 341 | } | ||
1484 | 342 | return "th"; | ||
1485 | 343 | } | ||
1486 | 344 | |||
1487 | 345 | /////////////////////////////////////////////////////////////////////////////// | ||
1488 | 346 | |||
1489 | 347 | /** | ||
1490 | 348 | * A unary_function to convert a (presumed) lower-case string to title-case | ||
1491 | 349 | * "Like This." | ||
1492 | 350 | */ | ||
1493 | 351 | class to_title : public unary_function<char,char> { | ||
1494 | 352 | public: | ||
1495 | 353 | to_title() : capitalize_( true ) { } | ||
1496 | 354 | |||
1497 | 355 | result_type operator()( argument_type c ) { | ||
1498 | 356 | if ( ascii::is_alpha( c ) ) { | ||
1499 | 357 | if ( capitalize_ ) { | ||
1500 | 358 | c = ascii::to_upper( c ); | ||
1501 | 359 | capitalize_ = false; | ||
1502 | 360 | } | ||
1503 | 361 | } else if ( ascii::is_space( c ) ) | ||
1504 | 362 | capitalize_ = true; | ||
1505 | 363 | return c; | ||
1506 | 364 | }; | ||
1507 | 365 | |||
1508 | 366 | private: | ||
1509 | 367 | bool capitalize_; | ||
1510 | 368 | }; | ||
1511 | 369 | |||
1512 | 370 | /////////////////////////////////////////////////////////////////////////////// | ||
1513 | 371 | |||
1514 | 372 | static void append_number( int n, modifier const &mod, zstring *dest ) { | ||
1515 | 373 | switch ( mod.first.type ) { | ||
1516 | 374 | case modifier::arabic: { | ||
1517 | 375 | utf8::itou_buf_type buf; | ||
1518 | 376 | zstring tmp( utf8::itou( n, buf, mod.first.zero ) ); | ||
1519 | 377 | if ( mod.second.co_type == modifier::ordinal ) | ||
1520 | 378 | tmp += ordinal( n ); | ||
1521 | 379 | *dest += mod.left_pad_zero( &tmp ); | ||
1522 | 380 | break; | ||
1523 | 381 | } | ||
1524 | 382 | |||
1525 | 383 | case modifier::alpha: | ||
1526 | 384 | case modifier::ALPHA: { | ||
1527 | 385 | zstring tmp( alpha( n, mod.first.type == modifier::ALPHA ) ); | ||
1528 | 386 | *dest += mod.right_pad_space( &tmp ); | ||
1529 | 387 | break; | ||
1530 | 388 | } | ||
1531 | 389 | |||
1532 | 390 | case modifier::roman: | ||
1533 | 391 | case modifier::ROMAN: { | ||
1534 | 392 | ostringstream oss; | ||
1535 | 393 | if ( mod.first.type == modifier::ROMAN ) | ||
1536 | 394 | oss << uppercase; | ||
1537 | 395 | oss << roman( n ); | ||
1538 | 396 | zstring tmp( oss.str() ); | ||
1539 | 397 | *dest += mod.right_pad_space( &tmp ); | ||
1540 | 398 | break; | ||
1541 | 399 | } | ||
1542 | 400 | |||
1543 | 401 | case modifier::words: { | ||
1544 | 402 | zstring tmp( english( n, mod.second.co_type == modifier::ordinal ) ); | ||
1545 | 403 | *dest += mod.right_pad_space( &tmp ); | ||
1546 | 404 | break; | ||
1547 | 405 | } | ||
1548 | 406 | |||
1549 | 407 | case modifier::Words: { | ||
1550 | 408 | zstring tmp( english( n, mod.second.co_type == modifier::ordinal ) ); | ||
1551 | 409 | std::transform( tmp.begin(), tmp.end(), tmp.begin(), to_title() ); | ||
1552 | 410 | *dest += mod.right_pad_space( &tmp ); | ||
1553 | 411 | break; | ||
1554 | 412 | } | ||
1555 | 413 | |||
1556 | 414 | case modifier::WORDS: { | ||
1557 | 415 | zstring tmp( english( n, mod.second.co_type == modifier::ordinal ) ); | ||
1558 | 416 | ascii::to_upper( tmp ); | ||
1559 | 417 | *dest += mod.right_pad_space( &tmp ); | ||
1560 | 418 | break; | ||
1561 | 419 | } | ||
1562 | 420 | |||
1563 | 421 | default: | ||
1564 | 422 | /* handled elsewhere */; | ||
1565 | 423 | } | ||
1566 | 424 | } | ||
1567 | 425 | |||
1568 | 426 | static void append_fractional_seconds( int n, modifier const &mod, | ||
1569 | 427 | zstring *dest ) { | ||
1570 | 428 | switch ( mod.first.type ) { | ||
1571 | 429 | case modifier::arabic: | ||
1572 | 430 | if ( mod.min_width || mod.max_width ) { | ||
1573 | 431 | if ( mod.max_width ) { | ||
1574 | 432 | double const f = (double)n / DateTime::FRAC_SECONDS_UPPER_LIMIT; | ||
1575 | 433 | double const p = ::pow( 10, mod.max_width ); | ||
1576 | 434 | n = (int)( f * p + 0.5 ); | ||
1577 | 435 | } else | ||
1578 | 436 | n = (int)( n * 1000.0 / DateTime::FRAC_SECONDS_UPPER_LIMIT ); | ||
1579 | 437 | |||
1580 | 438 | ascii::itoa_buf_type buf; | ||
1581 | 439 | zstring tmp( ascii::itoa( n, buf ) ); | ||
1582 | 440 | |||
1583 | 441 | if ( tmp.size() < mod.min_width ) | ||
1584 | 442 | ascii::right_pad( &tmp, mod.min_width, '0' ); | ||
1585 | 443 | else if ( mod.min_width > 0 ) | ||
1586 | 444 | while ( tmp.size() > mod.min_width && | ||
1587 | 445 | tmp[ tmp.size() - 1 ] == '0' ) { | ||
1588 | 446 | tmp = tmp.substr( 0, tmp.size() - 1 ); | ||
1589 | 447 | } | ||
1590 | 448 | *dest += tmp; | ||
1591 | 449 | break; | ||
1592 | 450 | } | ||
1593 | 451 | n = (int)( n * 1000.0 / DateTime::FRAC_SECONDS_UPPER_LIMIT ); | ||
1594 | 452 | // no break; | ||
1595 | 453 | default: | ||
1596 | 454 | append_number( n, mod, dest ); | ||
1597 | 455 | } | ||
1598 | 456 | } | ||
1599 | 457 | |||
1600 | 458 | static void append_string( zstring const &s, modifier const &mod, | ||
1601 | 459 | zstring *dest ) { | ||
1602 | 460 | zstring tmp; | ||
1603 | 461 | switch ( mod.first.type ) { | ||
1604 | 462 | case modifier::name: | ||
1605 | 463 | utf8::to_lower( s, &tmp ); | ||
1606 | 464 | break; | ||
1607 | 465 | case modifier::Name: { | ||
1608 | 466 | utf8::to_upper( s.substr( 0, 1 ), &tmp ); | ||
1609 | 467 | zstring tmp2; | ||
1610 | 468 | utf8::to_lower( s.substr( 1 ), &tmp2 ); | ||
1611 | 469 | tmp += tmp2; | ||
1612 | 470 | break; | ||
1613 | 471 | } | ||
1614 | 472 | case modifier::NAME: | ||
1615 | 473 | utf8::to_upper( s, &tmp ); | ||
1616 | 474 | break; | ||
1617 | 475 | default: | ||
1618 | 476 | break; | ||
1619 | 477 | } | ||
1620 | 478 | *dest += mod.right_pad_space( &tmp ); | ||
1621 | 479 | } | ||
1622 | 480 | |||
1623 | 481 | static void append_month( unsigned mon, modifier const &mod, zstring *dest ) { | ||
1624 | 482 | switch ( mod.first.type ) { | ||
1625 | 483 | case modifier::name: | ||
1626 | 484 | case modifier::Name: | ||
1627 | 485 | case modifier::NAME: { | ||
1628 | 486 | zstring name( locale::get_month_name( mon, mod.lang, mod.country ) ); | ||
1629 | 487 | utf8_string<zstring> u_name( name ); | ||
1630 | 488 | if ( mod.gt_max_width( u_name.size() ) ) { | ||
1631 | 489 | // | ||
1632 | 490 | // XQuery 3.0 F&O: 9.8.4.1: If the full representation of the value | ||
1633 | 491 | // exceeds the specified maximum width, then the processor should | ||
1634 | 492 | // attempt to use an alternative shorter representation that fits | ||
1635 | 493 | // within the maximum width. Where the presentation modifier is N, n, | ||
1636 | 494 | // or Nn, this is done by abbreviating the name, using either | ||
1637 | 495 | // conventional abbreviations if available, or crude right-truncation | ||
1638 | 496 | // if not. | ||
1639 | 497 | // | ||
1640 | 498 | name = locale::get_month_abbr( mon, mod.lang, mod.country ); | ||
1641 | 499 | if ( mod.gt_max_width( u_name.size() ) ) | ||
1642 | 500 | u_name = u_name.substr( 0, mod.max_width ); | ||
1643 | 501 | } | ||
1644 | 502 | mod.append_if_fallback_lang( dest ); | ||
1645 | 503 | append_string( name, mod, dest ); | ||
1646 | 504 | break; | ||
1647 | 505 | } | ||
1648 | 506 | default: | ||
1649 | 507 | append_number( mon + 1, mod, dest ); | ||
1650 | 508 | } | ||
1651 | 509 | } | ||
1652 | 510 | |||
1653 | 511 | static void append_timezone( char component, TimeZone const &tz, | ||
1654 | 512 | modifier const &mod, zstring *dest ) { | ||
1655 | 513 | ascii::itoa_buf_type buf; | ||
1656 | 514 | zstring format, tmp; | ||
1657 | 515 | bool has_grouping_separators; | ||
1658 | 516 | |||
1659 | 517 | if ( mod.first.format.empty() ) { | ||
1660 | 518 | format = "01:01"; | ||
1661 | 519 | has_grouping_separators = true; | ||
1662 | 520 | } else { | ||
1663 | 521 | format = mod.first.format; | ||
1664 | 522 | has_grouping_separators = mod.first.has_grouping_separators; | ||
1665 | 523 | } | ||
1666 | 524 | |||
1667 | 525 | int hour = tz.getHours(); | ||
1668 | 526 | int const min = std::abs( tz.getMinutes() ); | ||
1669 | 527 | |||
1670 | 528 | switch ( mod.first.type ) { | ||
1671 | 529 | case modifier::NAME: | ||
1672 | 530 | // | ||
1673 | 531 | // XQuery 3.0 F&O: 9.8.4.2: If the first presentation modifier is N, then | ||
1674 | 532 | // the timezone is output (where possible) as a timezone name, for | ||
1675 | 533 | // example EST or CET. The same timezone offset has different names in | ||
1676 | 534 | // different places; it is therefore recommended that this option should | ||
1677 | 535 | // be used only if a country code or Olson timezone name is supplied in | ||
1678 | 536 | // the $place argument. In the absence of this information, the | ||
1679 | 537 | // implementation may apply a default, for example by using the timezone | ||
1680 | 538 | // names that are conventional in North America. If no timezone name can | ||
1681 | 539 | // be identified, the timezone offset is output using the fallback format | ||
1682 | 540 | // +01:01. | ||
1683 | 541 | // | ||
1684 | 542 | if ( !min ) | ||
1685 | 543 | switch ( hour ) { | ||
1686 | 544 | case 0: tmp += "GMT"; goto append; | ||
1687 | 545 | case -5: tmp += "EST"; goto append; | ||
1688 | 546 | case -6: tmp += "CST"; goto append; | ||
1689 | 547 | case -7: tmp += "MST"; goto append; | ||
1690 | 548 | case -8: tmp += "PST"; goto append; | ||
1691 | 549 | } | ||
1692 | 550 | // TODO: use Olson timezone names | ||
1693 | 551 | goto fallback; | ||
1694 | 552 | |||
1695 | 553 | case modifier::military_tz: | ||
1696 | 554 | // | ||
1697 | 555 | // Ibid: If the first presentation modifier is Z, then the timezone is | ||
1698 | 556 | // formatted as a military timezone letter, using the convention Z = | ||
1699 | 557 | // +00:00, A = +01:00, B = +02:00, ..., M = +12:00, N = -01:00, O = | ||
1700 | 558 | // -02:00, ... Y = -12:00. | ||
1701 | 559 | // | ||
1702 | 560 | if ( tz.timeZoneNotSet() ) { | ||
1703 | 561 | // | ||
1704 | 562 | // Ibid: The letter J (meaning local time) is used in the case of a | ||
1705 | 563 | // value that does not specify a timezone offset. | ||
1706 | 564 | // | ||
1707 | 565 | tmp += 'J'; | ||
1708 | 566 | break; | ||
1709 | 567 | } | ||
1710 | 568 | if ( hour >= -12 && hour <= 12 && !min ) { | ||
1711 | 569 | tmp += time::get_military_tz( hour ); | ||
1712 | 570 | break; | ||
1713 | 571 | } | ||
1714 | 572 | // | ||
1715 | 573 | // Ibid: Timezone offsets that have no representation in this system | ||
1716 | 574 | // (for example Indian Standard Time, +05:30) are output as if the | ||
1717 | 575 | // format 01:01 had been requested. | ||
1718 | 576 | // | ||
1719 | 577 | // no break; | ||
1720 | 578 | |||
1721 | 579 | fallback: | ||
1722 | 580 | format = "01:01"; | ||
1723 | 581 | // no break; | ||
1724 | 582 | |||
1725 | 583 | default: | ||
1726 | 584 | if ( component == 'z' ) { | ||
1727 | 585 | // | ||
1728 | 586 | // Ibid: When the component specifier is z, the output is the same as | ||
1729 | 587 | // for component specifier Z, except that it is prefixed by the | ||
1730 | 588 | // characters GMT or some localized equivalent. The prefix is omitted, | ||
1731 | 589 | // however, in cases where the timezone is identified by name rather | ||
1732 | 590 | // than by a numeric offset from UTC. | ||
1733 | 591 | // | ||
1734 | 592 | tmp = "GMT"; | ||
1735 | 593 | } | ||
1736 | 594 | |||
1737 | 595 | if ( mod.second.at_type == modifier::traditional && !hour && !min ) { | ||
1738 | 596 | // | ||
1739 | 597 | // Ibid: If the first presentation modifier is numeric, in any of the | ||
1740 | 598 | // above formats, and the second presentation modifier is t, then a | ||
1741 | 599 | // zero timezone offset (that is, UTC) is output as Z instead of a | ||
1742 | 600 | // signed numeric value. | ||
1743 | 601 | // | ||
1744 | 602 | tmp += 'Z'; | ||
1745 | 603 | break; | ||
1746 | 604 | } | ||
1747 | 605 | |||
1748 | 606 | if ( tz.isNegative() ) | ||
1749 | 607 | tmp += '-', hour = std::abs( hour ); | ||
1750 | 608 | else | ||
1751 | 609 | tmp += '+'; | ||
1752 | 610 | |||
1753 | 611 | if ( has_grouping_separators ) { | ||
1754 | 612 | // | ||
1755 | 613 | // Ibid: If the first presentation modifier is numeric with a grouping- | ||
1756 | 614 | // separator (for example 1:01 or 01.01), then the timezone offset is | ||
1757 | 615 | // output in hours and minutes, separated by the grouping separator, | ||
1758 | 616 | // even if the number of minutes is zero: for example +5:00 or +10.30. | ||
1759 | 617 | // | ||
1760 | 618 | int grouping_separators = 0; | ||
1761 | 619 | bool got_digit = false; | ||
1762 | 620 | int hm_width[] = { 0, 0 }; // hour/minute widths | ||
1763 | 621 | utf8_string<zstring const> const u_format( format ); | ||
1764 | 622 | utf8_string<zstring> u_tmp( tmp ); | ||
1765 | 623 | |||
1766 | 624 | FOR_EACH( utf8_string<zstring const>, i, u_format ) { | ||
1767 | 625 | unicode::code_point const cp = *i; | ||
1768 | 626 | if ( unicode::is_Nd( cp ) ) { | ||
1769 | 627 | got_digit = true; | ||
1770 | 628 | if ( grouping_separators < 2 ) | ||
1771 | 629 | ++hm_width[ grouping_separators ]; | ||
1772 | 630 | continue; | ||
1773 | 631 | } | ||
1774 | 632 | if ( got_digit && is_grouping_separator( cp ) ) { | ||
1775 | 633 | if ( ++grouping_separators == 1 ) { | ||
1776 | 634 | zstring tmp2( utf8::itou( hour, buf, mod.first.zero ) ); | ||
1777 | 635 | tmp += utf8::left_pad( &tmp2, hm_width[0], mod.first.zero ); | ||
1778 | 636 | } | ||
1779 | 637 | } else if ( grouping_separators ) | ||
1780 | 638 | grouping_separators = 99; | ||
1781 | 639 | u_tmp += cp; | ||
1782 | 640 | } | ||
1783 | 641 | |||
1784 | 642 | if ( hm_width[1] ) { | ||
1785 | 643 | zstring tmp2( utf8::itou( min, buf, mod.first.zero ) ); | ||
1786 | 644 | tmp += utf8::left_pad( &tmp2, hm_width[1], mod.first.zero ); | ||
1787 | 645 | } | ||
1788 | 646 | } else { | ||
1789 | 647 | utf8_string<zstring const> const u_format( format ); | ||
1790 | 648 | utf8_string<zstring const>::size_type const u_size( u_format.size() ); | ||
1791 | 649 | |||
1792 | 650 | if ( u_size <= 2 ) { | ||
1793 | 651 | // | ||
1794 | 652 | // Ibid: If the first presentation modifier is numeric and comprises | ||
1795 | 653 | // one or two digits with no grouping-separator (for example 1 or | ||
1796 | 654 | // 01), then the timezone is formatted as a displacement from UTC in | ||
1797 | 655 | // hours, preceded by a plus or minus sign: for example -5 or +03. If | ||
1798 | 656 | // the actual timezone offset is not an integral number of hours, | ||
1799 | 657 | // then the minutes part of the offset is appended, separated by a | ||
1800 | 658 | // colon: for example +10:30 or -1:15. | ||
1801 | 659 | // | ||
1802 | 660 | zstring tmp2( utf8::itou( hour, buf, mod.first.zero ) ); | ||
1803 | 661 | tmp += utf8::left_pad( &tmp2, u_size, mod.first.zero ); | ||
1804 | 662 | if ( min ) { | ||
1805 | 663 | tmp2 = utf8::itou( min, buf, mod.first.zero ); | ||
1806 | 664 | tmp += ':'; | ||
1807 | 665 | tmp += utf8::left_pad( &tmp2, 2, mod.first.zero ); | ||
1808 | 666 | } | ||
1809 | 667 | break; | ||
1810 | 668 | } | ||
1811 | 669 | if ( u_size <= 4 ) { | ||
1812 | 670 | // | ||
1813 | 671 | // Ibid: If the first presentation modifier is numeric and comprises | ||
1814 | 672 | // three or four digits with no grouping-separator, for example 001 | ||
1815 | 673 | // or 0001, then the timezone offset is shown in hours and minutes | ||
1816 | 674 | // with no separator, for example -0500 or +1030. | ||
1817 | 675 | // | ||
1818 | 676 | int const hhmm = hour * 100 + min; | ||
1819 | 677 | zstring tmp2( utf8::itou( hhmm, buf, mod.first.zero ) ); | ||
1820 | 678 | tmp += utf8::left_pad( &tmp2, u_size, mod.first.zero ); | ||
1821 | 679 | break; | ||
1822 | 680 | } | ||
1823 | 681 | } // else | ||
1824 | 682 | } // switch | ||
1825 | 683 | |||
1826 | 684 | append: | ||
1827 | 685 | *dest += tmp; | ||
1828 | 686 | } | ||
1829 | 687 | |||
1830 | 688 | static void append_weekday( unsigned mday, unsigned mon, unsigned year, | ||
1831 | 689 | modifier const &mod, zstring *dest ) { | ||
1832 | 690 | int wday = time::calc_wday( mday, mon, year ); | ||
1833 | 691 | |||
1834 | 692 | modifier mod_copy( mod ); | ||
1835 | 693 | if ( !mod.first.parsed ) | ||
1836 | 694 | mod_copy.first.type = modifier::name; | ||
1837 | 695 | |||
1838 | 696 | switch ( mod_copy.first.type ) { | ||
1839 | 697 | case modifier::name: | ||
1840 | 698 | case modifier::Name: | ||
1841 | 699 | case modifier::NAME: { | ||
1842 | 700 | zstring name( locale::get_weekday_name( wday, mod.lang, mod.country ) ); | ||
1843 | 701 | utf8_string<zstring> u_name( name ); | ||
1844 | 702 | if ( mod.gt_max_width( u_name.size() ) ) { | ||
1845 | 703 | // | ||
1846 | 704 | // XQuery 3.0 F&O: 9.8.4.1: If the full representation of the value | ||
1847 | 705 | // exceeds the specified maximum width, then the processor should | ||
1848 | 706 | // attempt to use an alternative shorter representation that fits | ||
1849 | 707 | // within the maximum width. Where the presentation modifier is N, n, | ||
1850 | 708 | // or Nn, this is done by abbreviating the name, using either | ||
1851 | 709 | // conventional abbreviations if available, or crude right-truncation | ||
1852 | 710 | // if not. | ||
1853 | 711 | // | ||
1854 | 712 | name = locale::get_weekday_abbr( wday, mod.lang, mod.country ); | ||
1855 | 713 | if ( mod.gt_max_width( u_name.size() ) ) | ||
1856 | 714 | u_name = u_name.substr( 0, mod.max_width ); | ||
1857 | 715 | } | ||
1858 | 716 | mod.append_if_fallback_lang( dest ); | ||
1859 | 717 | append_string( name, mod_copy, dest ); | ||
1860 | 718 | break; | ||
1861 | 719 | } | ||
1862 | 720 | default: { | ||
1863 | 721 | int const new_wday = calendar::convert_wday_to( wday, mod.cal ); | ||
1864 | 722 | if ( mod.cal_is_fallback || new_wday == -1 ) { | ||
1865 | 723 | // | ||
1866 | 724 | // Ibid: If the fallback representation uses a different calendar from | ||
1867 | 725 | // that requested, the output string must identify the calendar | ||
1868 | 726 | // actually used, for example by prefixing the string with [Calendar: | ||
1869 | 727 | // X] (where X is the calendar actually used), localized as appropriate | ||
1870 | 728 | // to the requested language. | ||
1871 | 729 | // | ||
1872 | 730 | ostringstream oss; | ||
1873 | 731 | // TODO: localize "Calendar" | ||
1874 | 732 | oss << "[Calendar: " | ||
1875 | 733 | << ( new_wday == -1 ? calendar::get_default() : mod.cal ) << ']'; | ||
1876 | 734 | *dest += oss.str(); | ||
1877 | 735 | } else | ||
1878 | 736 | wday = new_wday; | ||
1879 | 737 | append_number( wday, mod_copy, dest ); | ||
1880 | 738 | } | ||
1881 | 739 | } | ||
1882 | 740 | } | ||
1883 | 741 | |||
1884 | 742 | static void append_week_in_year( unsigned mday, unsigned mon, unsigned year, | ||
1885 | 743 | modifier const &mod, zstring *dest ) { | ||
1886 | 744 | int week = time::calendar::calc_week_in_year( mday, mon, year, mod.cal ); | ||
1887 | 745 | if ( week == -1 ) { | ||
1888 | 746 | week = time::calendar::calc_week_in_year( mday, mon, year, calendar::ISO ); | ||
1889 | 747 | ostringstream oss; | ||
1890 | 748 | // TODO: localize "Calendar" | ||
1891 | 749 | oss << "[Calendar: " << calendar::string_of[ calendar::ISO ] << ']'; | ||
1892 | 750 | *dest += oss.str(); | ||
1893 | 751 | } | ||
1894 | 752 | append_number( week, mod, dest ); | ||
1895 | 753 | } | ||
1896 | 754 | |||
1897 | 755 | static void append_year( int year, modifier const &mod, zstring *s ) { | ||
1898 | 756 | zstring tmp; | ||
1899 | 757 | append_number( year, mod, &tmp ); | ||
1900 | 758 | |||
1901 | 759 | if ( mod.first.type == modifier::arabic ) { | ||
1902 | 760 | utf8_string<zstring> u_tmp( tmp ); | ||
1903 | 761 | utf8_string<zstring>::size_type const u_size = u_tmp.size(); | ||
1904 | 762 | if ( mod.gt_max_width( u_size ) ) { | ||
1905 | 763 | // | ||
1906 | 764 | // XQuery 3.0 F&O: 9.8.4.1: If the full representation of the value | ||
1907 | 765 | // exceeds the specified maximum width, then the processor should attempt | ||
1908 | 766 | // to use an alternative shorter representation that fits within the | ||
1909 | 767 | // maximum width. ... In the case of the year component, setting | ||
1910 | 768 | // max-width requests omission of high-order digits from the year, for | ||
1911 | 769 | // example, if max-width is set to 2 then the year 2003 will be output as | ||
1912 | 770 | // 03. | ||
1913 | 771 | // | ||
1914 | 772 | u_tmp = u_tmp.substr( u_size - mod.max_width ); | ||
1915 | 773 | } | ||
1916 | 774 | } | ||
1917 | 775 | *s += tmp; | ||
1918 | 776 | } | ||
1919 | 777 | |||
1920 | 778 | static void parse_first_modifier( zstring const &picture_str, | ||
1921 | 779 | zstring::const_iterator *i, | ||
1922 | 780 | modifier *mod, QueryLoc const &loc ) { | ||
1923 | 781 | zstring::const_iterator &j = *i; | ||
1924 | 782 | ascii::skip_whitespace( picture_str, &j ); | ||
1925 | 783 | if ( j == picture_str.end() || *j == ',' ) { | ||
1926 | 784 | // | ||
1927 | 785 | // Assume that the ',' is the start of the width modifier (hence there is | ||
1928 | 786 | // neither a first nor second modifier). | ||
1929 | 787 | // | ||
1930 | 788 | return; | ||
1931 | 789 | } | ||
1932 | 790 | |||
1933 | 791 | utf8_string<zstring const> const u_picture_str( picture_str ); | ||
1934 | 792 | utf8_string<zstring const>::const_iterator u( u_picture_str.current( j ) ); | ||
1935 | 793 | utf8_string<zstring> u_mod_format( mod->first.format ); | ||
1936 | 794 | unicode::code_point cp = *u; | ||
1937 | 795 | |||
1938 | 796 | if ( cp != '#' && is_grouping_separator( cp ) ) { | ||
1939 | 797 | // | ||
1940 | 798 | // XQuery 3.0 F&O: 4.6.1: A grouping-separator-sign must not appear | ||
1941 | 799 | // at the start ... of the decimal-digit-pattern .... | ||
1942 | 800 | // | ||
1943 | 801 | throw XQUERY_EXCEPTION( | ||
1944 | 802 | err::FOFD1340, | ||
1945 | 803 | ERROR_PARAMS( | ||
1946 | 804 | picture_str, | ||
1947 | 805 | ZED( FOFD1340_NoGroupSepAtStart_3 ), | ||
1948 | 806 | unicode::printable_cp( cp ) | ||
1949 | 807 | ), | ||
1950 | 808 | ERROR_LOC( loc ) | ||
1951 | 809 | ); | ||
1952 | 810 | } | ||
1953 | 811 | |||
1954 | 812 | // | ||
1955 | 813 | // Because of: | ||
1956 | 814 | // | ||
1957 | 815 | // Ibid: if a variable marker contains one or more commas, then the last | ||
1958 | 816 | // comma is treated as introducing the width modifier, and all others are | ||
1959 | 817 | // treated as grouping separators. | ||
1960 | 818 | // | ||
1961 | 819 | // we have to count the number of commas in order to know when we've reached | ||
1962 | 820 | // the last one. | ||
1963 | 821 | // | ||
1964 | 822 | int commas = 0; | ||
1965 | 823 | for ( zstring::const_iterator c( *i ); c != picture_str.end(); ++c ) | ||
1966 | 824 | if ( *c == ',' ) | ||
1967 | 825 | ++commas; | ||
1968 | 826 | |||
1969 | 827 | unicode::code_point zero[2]; | ||
1970 | 828 | |||
1971 | 829 | if ( cp == '#' || unicode::is_Nd( cp, &zero[0] ) ) { | ||
1972 | 830 | bool got_grouping_separator = false; | ||
1973 | 831 | bool got_mandatory_digit = cp != '#'; | ||
1974 | 832 | |||
1975 | 833 | u_mod_format = *u; | ||
1976 | 834 | while ( ++u != u_picture_str.end() ) { | ||
1977 | 835 | cp = *u; | ||
1978 | 836 | if ( cp == '#' ) { | ||
1979 | 837 | if ( got_mandatory_digit ) { | ||
1980 | 838 | // | ||
1981 | 839 | // Ibid: There may be zero or more optional-digit-signs, and (if | ||
1982 | 840 | // present) these must precede all mandatory-digit-signs. | ||
1983 | 841 | // | ||
1984 | 842 | throw XQUERY_EXCEPTION( | ||
1985 | 843 | err::FOFD1340, | ||
1986 | 844 | ERROR_PARAMS( | ||
1987 | 845 | picture_str, | ||
1988 | 846 | ZED( FOFD1340_NoOptDigitAfterMandatory ) | ||
1989 | 847 | ), | ||
1990 | 848 | ERROR_LOC( loc ) | ||
1991 | 849 | ); | ||
1992 | 850 | } | ||
1993 | 851 | got_grouping_separator = false; | ||
1994 | 852 | } else if ( unicode::is_Nd( cp, &zero[ got_mandatory_digit ] ) ) { | ||
1995 | 853 | if ( got_mandatory_digit ) { | ||
1996 | 854 | if ( zero[1] != zero[0] ) { | ||
1997 | 855 | // | ||
1998 | 856 | // Ibid: All mandatory-digit-signs within the format token must be | ||
1999 | 857 | // from the same digit family, where a digit family is a sequence | ||
2000 | 858 | // of ten consecutive characters in Unicode category Nd, having | ||
2001 | 859 | // digit values 0 through 9. | ||
2002 | 860 | // | ||
2003 | 861 | throw XQUERY_EXCEPTION( | ||
2004 | 862 | err::FOFD1340, | ||
2005 | 863 | ERROR_PARAMS( | ||
2006 | 864 | picture_str, | ||
2007 | 865 | ZED( FOFD1340_DigitNotSameFamily_34 ), | ||
2008 | 866 | unicode::printable_cp( cp ), | ||
2009 | 867 | unicode::printable_cp( zero[1] ) | ||
2010 | 868 | ), | ||
2011 | 869 | ERROR_LOC( loc ) | ||
2012 | 870 | ); | ||
2013 | 871 | } | ||
2014 | 872 | // | ||
2015 | 873 | // Ibid: A format token containing more than one digit, such as 001 | ||
2016 | 874 | // or 9999, sets the minimum and maximum width to the number of | ||
2017 | 875 | // digits appearing in the format token. | ||
2018 | 876 | // | ||
2019 | 877 | if ( !mod->min_width ) | ||
2020 | 878 | mod->min_width = mod->max_width = 2; | ||
2021 | 879 | else | ||
2022 | 880 | mod->min_width = ++mod->max_width; | ||
2023 | 881 | } else | ||
2024 | 882 | got_mandatory_digit = true; | ||
2025 | 883 | got_grouping_separator = false; | ||
2026 | 884 | } else if ( cp == ';' || cp == ']' ) | ||
2027 | 885 | break; | ||
2028 | 886 | else if ( unicode::is_space( cp ) ) | ||
2029 | 887 | continue; | ||
2030 | 888 | else if ( is_grouping_separator( cp ) ) { | ||
2031 | 889 | if ( cp == ',' && !--commas ) { | ||
2032 | 890 | // | ||
2033 | 891 | // Ibid: if a variable marker contains one or more commas, then the | ||
2034 | 892 | // last comma is treated as introducing the width modifier, and all | ||
2035 | 893 | // others are treated as grouping separators. | ||
2036 | 894 | // | ||
2037 | 895 | break; | ||
2038 | 896 | } | ||
2039 | 897 | if ( got_grouping_separator ) { | ||
2040 | 898 | // | ||
2041 | 899 | // Ibid: A grouping-separator-sign must not appear ... adjacent to | ||
2042 | 900 | // another grouping-separator-sign. | ||
2043 | 901 | // | ||
2044 | 902 | throw XQUERY_EXCEPTION( | ||
2045 | 903 | err::FOFD1340, | ||
2046 | 904 | ERROR_PARAMS( | ||
2047 | 905 | picture_str, | ||
2048 | 906 | ZED( FOFD1340_NoAdjacentGroupSep_3 ), | ||
2049 | 907 | unicode::printable_cp( cp ) | ||
2050 | 908 | ), | ||
2051 | 909 | ERROR_LOC( loc ) | ||
2052 | 910 | ); | ||
2053 | 911 | } | ||
2054 | 912 | got_grouping_separator = true; | ||
2055 | 913 | mod->first.has_grouping_separators = true; | ||
2056 | 914 | } else | ||
2057 | 915 | break; | ||
2058 | 916 | |||
2059 | 917 | u_mod_format += cp; | ||
2060 | 918 | } // while | ||
2061 | 919 | if ( got_grouping_separator ) { | ||
2062 | 920 | // | ||
2063 | 921 | // Ibid: A grouping-separator-sign must not appear at the ... end of the | ||
2064 | 922 | // decimal-digit-pattern .... | ||
2065 | 923 | // | ||
2066 | 924 | throw XQUERY_EXCEPTION( | ||
2067 | 925 | err::FOFD1340, | ||
2068 | 926 | ERROR_PARAMS( | ||
2069 | 927 | picture_str, | ||
2070 | 928 | ZED( FOFD1340_NoGroupSepAtEnd_3 ), | ||
2071 | 929 | unicode::printable_cp( cp ) | ||
2072 | 930 | ), | ||
2073 | 931 | ERROR_LOC( loc ) | ||
2074 | 932 | ); | ||
2075 | 933 | } | ||
2076 | 934 | if ( !got_mandatory_digit ) { | ||
2077 | 935 | // | ||
2078 | 936 | // Ibid: There must be at least one mandatory-digit-sign. | ||
2079 | 937 | // | ||
2080 | 938 | throw XQUERY_EXCEPTION( | ||
2081 | 939 | err::FOFD1340, | ||
2082 | 940 | ERROR_PARAMS( picture_str, ZED( FOFD1340_MustBeOneMandatoryDigit ) ), | ||
2083 | 941 | ERROR_LOC( loc ) | ||
2084 | 942 | ); | ||
2085 | 943 | } | ||
2086 | 944 | mod->first.zero = zero[0]; | ||
2087 | 945 | j = u.base(); | ||
2088 | 946 | } else { | ||
2089 | 947 | switch ( *j++ ) { | ||
2090 | 948 | case 'A': | ||
2091 | 949 | mod->first.type = modifier::ALPHA; | ||
2092 | 950 | break; | ||
2093 | 951 | case 'a': | ||
2094 | 952 | mod->first.type = modifier::alpha; | ||
2095 | 953 | break; | ||
2096 | 954 | case 'I': | ||
2097 | 955 | mod->first.type = modifier::ROMAN; | ||
2098 | 956 | break; | ||
2099 | 957 | case 'i': | ||
2100 | 958 | mod->first.type = modifier::roman; | ||
2101 | 959 | break; | ||
2102 | 960 | case 'N': | ||
2103 | 961 | if ( j != picture_str.end() && *j == 'n' ) | ||
2104 | 962 | mod->first.type = modifier::Name, ++j; | ||
2105 | 963 | else | ||
2106 | 964 | mod->first.type = modifier::NAME; | ||
2107 | 965 | break; | ||
2108 | 966 | case 'n': | ||
2109 | 967 | mod->first.type = modifier::name; | ||
2110 | 968 | break; | ||
2111 | 969 | case 'W': | ||
2112 | 970 | if ( j != picture_str.end() && *j == 'w' ) | ||
2113 | 971 | mod->first.type = modifier::Words, ++j; | ||
2114 | 972 | else | ||
2115 | 973 | mod->first.type = modifier::WORDS; | ||
2116 | 974 | break; | ||
2117 | 975 | case 'w': | ||
2118 | 976 | mod->first.type = modifier::words; | ||
2119 | 977 | break; | ||
2120 | 978 | case 'Z': | ||
2121 | 979 | mod->first.type = modifier::military_tz; | ||
2122 | 980 | break; | ||
2123 | 981 | default: | ||
2124 | 982 | // | ||
2125 | 983 | // Ibid: If an implementation does not support a numbering sequence | ||
2126 | 984 | // represented by the given token, it must use a format token of 1. | ||
2127 | 985 | // | ||
2128 | 986 | mod->first.type = modifier::arabic; | ||
2129 | 987 | } // switch | ||
2130 | 988 | } | ||
2131 | 989 | mod->first.parsed = true; | ||
2132 | 990 | } | ||
2133 | 991 | |||
2134 | 992 | static void parse_second_modifier( zstring const &picture_str, | ||
2135 | 993 | zstring::const_iterator *i, modifier *mod, | ||
2136 | 994 | QueryLoc const &loc ) { | ||
2137 | 995 | zstring::const_iterator &j = *i; | ||
2138 | 996 | ascii::skip_whitespace( picture_str, &j ); | ||
2139 | 997 | if ( j == picture_str.end() ) | ||
2140 | 998 | return; | ||
2141 | 999 | switch ( *j ) { | ||
2142 | 1000 | case 'c': mod->second.co_type = modifier::cardinal ; break; | ||
2143 | 1001 | case 'o': mod->second.co_type = modifier::ordinal ; break; | ||
2144 | 1002 | case 'a': mod->second.at_type = modifier::alphabetic ; ++j; return; | ||
2145 | 1003 | case 't': mod->second.at_type = modifier::traditional; ++j; return; | ||
2146 | 1004 | default : return; | ||
2147 | 1005 | } | ||
2148 | 1006 | if ( ++j == picture_str.end() ) | ||
2149 | 1007 | return; | ||
2150 | 1008 | if ( *j == '(' ) { | ||
2151 | 1009 | while ( true ) { | ||
2152 | 1010 | if ( ++j == picture_str.end() ) | ||
2153 | 1011 | throw XQUERY_EXCEPTION( | ||
2154 | 1012 | err::FOFD1340, | ||
2155 | 1013 | ERROR_PARAMS( picture_str, ZED( CharExpected_3 ), ')' ), | ||
2156 | 1014 | ERROR_LOC( loc ) | ||
2157 | 1015 | ); | ||
2158 | 1016 | if ( *j == ')' ) | ||
2159 | 1017 | break; | ||
2160 | 1018 | mod->second.co_string += *j; | ||
2161 | 1019 | } | ||
2162 | 1020 | ++j; | ||
2163 | 1021 | } | ||
2164 | 1022 | } | ||
2165 | 1023 | |||
2166 | 1024 | static void parse_width_modifier( zstring const &picture_str, | ||
2167 | 1025 | zstring::const_iterator *i, modifier *mod, | ||
2168 | 1026 | QueryLoc const &loc ) { | ||
2169 | 1027 | zstring::const_iterator &j = *i; | ||
2170 | 1028 | |||
2171 | 1029 | ascii::skip_whitespace( picture_str, &j ); | ||
2172 | 1030 | if ( j == picture_str.end() || (*j != ',' && *j != ';') ) | ||
2173 | 1031 | return; | ||
2174 | 1032 | ascii::skip_whitespace( picture_str, &++j ); | ||
2175 | 1033 | if ( j == picture_str.end() ) | ||
2176 | 1034 | goto bad_width_modifier; | ||
2177 | 1035 | if ( *j == '*' ) { | ||
2178 | 1036 | mod->min_width = 0; | ||
2179 | 1037 | ++j; | ||
2180 | 1038 | } else { | ||
2181 | 1039 | try { | ||
2182 | 1040 | mod->min_width = static_cast<modifier::width_type>( | ||
2183 | 1041 | ztd::atoull( j, picture_str.end(), &j ) | ||
2184 | 1042 | ); | ||
2185 | 1043 | } | ||
2186 | 1044 | catch ( std::exception const& ) { | ||
2187 | 1045 | goto bad_width_modifier; | ||
2188 | 1046 | } | ||
2189 | 1047 | } | ||
2190 | 1048 | |||
2191 | 1049 | mod->max_width = 0; | ||
2192 | 1050 | |||
2193 | 1051 | ascii::skip_whitespace( picture_str, &j ); | ||
2194 | 1052 | if ( j == picture_str.end() || *j != '-' ) | ||
2195 | 1053 | return; | ||
2196 | 1054 | ascii::skip_whitespace( picture_str, &++j ); | ||
2197 | 1055 | if ( j == picture_str.end() ) | ||
2198 | 1056 | goto bad_width_modifier; | ||
2199 | 1057 | if ( *j == '*' ) | ||
2200 | 1058 | ++j; | ||
2201 | 1059 | else { | ||
2202 | 1060 | try { | ||
2203 | 1061 | mod->max_width = static_cast<modifier::width_type>( | ||
2204 | 1062 | ztd::atoull( j, picture_str.end(), &j ) | ||
2205 | 1063 | ); | ||
2206 | 1064 | } | ||
2207 | 1065 | catch ( std::exception const& ) { | ||
2208 | 1066 | goto bad_width_modifier; | ||
2209 | 1067 | } | ||
2210 | 1068 | } | ||
2211 | 1069 | |||
2212 | 1070 | return; | ||
2213 | 1071 | |||
2214 | 1072 | bad_width_modifier: | ||
2215 | 1073 | throw XQUERY_EXCEPTION( | ||
2216 | 1074 | err::FOFD1340, | ||
2217 | 1075 | ERROR_PARAMS( picture_str, ZED( FOFD1340_BadWidthModifier ) ), | ||
2218 | 1076 | ERROR_LOC( loc ) | ||
2219 | 1077 | ); | ||
2220 | 1078 | } | ||
2221 | 1079 | |||
2222 | 1080 | static int get_data_type( char component ) { | ||
2223 | 1081 | switch ( component ) { | ||
2224 | 1082 | case 'D': return DateTime::DAY_DATA; | ||
2225 | 1083 | case 'd': return DateTime::DAY_DATA; | ||
2226 | 1084 | case 'E': return DateTime::YEAR_DATA; | ||
2227 | 1085 | case 'F': return DateTime::DAY_DATA; | ||
2228 | 1086 | case 'f': return DateTime::FRACSECONDS_DATA; | ||
2229 | 1087 | case 'H': return DateTime::HOUR_DATA; | ||
2230 | 1088 | case 'h': return DateTime::HOUR_DATA; | ||
2231 | 1089 | case 'm': return DateTime::MINUTE_DATA; | ||
2232 | 1090 | case 'M': return DateTime::MONTH_DATA; | ||
2233 | 1091 | case 'P': return DateTime::HOUR_DATA; | ||
2234 | 1092 | case 's': return DateTime::SECONDS_DATA; | ||
2235 | 1093 | case 'W': return DateTime::DAY_DATA; | ||
2236 | 1094 | case 'w': return DateTime::DAY_DATA; | ||
2237 | 1095 | case 'Y': return DateTime::YEAR_DATA; | ||
2238 | 1096 | default : return -1; | ||
2239 | 1097 | } | ||
2240 | 1098 | } | ||
2241 | 1099 | |||
2242 | 1100 | bool FnFormatDateTimeIterator::nextImpl( store::Item_t& result, | ||
2243 | 1101 | PlanState &planState ) const { | ||
2244 | 1102 | zstring picture_str, result_str, item_str; | ||
2245 | 1103 | xs_dateTime dateTime; | ||
2246 | 1104 | calendar::type cal = calendar::unknown; | ||
2247 | 1105 | iso639_1::type lang = iso639_1::unknown; | ||
2248 | 1106 | iso3166_1::type country = iso3166_1::unknown; | ||
2249 | 1107 | bool cal_is_fallback = false, lang_is_fallback = false; | ||
2250 | 1108 | bool in_variable_marker; | ||
2251 | 1109 | store::Item_t item; | ||
2252 | 1110 | PlanIteratorState *state; | ||
2253 | 1111 | |||
2254 | 1112 | DEFAULT_STACK_INIT( PlanIteratorState, state, planState); | ||
2255 | 1113 | |||
2256 | 1114 | if ( !consumeNext( item, theChildren[0].getp(), planState ) ) { | ||
2257 | 1115 | // Got the empty sequence -- return same | ||
2258 | 1116 | STACK_PUSH( false, state ); | ||
2259 | 1117 | } else { | ||
2260 | 1118 | dateTime = item->getDateTimeValue(); | ||
2261 | 1119 | consumeNext( item, theChildren[1].getp(), planState ); | ||
2262 | 1120 | item->getStringValue2( picture_str ); | ||
2263 | 1121 | |||
2264 | 1122 | if ( theChildren.size() > 2 ) { | ||
2265 | 1123 | consumeNext( item, theChildren[2].getp(), planState ); | ||
2266 | 1124 | if ( !locale::parse( item->getStringValue(), &lang, &country ) || | ||
2267 | 1125 | !locale::is_supported( lang, country ) ) { | ||
2268 | 1126 | lang = iso639_1::unknown; | ||
2269 | 1127 | lang_is_fallback = true; | ||
2270 | 1128 | } | ||
2271 | 1129 | |||
2272 | 1130 | consumeNext( item, theChildren[3].getp(), planState ); | ||
2273 | 1131 | item->getStringValue2( item_str ); | ||
2274 | 1132 | // TODO: handle calendar being a QName. | ||
2275 | 1133 | cal = calendar::find( item_str ); | ||
2276 | 1134 | if ( !cal ) | ||
2277 | 1135 | cal_is_fallback = true; | ||
2278 | 1136 | |||
2279 | 1137 | consumeNext( item, theChildren[4].getp(), planState ); | ||
2280 | 1138 | item->getStringValue2( item_str ); | ||
2281 | 1139 | // TODO: do something with place | ||
2282 | 1140 | } | ||
2283 | 1141 | |||
2284 | 1142 | if ( !cal ) { | ||
2285 | 1143 | // | ||
2286 | 1144 | // XQuery 3.0 F&O: 9.8.4.3: If the $calendar argument is omitted or is | ||
2287 | 1145 | // set to an empty sequence then the default calendar defined in the | ||
2288 | 1146 | // dynamic context is used. | ||
2289 | 1147 | // | ||
2290 | 1148 | cal = planState.theLocalDynCtx->get_calendar(); | ||
2291 | 1149 | } | ||
2292 | 1150 | |||
2293 | 1151 | if ( !lang ) { | ||
2294 | 1152 | // | ||
2295 | 1153 | // Ibid: If the $language argument is omitted or is set to an empty | ||
2296 | 1154 | // sequence, or if it is set to an invalid value or a value that the | ||
2297 | 1155 | // implementation does not recognize, then the processor uses the default | ||
2298 | 1156 | // language defined in the dynamic context. | ||
2299 | 1157 | // | ||
2300 | 1158 | planState.theLocalDynCtx->get_locale( &lang, &country ); | ||
2301 | 1159 | } | ||
2302 | 1160 | |||
2303 | 1161 | char component; | ||
2304 | 1162 | in_variable_marker = false; | ||
2305 | 1163 | |||
2306 | 1164 | FOR_EACH( zstring, i, picture_str ) { | ||
2307 | 1165 | if ( !in_variable_marker ) { | ||
2308 | 1166 | switch ( *i ) { | ||
2309 | 1167 | case '[': | ||
2310 | 1168 | if ( ztd::peek( picture_str, i ) == '[' ) | ||
2311 | 1169 | ++i; | ||
2312 | 1170 | else { | ||
2313 | 1171 | component = 0; | ||
2314 | 1172 | in_variable_marker = true; | ||
2315 | 1173 | continue; | ||
2316 | 1174 | } | ||
2317 | 1175 | break; | ||
2318 | 1176 | case ']': | ||
2319 | 1177 | if ( ztd::peek( picture_str, i ) == ']' ) | ||
2320 | 1178 | ++i; | ||
2321 | 1179 | break; | ||
2322 | 1180 | } | ||
2323 | 1181 | result_str += *i; | ||
2324 | 1182 | continue; | ||
2325 | 1183 | } | ||
2326 | 1184 | |||
2327 | 1185 | if ( ascii::is_space( *i ) ) | ||
2328 | 1186 | continue; // ignore all whitespace | ||
2329 | 1187 | |||
2330 | 1188 | switch ( *i ) { | ||
2331 | 1189 | case ']': | ||
2332 | 1190 | if ( !component ) | ||
2333 | 1191 | throw XQUERY_EXCEPTION( | ||
2334 | 1192 | err::FOFD1340, | ||
2335 | 1193 | ERROR_PARAMS( picture_str, ZED( FOFD1340_NoComponent ) ), | ||
2336 | 1194 | ERROR_LOC( loc ) | ||
2337 | 1195 | ); | ||
2338 | 1196 | component = 0; | ||
2339 | 1197 | in_variable_marker = false; | ||
2340 | 1198 | continue; | ||
2341 | 1199 | case 'C': | ||
2342 | 1200 | case 'D': | ||
2343 | 1201 | case 'd': | ||
2344 | 1202 | case 'E': | ||
2345 | 1203 | case 'F': | ||
2346 | 1204 | case 'f': | ||
2347 | 1205 | case 'H': | ||
2348 | 1206 | case 'h': | ||
2349 | 1207 | case 'M': | ||
2350 | 1208 | case 'm': | ||
2351 | 1209 | case 'P': | ||
2352 | 1210 | case 's': | ||
2353 | 1211 | case 'W': | ||
2354 | 1212 | case 'w': | ||
2355 | 1213 | case 'Y': | ||
2356 | 1214 | case 'Z': | ||
2357 | 1215 | case 'z': | ||
2358 | 1216 | #if 0 | ||
2359 | 1217 | if ( component ) | ||
2360 | 1218 | throw XQUERY_EXCEPTION( | ||
2361 | 1219 | err::FOFD1340, | ||
2362 | 1220 | ERROR_PARAMS( | ||
2363 | 1221 | picture_str, ZED( FOFD1340_MultipleComponent_3 ), *i | ||
2364 | 1222 | ), | ||
2365 | 1223 | ERROR_LOC( loc ) | ||
2366 | 1224 | ); | ||
2367 | 1225 | #endif | ||
2368 | 1226 | component = *i; | ||
2369 | 1227 | break; | ||
2370 | 1228 | default: | ||
2371 | 1229 | throw XQUERY_EXCEPTION( | ||
2372 | 1230 | err::FOFD1340, | ||
2373 | 1231 | ERROR_PARAMS( picture_str, ZED( FOFD1340_BadComponent_3 ), *i ), | ||
2374 | 1232 | ERROR_LOC( loc ) | ||
2375 | 1233 | ); | ||
2376 | 1234 | } // switch | ||
2377 | 1235 | if ( ++i == picture_str.end() ) | ||
2378 | 1236 | goto eos; | ||
2379 | 1237 | |||
2380 | 1238 | modifier mod; | ||
2381 | 1239 | mod.lang = lang; | ||
2382 | 1240 | mod.lang_is_fallback = lang_is_fallback; | ||
2383 | 1241 | mod.country = country; | ||
2384 | 1242 | mod.cal = cal; | ||
2385 | 1243 | mod.cal_is_fallback = cal_is_fallback; | ||
2386 | 1244 | |||
2387 | 1245 | if ( *i != ']' ) { | ||
2388 | 1246 | parse_first_modifier( picture_str, &i, &mod, loc ); | ||
2389 | 1247 | if ( i == picture_str.end() ) | ||
2390 | 1248 | goto eos; | ||
2391 | 1249 | if ( *i != ']' ) { | ||
2392 | 1250 | parse_second_modifier( picture_str, &i, &mod, loc ); | ||
2393 | 1251 | if ( i == picture_str.end() ) | ||
2394 | 1252 | goto eos; | ||
2395 | 1253 | parse_width_modifier( picture_str, &i, &mod, loc ); | ||
2396 | 1254 | if ( i == picture_str.end() ) | ||
2397 | 1255 | goto eos; | ||
2398 | 1256 | } | ||
2399 | 1257 | } | ||
2400 | 1258 | if ( *i == ']' ) | ||
2401 | 1259 | --i; | ||
2402 | 1260 | |||
2403 | 1261 | int const data_type = get_data_type( component ); | ||
2404 | 1262 | if ( data_type != -1 && !DateTime::FACET_MEMBERS[facet_type][data_type] ) | ||
2405 | 1263 | throw XQUERY_EXCEPTION( | ||
2406 | 1264 | err::FOFD1350, ERROR_PARAMS( component ), ERROR_LOC( loc ) | ||
2407 | 1265 | ); | ||
2408 | 1266 | |||
2409 | 1267 | switch ( component ) { | ||
2410 | 1268 | case 'C': { // calendar | ||
2411 | 1269 | modifier mod_copy( mod ); | ||
2412 | 1270 | if ( !mod.first.parsed ) | ||
2413 | 1271 | mod_copy.first.type = modifier::name; | ||
2414 | 1272 | append_string( "gregorian", mod_copy, &result_str ); | ||
2415 | 1273 | break; | ||
2416 | 1274 | } | ||
2417 | 1275 | case 'D': | ||
2418 | 1276 | append_number( dateTime.getDay(), mod, &result_str ); | ||
2419 | 1277 | break; | ||
2420 | 1278 | case 'd': | ||
2421 | 1279 | append_number( dateTime.getDayOfYear(), mod, &result_str ); | ||
2422 | 1280 | break; | ||
2423 | 1281 | case 'E': { // era | ||
2424 | 1282 | modifier mod_copy( mod ); | ||
2425 | 1283 | if ( !mod.first.parsed ) | ||
2426 | 1284 | mod_copy.first.type = modifier::name; | ||
2427 | 1285 | int const year = dateTime.getYear(); | ||
2428 | 1286 | zstring const era( year > 0 ? "ad" : year < 0 ? "bc" : "" ); | ||
2429 | 1287 | append_string( era, mod_copy, &result_str ); | ||
2430 | 1288 | break; | ||
2431 | 1289 | } | ||
2432 | 1290 | case 'F': { | ||
2433 | 1291 | modifier mod_copy( mod ); | ||
2434 | 1292 | if ( !mod.first.parsed ) | ||
2435 | 1293 | mod_copy.first.type = modifier::name; | ||
2436 | 1294 | append_weekday( | ||
2437 | 1295 | dateTime.getDay(), dateTime.getMonth() - 1, dateTime.getYear(), | ||
2438 | 1296 | mod_copy, &result_str | ||
2439 | 1297 | ); | ||
2440 | 1298 | break; | ||
2441 | 1299 | } | ||
2442 | 1300 | case 'f': | ||
2443 | 1301 | append_fractional_seconds( | ||
2444 | 1302 | dateTime.getFractionalSeconds(), mod, &result_str | ||
2445 | 1303 | ); | ||
2446 | 1304 | break; | ||
2447 | 1305 | case 'H': // hour (24 hours) | ||
2448 | 1306 | append_number( dateTime.getHours(), mod, &result_str ); | ||
2449 | 1307 | break; | ||
2450 | 1308 | case 'h': // hour (12 hours) | ||
2451 | 1309 | // Convert hour from: 0 1 ... 12 13 ... 23 | ||
2452 | 1310 | // to: 12 1 ... 12 1 ... 11 | ||
2453 | 1311 | append_number( | ||
2454 | 1312 | 1 + (11 + dateTime.getHours()) % 12, mod, &result_str | ||
2455 | 1313 | ); | ||
2456 | 1314 | break; | ||
2457 | 1315 | case 'M': | ||
2458 | 1316 | append_month( dateTime.getMonth() - 1, mod, &result_str ); | ||
2459 | 1317 | break; | ||
2460 | 1318 | case 'm': { | ||
2461 | 1319 | modifier mod_copy( mod ); | ||
2462 | 1320 | mod_copy.set_default_width( 2 ); | ||
2463 | 1321 | append_number( dateTime.getMinutes(), mod_copy, &result_str ); | ||
2464 | 1322 | break; | ||
2465 | 1323 | } | ||
2466 | 1324 | case 'P': { | ||
2467 | 1325 | modifier mod_copy( mod ); | ||
2468 | 1326 | if ( !mod.first.parsed ) | ||
2469 | 1327 | mod_copy.first.type = modifier::name; | ||
2470 | 1328 | append_string( | ||
2471 | 1329 | locale::get_time_ampm( dateTime.getHours() >= 12, lang, country ), | ||
2472 | 1330 | mod_copy, &result_str | ||
2473 | 1331 | ); | ||
2474 | 1332 | break; | ||
2475 | 1333 | } | ||
2476 | 1334 | case 's': { | ||
2477 | 1335 | modifier mod_copy( mod ); | ||
2478 | 1336 | mod_copy.set_default_width( 2 ); | ||
2479 | 1337 | append_number( dateTime.getIntSeconds(), mod_copy, &result_str ); | ||
2480 | 1338 | break; | ||
2481 | 1339 | } | ||
2482 | 1340 | case 'W': | ||
2483 | 1341 | append_week_in_year( | ||
2484 | 1342 | dateTime.getDay(), dateTime.getMonth() - 1, dateTime.getYear(), | ||
2485 | 1343 | mod, &result_str | ||
2486 | 1344 | ); | ||
2487 | 1345 | break; | ||
2488 | 1346 | case 'w': | ||
2489 | 1347 | append_number( dateTime.getWeekInMonth(), mod, &result_str ); | ||
2490 | 1348 | break; | ||
2491 | 1349 | case 'Y': | ||
2492 | 1350 | append_year( std::abs( dateTime.getYear() ), mod, &result_str ); | ||
2493 | 1351 | break; | ||
2494 | 1352 | case 'Z': | ||
2495 | 1353 | case 'z': | ||
2496 | 1354 | append_timezone( | ||
2497 | 1355 | component, dateTime.getTimezone(), mod, &result_str | ||
2498 | 1356 | ); | ||
2499 | 1357 | break; | ||
2500 | 1358 | } // switch | ||
2501 | 1359 | } // for | ||
2502 | 1360 | |||
2503 | 1361 | if ( in_variable_marker ) | ||
2504 | 1362 | eos: throw XQUERY_EXCEPTION( | ||
2505 | 1363 | err::FOFD1340, | ||
2506 | 1364 | ERROR_PARAMS( picture_str, ZED( CharExpected_3 ), ']' ), | ||
2507 | 1365 | ERROR_LOC( loc ) | ||
2508 | 1366 | ); | ||
2509 | 1367 | |||
2510 | 1368 | STACK_PUSH( GENV_ITEMFACTORY->createString( result, result_str ), state ); | ||
2511 | 1369 | } | ||
2512 | 1370 | |||
2513 | 1371 | STACK_END( state ); | ||
2514 | 1372 | } | ||
2515 | 1373 | |||
2516 | 1374 | /////////////////////////////////////////////////////////////////////////////// | ||
2517 | 1375 | |||
2518 | 1376 | } // namespace zorba | ||
2519 | 1377 | /* vim:set et sw=2 ts=2: */ | ||
2520 | 0 | 1378 | ||
2521 | === added file 'src/runtime/durations_dates_times/format_dateTime.h' | |||
2522 | --- src/runtime/durations_dates_times/format_dateTime.h 1970-01-01 00:00:00 +0000 | |||
2523 | +++ src/runtime/durations_dates_times/format_dateTime.h 2013-03-21 16:00:34 +0000 | |||
2524 | @@ -0,0 +1,81 @@ | |||
2525 | 1 | /* | ||
2526 | 2 | * Copyright 2006-2008 The FLWOR Foundation. | ||
2527 | 3 | * | ||
2528 | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
2529 | 5 | * you may not use this file except in compliance with the License. | ||
2530 | 6 | * You may obtain a copy of the License at | ||
2531 | 7 | * | ||
2532 | 8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
2533 | 9 | * | ||
2534 | 10 | * Unless required by applicable law or agreed to in writing, software | ||
2535 | 11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
2536 | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
2537 | 13 | * See the License for the specific language governing permissions and | ||
2538 | 14 | * limitations under the License. | ||
2539 | 15 | */ | ||
2540 | 16 | |||
2541 | 17 | #ifndef ZORBA_RUNTIME_FORMAT_DATETIME_H | ||
2542 | 18 | #define ZORBA_RUNTIME_FORMAT_DATETIME_H | ||
2543 | 19 | |||
2544 | 20 | #include "common/shared_types.h" | ||
2545 | 21 | #include "zorbatypes/datetime.h" | ||
2546 | 22 | |||
2547 | 23 | #include "runtime/base/binarybase.h" | ||
2548 | 24 | #include "runtime/base/unarybase.h" | ||
2549 | 25 | #include "runtime/base/narybase.h" | ||
2550 | 26 | |||
2551 | 27 | namespace zorba { | ||
2552 | 28 | |||
2553 | 29 | /////////////////////////////////////////////////////////////////////////////// | ||
2554 | 30 | |||
2555 | 31 | // XQuery 3.0 DateTime formatting | ||
2556 | 32 | class FnFormatDateTimeIterator : | ||
2557 | 33 | public NaryBaseIterator<FnFormatDateTimeIterator,PlanIteratorState> | ||
2558 | 34 | { | ||
2559 | 35 | |||
2560 | 36 | public: | ||
2561 | 37 | SERIALIZABLE_CLASS(FnFormatDateTimeIterator); | ||
2562 | 38 | |||
2563 | 39 | SERIALIZABLE_CLASS_CONSTRUCTOR2T( | ||
2564 | 40 | FnFormatDateTimeIterator, | ||
2565 | 41 | NaryBaseIterator<FnFormatDateTimeIterator, PlanIteratorState >); | ||
2566 | 42 | |||
2567 | 43 | void serialize( ::zorba::serialization::Archiver &ar ) | ||
2568 | 44 | { | ||
2569 | 45 | serialize_baseclass(ar, | ||
2570 | 46 | (NaryBaseIterator<FnFormatDateTimeIterator, PlanIteratorState >*)this); | ||
2571 | 47 | |||
2572 | 48 | SERIALIZE_ENUM(DateTime::FACET_TYPE, facet_type); | ||
2573 | 49 | } | ||
2574 | 50 | |||
2575 | 51 | public: | ||
2576 | 52 | FnFormatDateTimeIterator( | ||
2577 | 53 | static_context *sctx, | ||
2578 | 54 | QueryLoc const &loc, | ||
2579 | 55 | std::vector<PlanIter_t> &aChildren, | ||
2580 | 56 | DateTime::FACET_TYPE a_facet_type = DateTime::DATETIME_FACET) | ||
2581 | 57 | : | ||
2582 | 58 | NaryBaseIterator<FnFormatDateTimeIterator, PlanIteratorState>(sctx, loc, aChildren), | ||
2583 | 59 | facet_type(a_facet_type) | ||
2584 | 60 | { | ||
2585 | 61 | } | ||
2586 | 62 | |||
2587 | 63 | void accept( PlanIterVisitor& ) const; | ||
2588 | 64 | |||
2589 | 65 | bool nextImpl( store::Item_t&, PlanState& ) const; | ||
2590 | 66 | |||
2591 | 67 | private: | ||
2592 | 68 | DateTime::FACET_TYPE facet_type; | ||
2593 | 69 | }; | ||
2594 | 70 | |||
2595 | 71 | /////////////////////////////////////////////////////////////////////////////// | ||
2596 | 72 | |||
2597 | 73 | } // namespace zorba | ||
2598 | 74 | |||
2599 | 75 | #endif /* ZORBA_RUNTIME_FORMAT_DATETIME_H */ | ||
2600 | 76 | /* | ||
2601 | 77 | * Local variables: | ||
2602 | 78 | * mode: c++ | ||
2603 | 79 | * End: | ||
2604 | 80 | */ | ||
2605 | 81 | /* vim:set et sw=2 ts=2: */ | ||
2606 | 0 | 82 | ||
2607 | === modified file 'src/runtime/visitors/printer_visitor_impl.cpp' | |||
2608 | --- src/runtime/visitors/printer_visitor_impl.cpp 2013-03-05 12:34:19 +0000 | |||
2609 | +++ src/runtime/visitors/printer_visitor_impl.cpp 2013-03-21 16:00:34 +0000 | |||
2610 | @@ -46,6 +46,7 @@ | |||
2611 | 46 | #include "runtime/core/arithmetic_impl.h" | 46 | #include "runtime/core/arithmetic_impl.h" |
2612 | 47 | #include "runtime/sequences/SequencesImpl.h" | 47 | #include "runtime/sequences/SequencesImpl.h" |
2613 | 48 | #include "runtime/durations_dates_times/DurationsDatesTimesImpl.h" | 48 | #include "runtime/durations_dates_times/DurationsDatesTimesImpl.h" |
2614 | 49 | #include "runtime/durations_dates_times/format_dateTime.h" | ||
2615 | 49 | #ifdef ZORBA_WITH_DEBUGGER | 50 | #ifdef ZORBA_WITH_DEBUGGER |
2616 | 50 | #include "runtime/debug/debug_iterator.h" | 51 | #include "runtime/debug/debug_iterator.h" |
2617 | 51 | #endif | 52 | #endif |
2618 | 52 | 53 | ||
2619 | === modified file 'src/unit_tests/CMakeLists.txt' | |||
2620 | --- src/unit_tests/CMakeLists.txt 2013-03-17 04:47:01 +0000 | |||
2621 | +++ src/unit_tests/CMakeLists.txt 2013-03-21 16:00:34 +0000 | |||
2622 | @@ -22,6 +22,7 @@ | |||
2623 | 22 | test_mem_sizeof.cpp | 22 | test_mem_sizeof.cpp |
2624 | 23 | test_parameters.cpp | 23 | test_parameters.cpp |
2625 | 24 | test_string.cpp | 24 | test_string.cpp |
2626 | 25 | test_time.cpp | ||
2627 | 25 | test_time_parse.cpp | 26 | test_time_parse.cpp |
2628 | 26 | test_uri.cpp | 27 | test_uri.cpp |
2629 | 27 | test_uuid.cpp | 28 | test_uuid.cpp |
2630 | 28 | 29 | ||
2631 | === added file 'src/unit_tests/test_time.cpp' | |||
2632 | --- src/unit_tests/test_time.cpp 1970-01-01 00:00:00 +0000 | |||
2633 | +++ src/unit_tests/test_time.cpp 2013-03-21 16:00:34 +0000 | |||
2634 | @@ -0,0 +1,118 @@ | |||
2635 | 1 | /* | ||
2636 | 2 | * Copyright 2006-2008 The FLWOR Foundation. | ||
2637 | 3 | * | ||
2638 | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
2639 | 5 | * you may not use this file except in compliance with the License. | ||
2640 | 6 | * You may obtain a copy of the License at | ||
2641 | 7 | * | ||
2642 | 8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
2643 | 9 | * | ||
2644 | 10 | * Unless required by applicable law or agreed to in writing, software | ||
2645 | 11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
2646 | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
2647 | 13 | * See the License for the specific language governing permissions and | ||
2648 | 14 | * limitations under the License. | ||
2649 | 15 | */ | ||
2650 | 16 | |||
2651 | 17 | #include "stdafx.h" | ||
2652 | 18 | |||
2653 | 19 | #include <cstring> | ||
2654 | 20 | #include <functional> | ||
2655 | 21 | #include <iostream> | ||
2656 | 22 | #include <stdexcept> | ||
2657 | 23 | #include <string> | ||
2658 | 24 | |||
2659 | 25 | #include "util/ascii_util.h" | ||
2660 | 26 | #include "util/stl_util.h" | ||
2661 | 27 | #include "util/time_util.h" | ||
2662 | 28 | #include "zorbatypes/zstring.h" | ||
2663 | 29 | |||
2664 | 30 | using namespace std; | ||
2665 | 31 | using namespace zorba; | ||
2666 | 32 | using namespace zorba::time; | ||
2667 | 33 | |||
2668 | 34 | /////////////////////////////////////////////////////////////////////////////// | ||
2669 | 35 | |||
2670 | 36 | static int failures; | ||
2671 | 37 | static int test_no; | ||
2672 | 38 | |||
2673 | 39 | static bool assert_true( int no, char const *expr, int line, bool result ) { | ||
2674 | 40 | if ( !result ) { | ||
2675 | 41 | cout << '#' << no << " FAILED, line " << line << ": " << expr << endl; | ||
2676 | 42 | ++failures; | ||
2677 | 43 | } | ||
2678 | 44 | return result; | ||
2679 | 45 | } | ||
2680 | 46 | |||
2681 | 47 | #define ASSERT_TRUE( NO, EXPR ) assert_true( NO, #EXPR, __LINE__, !!(EXPR) ) | ||
2682 | 48 | |||
2683 | 49 | /////////////////////////////////////////////////////////////////////////////// | ||
2684 | 50 | |||
2685 | 51 | static void test_calc_week_in_year() { | ||
2686 | 52 | struct test_type { | ||
2687 | 53 | unsigned mday, mon, year; | ||
2688 | 54 | time::calendar::type cal; | ||
2689 | 55 | int expected; | ||
2690 | 56 | }; | ||
2691 | 57 | static test_type const test[] = { | ||
2692 | 58 | /* 1 */ { 1, time::jan, 2013, calendar::AD, 1 }, | ||
2693 | 59 | /* 2 */ { 2, time::jan, 2013, calendar::AD, 1 }, | ||
2694 | 60 | /* 3 */ { 3, time::jan, 2013, calendar::AD, 1 }, | ||
2695 | 61 | /* 4 */ { 4, time::jan, 2013, calendar::AD, 1 }, | ||
2696 | 62 | /* 5 */ { 5, time::jan, 2013, calendar::AD, 1 }, | ||
2697 | 63 | /* 6 */ { 6, time::jan, 2013, calendar::AD, 2 }, | ||
2698 | 64 | /* 7 */ { 28, time::dec, 2013, calendar::AD, 52 }, | ||
2699 | 65 | /* 8 */ { 31, time::dec, 2013, calendar::AD, 53 }, | ||
2700 | 66 | |||
2701 | 67 | /* 9 */ { 1, time::jan, 2013, calendar::ISO, 1 }, | ||
2702 | 68 | /* 10 */ { 2, time::jan, 2013, calendar::ISO, 1 }, | ||
2703 | 69 | /* 11 */ { 3, time::jan, 2013, calendar::ISO, 1 }, | ||
2704 | 70 | /* 12 */ { 4, time::jan, 2013, calendar::ISO, 1 }, | ||
2705 | 71 | /* 13 */ { 5, time::jan, 2013, calendar::ISO, 1 }, | ||
2706 | 72 | /* 14 */ { 6, time::jan, 2013, calendar::ISO, 1 }, | ||
2707 | 73 | /* 15 */ { 7, time::jan, 2013, calendar::ISO, 2 }, | ||
2708 | 74 | |||
2709 | 75 | // Test cases taken from http://en.wikipedia.org/wiki/ISO_week_date | ||
2710 | 76 | /* 16 */ { 1, time::jan, 2005, calendar::ISO, 53 }, | ||
2711 | 77 | /* 17 */ { 2, time::jan, 2005, calendar::ISO, 53 }, | ||
2712 | 78 | /* 18 */ { 31, time::dec, 2005, calendar::ISO, 52 }, | ||
2713 | 79 | /* 19 */ { 1, time::jan, 2007, calendar::ISO, 1 }, | ||
2714 | 80 | /* 20 */ { 30, time::dec, 2007, calendar::ISO, 52 }, | ||
2715 | 81 | /* 21 */ { 31, time::dec, 2007, calendar::ISO, 1 }, | ||
2716 | 82 | /* 22 */ { 1, time::jan, 2008, calendar::ISO, 1 }, | ||
2717 | 83 | /* 23 */ { 28, time::dec, 2008, calendar::ISO, 52 }, | ||
2718 | 84 | /* 24 */ { 29, time::dec, 2008, calendar::ISO, 1 }, | ||
2719 | 85 | /* 25 */ { 30, time::dec, 2008, calendar::ISO, 1 }, | ||
2720 | 86 | /* 26 */ { 31, time::dec, 2008, calendar::ISO, 1 }, | ||
2721 | 87 | /* 27 */ { 31, time::dec, 2009, calendar::ISO, 53 }, | ||
2722 | 88 | /* 28 */ { 1, time::jan, 2010, calendar::ISO, 53 }, | ||
2723 | 89 | /* 29 */ { 2, time::jan, 2010, calendar::ISO, 53 }, | ||
2724 | 90 | /* 30 */ { 3, time::jan, 2010, calendar::ISO, 53 }, | ||
2725 | 91 | /* 31 */ { 4, time::jan, 2010, calendar::ISO, 1 }, | ||
2726 | 92 | |||
2727 | 93 | { 0 }, | ||
2728 | 94 | }; | ||
2729 | 95 | |||
2730 | 96 | for ( test_type const *t = test; t->mday; ++t ) { | ||
2731 | 97 | int w = calendar::calc_week_in_year( t->mday, t->mon, t->year, t->cal ); | ||
2732 | 98 | ++test_no; | ||
2733 | 99 | ASSERT_TRUE( test_no, w == t->expected ); | ||
2734 | 100 | } | ||
2735 | 101 | } | ||
2736 | 102 | |||
2737 | 103 | /////////////////////////////////////////////////////////////////////////////// | ||
2738 | 104 | |||
2739 | 105 | namespace zorba { | ||
2740 | 106 | namespace UnitTests { | ||
2741 | 107 | |||
2742 | 108 | int test_time( int, char*[] ) { | ||
2743 | 109 | |||
2744 | 110 | test_calc_week_in_year(); | ||
2745 | 111 | |||
2746 | 112 | cout << failures << " test(s) failed\n"; | ||
2747 | 113 | return failures ? 1 : 0; | ||
2748 | 114 | } | ||
2749 | 115 | |||
2750 | 116 | } // namespace UnitTests | ||
2751 | 117 | } // namespace zorba | ||
2752 | 118 | /* vim:set et sw=2 ts=2: */ | ||
2753 | 0 | 119 | ||
2754 | === modified file 'src/unit_tests/unit_test_list.h' | |||
2755 | --- src/unit_tests/unit_test_list.h 2013-03-17 04:47:01 +0000 | |||
2756 | +++ src/unit_tests/unit_test_list.h 2013-03-21 16:00:34 +0000 | |||
2757 | @@ -41,6 +41,7 @@ | |||
2758 | 41 | int test_mem_sizeof( int, char*[] ); | 41 | int test_mem_sizeof( int, char*[] ); |
2759 | 42 | int test_parameters( int, char*[] ); | 42 | int test_parameters( int, char*[] ); |
2760 | 43 | int test_string( int, char*[] ); | 43 | int test_string( int, char*[] ); |
2761 | 44 | int test_time( int, char*[] ); | ||
2762 | 44 | int test_time_parse( int, char*[] ); | 45 | int test_time_parse( int, char*[] ); |
2763 | 45 | 46 | ||
2764 | 46 | #ifdef ZORBA_WITH_FILE_ACCESS | 47 | #ifdef ZORBA_WITH_FILE_ACCESS |
2765 | 47 | 48 | ||
2766 | === modified file 'src/unit_tests/unit_tests.cpp' | |||
2767 | --- src/unit_tests/unit_tests.cpp 2013-03-17 04:47:01 +0000 | |||
2768 | +++ src/unit_tests/unit_tests.cpp 2013-03-21 16:00:34 +0000 | |||
2769 | @@ -56,6 +56,7 @@ | |||
2770 | 56 | libunittests["json_parser"] = test_json_parser; | 56 | libunittests["json_parser"] = test_json_parser; |
2771 | 57 | libunittests["parameters"] = test_parameters; | 57 | libunittests["parameters"] = test_parameters; |
2772 | 58 | libunittests["string"] = test_string; | 58 | libunittests["string"] = test_string; |
2773 | 59 | libunittests["time"] = test_time; | ||
2774 | 59 | libunittests["time_parse"] = test_time_parse; | 60 | libunittests["time_parse"] = test_time_parse; |
2775 | 60 | 61 | ||
2776 | 61 | #ifndef ZORBA_NO_FULL_TEXT | 62 | #ifndef ZORBA_NO_FULL_TEXT |
2777 | 62 | 63 | ||
2778 | === modified file 'src/util/ascii_util.h' | |||
2779 | --- src/util/ascii_util.h 2013-03-19 04:22:49 +0000 | |||
2780 | +++ src/util/ascii_util.h 2013-03-21 16:00:34 +0000 | |||
2781 | @@ -22,6 +22,7 @@ | |||
2782 | 22 | #include <cctype> | 22 | #include <cctype> |
2783 | 23 | #include <cstddef> | 23 | #include <cstddef> |
2784 | 24 | #include <cstring> | 24 | #include <cstring> |
2785 | 25 | #include <iterator> | ||
2786 | 25 | 26 | ||
2787 | 26 | // local | 27 | // local |
2788 | 27 | #include "omanip.h" | 28 | #include "omanip.h" |
2789 | @@ -1147,9 +1148,62 @@ | |||
2790 | 1147 | *pos = trim_start_whitespace( s + *pos, s_len - *pos ) - s; | 1148 | *pos = trim_start_whitespace( s + *pos, s_len - *pos ) - s; |
2791 | 1148 | } | 1149 | } |
2792 | 1149 | 1150 | ||
2793 | 1151 | /** | ||
2794 | 1152 | * Skips any consecutive whitespace chars that are found at a given starting | ||
2795 | 1153 | * position within a given string. | ||
2796 | 1154 | * | ||
2797 | 1155 | * @tparam StringType The string type. | ||
2798 | 1156 | * @param s The string. | ||
2799 | 1157 | * @param i A pointer to the iterator to advance past the whitespace. | ||
2800 | 1158 | * On return, \a *i is updated with the position of the 1st non-whitespace | ||
2801 | 1159 | * char. | ||
2802 | 1160 | */ | ||
2803 | 1161 | template<class StringType> inline | ||
2804 | 1162 | void skip_whitespace( StringType const &s, | ||
2805 | 1163 | typename StringType::const_iterator *i ) { | ||
2806 | 1164 | typename StringType::difference_type const d = *i - s.begin(); | ||
2807 | 1165 | char const *const sd = s.data() + d; | ||
2808 | 1166 | std::advance( *i, trim_start_whitespace( sd, s.size() - d ) - sd ); | ||
2809 | 1167 | } | ||
2810 | 1168 | |||
2811 | 1150 | ////////// Miscellaneous ////////////////////////////////////////////////////// | 1169 | ////////// Miscellaneous ////////////////////////////////////////////////////// |
2812 | 1151 | 1170 | ||
2813 | 1152 | /** | 1171 | /** |
2814 | 1172 | * Pads a string to the left with a given character until the string is the | ||
2815 | 1173 | * given width. | ||
2816 | 1174 | * | ||
2817 | 1175 | * @param s The string to pad. | ||
2818 | 1176 | * @param width The width to pad to. | ||
2819 | 1177 | * @param c The character to pad with. | ||
2820 | 1178 | * @return Returns \c *s. | ||
2821 | 1179 | */ | ||
2822 | 1180 | template<class StringType> inline | ||
2823 | 1181 | StringType& left_pad( StringType *s, typename StringType::size_type width, | ||
2824 | 1182 | char c ) { | ||
2825 | 1183 | typedef typename StringType::size_type size_type; | ||
2826 | 1184 | if ( s->size() < width ) | ||
2827 | 1185 | s->insert( static_cast<size_type>( 0 ), width - s->size(), c ); | ||
2828 | 1186 | return *s; | ||
2829 | 1187 | } | ||
2830 | 1188 | |||
2831 | 1189 | /** | ||
2832 | 1190 | * Pads a string to the right with a given character until the string is the | ||
2833 | 1191 | * given width. | ||
2834 | 1192 | * | ||
2835 | 1193 | * @param s The string to pad. | ||
2836 | 1194 | * @param width The width to pad to. | ||
2837 | 1195 | * @param c The character to pad with. | ||
2838 | 1196 | * @return Returns \c *s. | ||
2839 | 1197 | */ | ||
2840 | 1198 | template<class StringType> inline | ||
2841 | 1199 | StringType& right_pad( StringType *s, typename StringType::size_type width, | ||
2842 | 1200 | char c ) { | ||
2843 | 1201 | if ( s->size() < width ) | ||
2844 | 1202 | s->append( width - s->size(), c ); | ||
2845 | 1203 | return *s; | ||
2846 | 1204 | } | ||
2847 | 1205 | |||
2848 | 1206 | /** | ||
2849 | 1153 | * Prints the given character in a printable way: if \c is_print(c) is \c true, | 1207 | * Prints the given character in a printable way: if \c is_print(c) is \c true, |
2850 | 1154 | * prints \a c as-is; otherwise prints \c #x followed by the hexadecimal value | 1208 | * prints \a c as-is; otherwise prints \c #x followed by the hexadecimal value |
2851 | 1155 | * of the character. | 1209 | * of the character. |
2852 | 1156 | 1210 | ||
2853 | === modified file 'src/util/stream_util.cpp' | |||
2854 | --- src/util/stream_util.cpp 2013-03-16 20:44:27 +0000 | |||
2855 | +++ src/util/stream_util.cpp 2013-03-21 16:00:34 +0000 | |||
2856 | @@ -70,6 +70,37 @@ | |||
2857 | 70 | return buf - buf_orig; | 70 | return buf - buf_orig; |
2858 | 71 | } | 71 | } |
2859 | 72 | 72 | ||
2860 | 73 | ostream& roman( ostream &o, unsigned n ) { | ||
2861 | 74 | // | ||
2862 | 75 | // Based on http://rosettacode.org/wiki/Roman_numerals/Encode#C.2B.2B | ||
2863 | 76 | // | ||
2864 | 77 | struct roman_data { | ||
2865 | 78 | unsigned value; | ||
2866 | 79 | char const *numeral[2]; | ||
2867 | 80 | }; | ||
2868 | 81 | static roman_data const data[] = { | ||
2869 | 82 | 1000, { "m", "M" }, | ||
2870 | 83 | 900, { "cm", "CM" }, | ||
2871 | 84 | 500, { "d", "D" }, | ||
2872 | 85 | 400, { "cd", "CD" }, | ||
2873 | 86 | 100, { "c", "C" }, | ||
2874 | 87 | 90, { "xc", "XC" }, | ||
2875 | 88 | 50, { "l", "L" }, | ||
2876 | 89 | 40, { "xl", "XL" }, | ||
2877 | 90 | 10, { "x", "X" }, | ||
2878 | 91 | 9, { "ix", "IX" }, | ||
2879 | 92 | 5, { "v", "V" }, | ||
2880 | 93 | 4, { "iv", "IV" }, | ||
2881 | 94 | 1, { "i", "I" }, | ||
2882 | 95 | 0, { 0, 0 } | ||
2883 | 96 | }; | ||
2884 | 97 | bool const uc = !!(o.flags() & ios::uppercase); | ||
2885 | 98 | for ( roman_data const *r = data; r->value > 0; ++r ) | ||
2886 | 99 | for ( ; n >= r->value; n -= r->value ) | ||
2887 | 100 | o << r->numeral[ uc ]; | ||
2888 | 101 | return o; | ||
2889 | 102 | } | ||
2890 | 103 | |||
2891 | 73 | /////////////////////////////////////////////////////////////////////////////// | 104 | /////////////////////////////////////////////////////////////////////////////// |
2892 | 74 | 105 | ||
2893 | 75 | } // namespace zorba | 106 | } // namespace zorba |
2894 | 76 | 107 | ||
2895 | === modified file 'src/util/stream_util.h' | |||
2896 | --- src/util/stream_util.h 2013-03-16 20:44:27 +0000 | |||
2897 | +++ src/util/stream_util.h 2013-03-21 16:00:34 +0000 | |||
2898 | @@ -20,6 +20,7 @@ | |||
2899 | 20 | 20 | ||
2900 | 21 | #include <iostream> | 21 | #include <iostream> |
2901 | 22 | 22 | ||
2902 | 23 | #include "omanip.h" | ||
2903 | 23 | #include "string_util.h" | 24 | #include "string_util.h" |
2904 | 24 | 25 | ||
2905 | 25 | namespace zorba { | 26 | namespace zorba { |
2906 | @@ -73,6 +74,19 @@ | |||
2907 | 73 | std::streamsize read_without_whitespace( std::istream &is, char *buf, | 74 | std::streamsize read_without_whitespace( std::istream &is, char *buf, |
2908 | 74 | std::streamsize n ); | 75 | std::streamsize n ); |
2909 | 75 | 76 | ||
2910 | 77 | /** | ||
2911 | 78 | * Emits an integer as Roman numerals to the given ostream. By default, | ||
2912 | 79 | * numerals are emitted in lower-case. To emit in upper-case, set the | ||
2913 | 80 | * \c uppercase format flag on the stream. | ||
2914 | 81 | * | ||
2915 | 82 | * @param o The ostream to emit to. | ||
2916 | 83 | * @param n The integer to emit. | ||
2917 | 84 | * @return Returns \a o. | ||
2918 | 85 | */ | ||
2919 | 86 | std::ostream& roman( std::ostream &o, unsigned n ); | ||
2920 | 87 | |||
2921 | 88 | DEF_OMANIP1( roman, unsigned ) | ||
2922 | 89 | |||
2923 | 76 | /////////////////////////////////////////////////////////////////////////////// | 90 | /////////////////////////////////////////////////////////////////////////////// |
2924 | 77 | 91 | ||
2925 | 78 | } // namespace zorba | 92 | } // namespace zorba |
2926 | 79 | 93 | ||
2927 | === modified file 'src/util/time_util.cpp' | |||
2928 | --- src/util/time_util.cpp 2013-02-13 01:57:47 +0000 | |||
2929 | +++ src/util/time_util.cpp 2013-03-21 16:00:34 +0000 | |||
2930 | @@ -16,7 +16,9 @@ | |||
2931 | 16 | 16 | ||
2932 | 17 | #include "stdafx.h" | 17 | #include "stdafx.h" |
2933 | 18 | 18 | ||
2934 | 19 | #include <algorithm> | ||
2935 | 19 | #include <cassert> | 20 | #include <cassert> |
2936 | 21 | #include <cstring> | ||
2937 | 20 | #ifdef WIN32 | 22 | #ifdef WIN32 |
2938 | 21 | # include <windows.h> | 23 | # include <windows.h> |
2939 | 22 | # include <time.h> /* for gmtime_s() */ | 24 | # include <time.h> /* for gmtime_s() */ |
2940 | @@ -31,13 +33,138 @@ | |||
2941 | 31 | #endif /* WIN32 */ | 33 | #endif /* WIN32 */ |
2942 | 32 | 34 | ||
2943 | 33 | // local | 35 | // local |
2944 | 36 | #include "less.h" | ||
2945 | 34 | #include "time_util.h" | 37 | #include "time_util.h" |
2946 | 35 | 38 | ||
2947 | 39 | #define DEF_END(CHAR_ARRAY) \ | ||
2948 | 40 | static char const *const *const end = \ | ||
2949 | 41 | CHAR_ARRAY + sizeof( CHAR_ARRAY ) / sizeof( char* ) | ||
2950 | 42 | |||
2951 | 43 | #define FIND(WHAT) \ | ||
2952 | 44 | static_cast<type>( find_index( string_of, end, WHAT ) ) | ||
2953 | 45 | |||
2954 | 46 | using namespace std; | ||
2955 | 47 | |||
2956 | 48 | /** | ||
2957 | 49 | * A less-verbose way to use std::lower_bound. | ||
2958 | 50 | */ | ||
2959 | 51 | inline int find_index( char const *const *begin, char const *const *end, | ||
2960 | 52 | char const *s ) { | ||
2961 | 53 | char const *const *const entry = | ||
2962 | 54 | ::lower_bound( begin, end, s, less<char const*>() ); | ||
2963 | 55 | return entry != end && ::strcmp( s, *entry ) == 0 ? entry - begin : 0; | ||
2964 | 56 | } | ||
2965 | 57 | |||
2966 | 36 | namespace zorba { | 58 | namespace zorba { |
2967 | 37 | namespace time { | 59 | namespace time { |
2968 | 38 | 60 | ||
2969 | 39 | /////////////////////////////////////////////////////////////////////////////// | 61 | /////////////////////////////////////////////////////////////////////////////// |
2970 | 40 | 62 | ||
2971 | 63 | namespace iso8601 { | ||
2972 | 64 | /** | ||
2973 | 65 | * Weekday values as used by the ISO 8601 specification. | ||
2974 | 66 | */ | ||
2975 | 67 | enum weekday { | ||
2976 | 68 | mon = 1, | ||
2977 | 69 | tue = 2, | ||
2978 | 70 | wed = 3, | ||
2979 | 71 | thu = 4, | ||
2980 | 72 | fri = 5, | ||
2981 | 73 | sat = 6, | ||
2982 | 74 | sun = 7 | ||
2983 | 75 | }; | ||
2984 | 76 | } | ||
2985 | 77 | |||
2986 | 78 | namespace calendar { | ||
2987 | 79 | |||
2988 | 80 | char const *const string_of[] = { | ||
2989 | 81 | "#UNKNOWN", | ||
2990 | 82 | "AD", // Anno Domini (Christian Era) | ||
2991 | 83 | "AH", // Anno Hegirae (Muhammedan Era) | ||
2992 | 84 | "AM", // Anno Mundi (Jewish) | ||
2993 | 85 | "AME", // Mauludi Era (solar years since Mohammed's birth) | ||
2994 | 86 | "AP", // Anno Persici | ||
2995 | 87 | "AS", // Aji Saka Era (Java) | ||
2996 | 88 | "BE", // Buddhist Era | ||
2997 | 89 | "CB", // Cooch Behar Era | ||
2998 | 90 | "CE", // Common Era | ||
2999 | 91 | "CL", // Chinese Lunar Era | ||
3000 | 92 | "CS", // Chula Sakarat Era | ||
3001 | 93 | "EE", // Ethiopian Era | ||
3002 | 94 | "FE", // Fasli Era | ||
3003 | 95 | "ISO", // ISO 8601 calendar | ||
3004 | 96 | "JE", // Japanese | ||
3005 | 97 | "KE", // Khalsa Era (Sikh calendar) | ||
3006 | 98 | "KY", // Kali Yuga | ||
3007 | 99 | "ME", // Malabar Era | ||
3008 | 100 | "MS", // Monarchic Solar Era | ||
3009 | 101 | "OS", // Old Style (Julian) | ||
3010 | 102 | "RS", // Rattanakosin (Bangkok) Era | ||
3011 | 103 | "SE", // Saka Era | ||
3012 | 104 | "SH", // Mohammedan Solar Era (Iran) | ||
3013 | 105 | "SS", // Saka Samvat | ||
3014 | 106 | "TE", // Tripurabda Era | ||
3015 | 107 | "VE", // Vikrama Era | ||
3016 | 108 | "VS" // Vikrama Samvat Era | ||
3017 | 109 | }; | ||
3018 | 110 | |||
3019 | 111 | int calc_week_in_year( unsigned mday, unsigned mon, unsigned year, type cal ) { | ||
3020 | 112 | int yday = time::calc_yday( mday, mon, year ); | ||
3021 | 113 | int jan1_wday = time::calc_wday( 1, time::jan, year ); | ||
3022 | 114 | |||
3023 | 115 | switch ( cal ) { | ||
3024 | 116 | case AD: | ||
3025 | 117 | return (jan1_wday + yday) / 7 + 1; | ||
3026 | 118 | case ISO: { | ||
3027 | 119 | // Based on http://www.personal.ecu.edu/mccartyr/ISOwdALG.txt | ||
3028 | 120 | ++yday; // code assumes [1-366] | ||
3029 | 121 | jan1_wday = convert_wday_to( jan1_wday, cal ); | ||
3030 | 122 | |||
3031 | 123 | if ( jan1_wday > iso8601::thu && jan1_wday + yday <= 8 ) { | ||
3032 | 124 | // date falls in week 52 or 53 of the previous year | ||
3033 | 125 | return 52 | ||
3034 | 126 | + (jan1_wday == iso8601::fri || | ||
3035 | 127 | (jan1_wday == iso8601::sat && time::is_leap_year( year - 1 ))); | ||
3036 | 128 | } | ||
3037 | 129 | int const wday = | ||
3038 | 130 | convert_wday_to( time::calc_wday( mday, mon, year ), cal ); | ||
3039 | 131 | if ( time::days_in_year( year ) - yday < 4 - wday ) { | ||
3040 | 132 | // date falls in week 1 of the next year | ||
3041 | 133 | return 1; | ||
3042 | 134 | } | ||
3043 | 135 | return (yday + (7 - wday) + (jan1_wday - 1)) / 7 | ||
3044 | 136 | - (jan1_wday > iso8601::thu); | ||
3045 | 137 | } | ||
3046 | 138 | default: | ||
3047 | 139 | return -1; | ||
3048 | 140 | } | ||
3049 | 141 | } | ||
3050 | 142 | |||
3051 | 143 | int convert_wday_from( unsigned wday, type from ) { | ||
3052 | 144 | switch ( from ) { | ||
3053 | 145 | case AD : return static_cast<int>( wday ); | ||
3054 | 146 | case ISO: return wday == iso8601::sun ? time::sun : wday; | ||
3055 | 147 | default : return -1; | ||
3056 | 148 | } | ||
3057 | 149 | } | ||
3058 | 150 | |||
3059 | 151 | int convert_wday_to( unsigned wday, type to ) { | ||
3060 | 152 | switch ( to ) { | ||
3061 | 153 | case AD : return static_cast<int>( wday ); | ||
3062 | 154 | case ISO: return wday == time::sun ? iso8601::sun : wday; | ||
3063 | 155 | default : return -1; | ||
3064 | 156 | } | ||
3065 | 157 | } | ||
3066 | 158 | |||
3067 | 159 | type find( char const *calendar ) { | ||
3068 | 160 | DEF_END( string_of ); | ||
3069 | 161 | return FIND( calendar ); | ||
3070 | 162 | } | ||
3071 | 163 | |||
3072 | 164 | } // namespace calendar | ||
3073 | 165 | |||
3074 | 166 | /////////////////////////////////////////////////////////////////////////////// | ||
3075 | 167 | |||
3076 | 41 | static unsigned const yday_mon[][13] = { | 168 | static unsigned const yday_mon[][13] = { |
3077 | 42 | // 0 1 2 3 4 5 6 7 8 9 10 11 12 | 169 | // 0 1 2 3 4 5 6 7 8 9 10 11 12 |
3078 | 43 | { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }, // non-leap | 170 | { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }, // non-leap |
3079 | @@ -48,7 +175,7 @@ | |||
3080 | 48 | 175 | ||
3081 | 49 | bool calc_mday_mon( unsigned yday, unsigned *mday, unsigned *mon, | 176 | bool calc_mday_mon( unsigned yday, unsigned *mday, unsigned *mon, |
3082 | 50 | unsigned year ) { | 177 | unsigned year ) { |
3084 | 51 | assert( yday < 365 + is_leap_year( year ) ); | 178 | assert( yday < days_in_year( year ) ); |
3085 | 52 | 179 | ||
3086 | 53 | unsigned const *const ym = yday_mon[ is_leap_year( year ) ]; | 180 | unsigned const *const ym = yday_mon[ is_leap_year( year ) ]; |
3087 | 54 | for ( unsigned m = 1; m <= 12; ++m ) | 181 | for ( unsigned m = 1; m <= 12; ++m ) |
3088 | @@ -102,31 +229,31 @@ | |||
3089 | 102 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | 229 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE |
3090 | 103 | * USE OR OTHER DEALINGS IN THE SOFTWARE. | 230 | * USE OR OTHER DEALINGS IN THE SOFTWARE. |
3091 | 104 | * | 231 | * |
3096 | 105 | * @param mday Month day: 1-31. | 232 | * @param mday The month day [1-31]. |
3097 | 106 | * @param mon Month: 0-11. | 233 | * @param mon The month [0-11]. |
3098 | 107 | * @param year Year. | 234 | * @param year The year. |
3099 | 108 | * @return Returns the weekday where 0 = Sunday. | 235 | * @return Returns the weekday [0-6] where 0 = Sunday. |
3100 | 109 | */ | 236 | */ |
3102 | 110 | unsigned calc_wday( unsigned mday, unsigned mon, unsigned year ) { | 237 | int calc_wday( unsigned mday, unsigned mon, unsigned year ) { |
3103 | 111 | assert( mday >= 1 ); | 238 | assert( mday >= 1 ); |
3104 | 112 | assert( mday <= days_in_month( mon, year ) ); | 239 | assert( mday <= days_in_month( mon, year ) ); |
3105 | 113 | assert( mon < 12 ); | 240 | assert( mon < 12 ); |
3106 | 114 | 241 | ||
3107 | 115 | ++mon; // Tondering's algorithm assumes month value in range 1-12. | 242 | ++mon; // Tondering's algorithm assumes month value in range 1-12. |
3111 | 116 | unsigned const a = (14 - mon) / 12; | 243 | int const a = (14 - mon) / 12; |
3112 | 117 | unsigned const y = year - a; | 244 | int const y = year - a; |
3113 | 118 | unsigned const m = mon + 12 * a - 2; | 245 | int const m = mon + 12 * a - 2; |
3114 | 119 | return (mday + y + y/4 - y/100 + y/400 + (31 * m) / 12) % 7; | 246 | return (mday + y + y/4 - y/100 + y/400 + (31 * m) / 12) % 7; |
3115 | 120 | } | 247 | } |
3116 | 121 | 248 | ||
3118 | 122 | unsigned calc_yday( unsigned mday, unsigned mon, unsigned year ) { | 249 | int calc_yday( unsigned mday, unsigned mon, unsigned year ) { |
3119 | 123 | assert( mday >= 1 ); | 250 | assert( mday >= 1 ); |
3120 | 124 | assert( mday <= days_in_month( mon, year ) ); | 251 | assert( mday <= days_in_month( mon, year ) ); |
3122 | 125 | return yday_mon[ is_leap_year( year ) ][ mon ] + mday - 1; | 252 | return (int)yday_mon[ is_leap_year( year ) ][ mon ] + mday - 1; |
3123 | 126 | } | 253 | } |
3124 | 127 | 254 | ||
3127 | 128 | unsigned days_in_month( unsigned mon, unsigned year ) { | 255 | int days_in_month( unsigned mon, unsigned year ) { |
3128 | 129 | static unsigned const days[] = { | 256 | static int const days[] = { |
3129 | 130 | 31, // 0: Jan | 257 | 31, // 0: Jan |
3130 | 131 | 28, // 1: Feb | 258 | 28, // 1: Feb |
3131 | 132 | 31, // 2: Mar | 259 | 31, // 2: Mar |
3132 | @@ -141,7 +268,7 @@ | |||
3133 | 141 | 31 // 11: Dec | 268 | 31 // 11: Dec |
3134 | 142 | }; | 269 | }; |
3135 | 143 | assert( mon < 12 ); | 270 | assert( mon < 12 ); |
3137 | 144 | return days[ mon ] + (mon == 1 /* Feb */ && is_leap_year( year )); | 271 | return days[ mon ] + (mon == feb && is_leap_year( year )); |
3138 | 145 | } | 272 | } |
3139 | 146 | 273 | ||
3140 | 147 | void get_epoch( sec_type *sec, usec_type *usec ) { | 274 | void get_epoch( sec_type *sec, usec_type *usec ) { |
3141 | @@ -202,6 +329,17 @@ | |||
3142 | 202 | #endif /* WIN32 */ | 329 | #endif /* WIN32 */ |
3143 | 203 | } | 330 | } |
3144 | 204 | 331 | ||
3145 | 332 | char get_military_tz( int hour ) { | ||
3146 | 333 | hour %= 24; | ||
3147 | 334 | if ( hour > 12 ) | ||
3148 | 335 | hour -= 24; | ||
3149 | 336 | else if ( hour < -12 ) | ||
3150 | 337 | hour += 24; | ||
3151 | 338 | if ( hour >= 0 && hour <= 12 ) | ||
3152 | 339 | return "ZABCDEFGHIKLM" [ hour ]; // no 'J' here (it means "no timezone") | ||
3153 | 340 | return " NOPQRSTUVWXY" [ -hour ]; | ||
3154 | 341 | } | ||
3155 | 342 | |||
3156 | 205 | /////////////////////////////////////////////////////////////////////////////// | 343 | /////////////////////////////////////////////////////////////////////////////// |
3157 | 206 | 344 | ||
3158 | 207 | } // namespace time | 345 | } // namespace time |
3159 | 208 | 346 | ||
3160 | === modified file 'src/util/time_util.h' | |||
3161 | --- src/util/time_util.h 2013-02-13 01:57:47 +0000 | |||
3162 | +++ src/util/time_util.h 2013-03-21 16:00:34 +0000 | |||
3163 | @@ -25,7 +25,9 @@ | |||
3164 | 25 | 25 | ||
3165 | 26 | // Zorba | 26 | // Zorba |
3166 | 27 | #include <zorba/config.h> | 27 | #include <zorba/config.h> |
3167 | 28 | #include <zorba/time.h> | ||
3168 | 28 | #include "cxx_util.h" | 29 | #include "cxx_util.h" |
3169 | 30 | #include "string_util.h" | ||
3170 | 29 | 31 | ||
3171 | 30 | #ifndef TM_YEAR_BASE | 32 | #ifndef TM_YEAR_BASE |
3172 | 31 | # define TM_YEAR_BASE 1900 | 33 | # define TM_YEAR_BASE 1900 |
3173 | @@ -36,14 +38,22 @@ | |||
3174 | 36 | 38 | ||
3175 | 37 | /////////////////////////////////////////////////////////////////////////////// | 39 | /////////////////////////////////////////////////////////////////////////////// |
3176 | 38 | 40 | ||
3177 | 41 | /** | ||
3178 | 42 | * A type to hold a number of seconds (at least since epoch). | ||
3179 | 43 | */ | ||
3180 | 39 | typedef time_t sec_type; | 44 | typedef time_t sec_type; |
3181 | 40 | 45 | ||
3182 | 46 | /** | ||
3183 | 47 | * A type to hold a number of microseconds. | ||
3184 | 48 | */ | ||
3185 | 41 | #ifdef WIN32 | 49 | #ifdef WIN32 |
3186 | 42 | typedef unsigned long usec_type; | 50 | typedef unsigned long usec_type; |
3187 | 43 | #else | 51 | #else |
3188 | 44 | typedef suseconds_t usec_type; | 52 | typedef suseconds_t usec_type; |
3189 | 45 | #endif /* WIN32 */ | 53 | #endif /* WIN32 */ |
3190 | 46 | 54 | ||
3191 | 55 | /////////////////////////////////////////////////////////////////////////////// | ||
3192 | 56 | |||
3193 | 47 | // | 57 | // |
3194 | 48 | // If the OS's tm struct has a GMT-timezone offset field, simply typedef tm as | 58 | // If the OS's tm struct has a GMT-timezone offset field, simply typedef tm as |
3195 | 49 | // ztm; otherwise declare ztm as a struct derived from tm that adds a | 59 | // ztm; otherwise declare ztm as a struct derived from tm that adds a |
3196 | @@ -71,12 +81,129 @@ | |||
3197 | 71 | /////////////////////////////////////////////////////////////////////////////// | 81 | /////////////////////////////////////////////////////////////////////////////// |
3198 | 72 | 82 | ||
3199 | 73 | /** | 83 | /** |
3200 | 84 | * XQuery 3.0 F&O: 9.8.4.3: The calendars listed below were known to be in use | ||
3201 | 85 | * during the last hundred years. | ||
3202 | 86 | */ | ||
3203 | 87 | namespace calendar { | ||
3204 | 88 | extern char const* const string_of[]; | ||
3205 | 89 | |||
3206 | 90 | /** | ||
3207 | 91 | * Emits a calendar::type to an ostream. | ||
3208 | 92 | * | ||
3209 | 93 | * @param o The ostream to emit to. | ||
3210 | 94 | * @param t The type to emit. | ||
3211 | 95 | * @return Returns \a o. | ||
3212 | 96 | */ | ||
3213 | 97 | inline std::ostream& operator<<( std::ostream &o, type t ) { | ||
3214 | 98 | return o << string_of[ t ]; | ||
3215 | 99 | } | ||
3216 | 100 | |||
3217 | 101 | /** | ||
3218 | 102 | * Calculates the week number for the given date and calendar. | ||
3219 | 103 | * | ||
3220 | 104 | * @param mday The month day [1-31]. | ||
3221 | 105 | * @param mon The month [0-11]. | ||
3222 | 106 | * @param year The year. | ||
3223 | 107 | * @param cal The calendar. | ||
3224 | 108 | * @return Returns the week [1-53] or -1 if it is unknown how to perform the | ||
3225 | 109 | * calculation for \a cal. | ||
3226 | 110 | */ | ||
3227 | 111 | int calc_week_in_year( unsigned mday, unsigned mon, unsigned year, type cal ); | ||
3228 | 112 | |||
3229 | 113 | /** | ||
3230 | 114 | * Converts a weekday number from a given calendar to the Unix interpretation | ||
3231 | 115 | * [0-6] where 0 = Sunday. | ||
3232 | 116 | * | ||
3233 | 117 | * @param wday The weekday to convert where the meaning of the value is | ||
3234 | 118 | * determined by \a from. | ||
3235 | 119 | * @param from The calendar designator to convert \a wday from. | ||
3236 | 120 | * @return Returns \a wday converted to \a to or -1 if it is unknown how to | ||
3237 | 121 | * perform the conversion. | ||
3238 | 122 | */ | ||
3239 | 123 | int convert_wday_from( unsigned wday, type from ); | ||
3240 | 124 | |||
3241 | 125 | /** | ||
3242 | 126 | * Converts a Unix weekday number to a specific calendar. | ||
3243 | 127 | * | ||
3244 | 128 | * @param wday The weekday to convert: [0-6] where 0 = Sunday. | ||
3245 | 129 | * @param to The calendar designator to convert \a wday to. | ||
3246 | 130 | * @return Returns \a wday converted to \a to or -1 if it is unknown how to | ||
3247 | 131 | * perform the conversion. | ||
3248 | 132 | */ | ||
3249 | 133 | int convert_wday_to( unsigned wday, type to ); | ||
3250 | 134 | |||
3251 | 135 | /** | ||
3252 | 136 | * Finds a calendar designator from the given string. | ||
3253 | 137 | * | ||
3254 | 138 | * @param calendar The calendar designator to find. It is presumed to be in | ||
3255 | 139 | * upper-case. | ||
3256 | 140 | * @return Returns said enumeration or \c unknown. | ||
3257 | 141 | */ | ||
3258 | 142 | type find( char const *calendar ); | ||
3259 | 143 | |||
3260 | 144 | // | ||
3261 | 145 | // Template version of find(). | ||
3262 | 146 | // | ||
3263 | 147 | template<class StringType> inline | ||
3264 | 148 | typename std::enable_if< | ||
3265 | 149 | ztd::has_c_str<StringType,char const* (StringType::*)() const>::value, | ||
3266 | 150 | type | ||
3267 | 151 | >::type | ||
3268 | 152 | find( StringType const &calendar ) { | ||
3269 | 153 | return find( calendar.c_str() ); | ||
3270 | 154 | } | ||
3271 | 155 | |||
3272 | 156 | /** | ||
3273 | 157 | * Gets the default calendar to use. | ||
3274 | 158 | * | ||
3275 | 159 | * @return Returns said calendar. | ||
3276 | 160 | */ | ||
3277 | 161 | inline type get_default() { | ||
3278 | 162 | return AD; // i.e., the Gregorian calendar | ||
3279 | 163 | } | ||
3280 | 164 | |||
3281 | 165 | } // namespace calendar | ||
3282 | 166 | |||
3283 | 167 | /////////////////////////////////////////////////////////////////////////////// | ||
3284 | 168 | |||
3285 | 169 | /** | ||
3286 | 170 | * Month (<code>mod</code>) values as used by the \c tm structure. | ||
3287 | 171 | */ | ||
3288 | 172 | enum month { | ||
3289 | 173 | jan = 0, | ||
3290 | 174 | feb = 1, | ||
3291 | 175 | mar = 2, | ||
3292 | 176 | apr = 3, | ||
3293 | 177 | may = 4, | ||
3294 | 178 | jun = 5, | ||
3295 | 179 | jul = 6, | ||
3296 | 180 | aug = 7, | ||
3297 | 181 | sep = 8, | ||
3298 | 182 | oct = 9, | ||
3299 | 183 | nov = 10, | ||
3300 | 184 | dec = 11 | ||
3301 | 185 | }; | ||
3302 | 186 | |||
3303 | 187 | /** | ||
3304 | 188 | * Weekday (<code>wday</code>) values as used by the \c tm structure. | ||
3305 | 189 | */ | ||
3306 | 190 | enum weekday { | ||
3307 | 191 | sun = 0, | ||
3308 | 192 | mon = 1, | ||
3309 | 193 | tue = 2, | ||
3310 | 194 | wed = 3, | ||
3311 | 195 | thu = 4, | ||
3312 | 196 | fri = 5, | ||
3313 | 197 | sat = 6 | ||
3314 | 198 | }; | ||
3315 | 199 | |||
3316 | 200 | /** | ||
3317 | 74 | * Calculates the day of the month and month from the given day of the year. | 201 | * Calculates the day of the month and month from the given day of the year. |
3318 | 75 | * | 202 | * |
3321 | 76 | * @param yday The year day (0-365) where 0 = January 1. | 203 | * @param yday The year day [0-365] where 0 = January 1. |
3322 | 77 | * @param mday A pointer to the result for the month day (1-31) or \c null if | 204 | * @param mday A pointer to the result for the month day [1-31] or \c null if |
3323 | 78 | * this is not desired. | 205 | * this is not desired. |
3325 | 79 | * @param mon A pointer to the result for the month (0-11) or \c null if this | 206 | * @param mon A pointer to the result for the month [0-11] or \c null if this |
3326 | 80 | * is not desired. | 207 | * is not desired. |
3327 | 81 | * @param year The year. | 208 | * @param year The year. |
3328 | 82 | * @return Returns \c true if \a yday and \a year are a valid combination and | 209 | * @return Returns \c true if \a yday and \a year are a valid combination and |
3329 | @@ -88,31 +215,31 @@ | |||
3330 | 88 | /** | 215 | /** |
3331 | 89 | * Calculates the weekday for the given date. | 216 | * Calculates the weekday for the given date. |
3332 | 90 | * | 217 | * |
3335 | 91 | * @param mday The month day (1-31). | 218 | * @param mday The month day [1-31]. |
3336 | 92 | * @param mon The month (0-11). | 219 | * @param mon The month [0-11]. |
3337 | 93 | * @param year The year. | 220 | * @param year The year. |
3339 | 94 | * @return Returns the weekday (0-6) where 0 = Sunday. | 221 | * @return Returns the weekday [0-6] where 0 = Sunday. |
3340 | 95 | */ | 222 | */ |
3342 | 96 | unsigned calc_wday( unsigned mday, unsigned mon, unsigned year ); | 223 | int calc_wday( unsigned mday, unsigned mon, unsigned year ); |
3343 | 97 | 224 | ||
3344 | 98 | /** | 225 | /** |
3345 | 99 | * Calculates the day of the year for the given date. | 226 | * Calculates the day of the year for the given date. |
3346 | 100 | * | 227 | * |
3349 | 101 | * @param mday The month day (1-31). | 228 | * @param mday The month day [1-31]. |
3350 | 102 | * @param mon The month (0-11). | 229 | * @param mon The month [0-11]. |
3351 | 103 | * @param year The year. | 230 | * @param year The year. |
3353 | 104 | * @return Returns the day of the year (0-365) where 0 = January 1. | 231 | * @return Returns the day of the year [0-365] where 0 = January 1. |
3354 | 105 | */ | 232 | */ |
3356 | 106 | unsigned calc_yday( unsigned mday, unsigned mon, unsigned year ); | 233 | int calc_yday( unsigned mday, unsigned mon, unsigned year ); |
3357 | 107 | 234 | ||
3358 | 108 | /** | 235 | /** |
3359 | 109 | * Gets the number of days in the given month. | 236 | * Gets the number of days in the given month. |
3360 | 110 | * | 237 | * |
3362 | 111 | * @param mon The month (0-11). | 238 | * @param mon The month [0-11]. |
3363 | 112 | * @param year The year. | 239 | * @param year The year. |
3365 | 113 | * @return Returns said number of days (1-31). | 240 | * @return Returns said number of days, one of: 28, 29, 30, or 31. |
3366 | 114 | */ | 241 | */ |
3368 | 115 | unsigned days_in_month( unsigned mon, unsigned year ); | 242 | int days_in_month( unsigned mon, unsigned year ); |
3369 | 116 | 243 | ||
3370 | 117 | /** | 244 | /** |
3371 | 118 | * Gets the number of seconds and microseconds since epoch. | 245 | * Gets the number of seconds and microseconds since epoch. |
3372 | @@ -150,6 +277,14 @@ | |||
3373 | 150 | void get_localtime( ztm *tm, sec_type when = 0 ); | 277 | void get_localtime( ztm *tm, sec_type when = 0 ); |
3374 | 151 | 278 | ||
3375 | 152 | /** | 279 | /** |
3376 | 280 | * Gets the military timezone letter code for the given GMT hour offset. | ||
3377 | 281 | * | ||
3378 | 282 | * @param hour The number of hours offset from GMT. | ||
3379 | 283 | * @return Returns one of ABCDEFGHIKLMNOPQRSTUVWXYZ (no J). | ||
3380 | 284 | */ | ||
3381 | 285 | char get_military_tz( int hour ); | ||
3382 | 286 | |||
3383 | 287 | /** | ||
3384 | 153 | * Checks whether the given year is a leap year. | 288 | * Checks whether the given year is a leap year. |
3385 | 154 | * | 289 | * |
3386 | 155 | * @param year The year to check. | 290 | * @param year The year to check. |
3387 | @@ -160,43 +295,53 @@ | |||
3388 | 160 | } | 295 | } |
3389 | 161 | 296 | ||
3390 | 162 | /** | 297 | /** |
3391 | 298 | * Gets the number of days in the given year. | ||
3392 | 299 | * | ||
3393 | 300 | * @param year The year. | ||
3394 | 301 | * @return Returns said number of days, either: 365 or 366. | ||
3395 | 302 | */ | ||
3396 | 303 | inline int days_in_year( unsigned year ) { | ||
3397 | 304 | return 365 + is_leap_year( year ); | ||
3398 | 305 | } | ||
3399 | 306 | |||
3400 | 307 | /** | ||
3401 | 163 | * Checks whether the given day of the month is valid. | 308 | * Checks whether the given day of the month is valid. |
3402 | 164 | * | 309 | * |
3405 | 165 | * @param mday The month day (1-31). | 310 | * @param mday The month day [1-31]. |
3406 | 166 | * @param mon The month (0-11). | 311 | * @param mon The month [0-11]. |
3407 | 167 | * @param year The year. | 312 | * @param year The year. |
3408 | 168 | * @return Returns \a true only if the given day of the month is valid. | 313 | * @return Returns \a true only if the given day of the month is valid. |
3409 | 169 | */ | 314 | */ |
3410 | 170 | inline bool is_mday_valid( unsigned mday, unsigned mon, unsigned year ) { | 315 | inline bool is_mday_valid( unsigned mday, unsigned mon, unsigned year ) { |
3412 | 171 | return mday >= 1 && mday <= days_in_month( mon, year ); | 316 | return mday >= 1 && (int)mday <= days_in_month( mon, year ); |
3413 | 172 | } | 317 | } |
3414 | 173 | 318 | ||
3415 | 174 | /** | 319 | /** |
3416 | 175 | * Checks whether the given weekday is valid. | 320 | * Checks whether the given weekday is valid. |
3417 | 176 | * | 321 | * |
3421 | 177 | * @param wday The weekday (0-6) where 0 = Sunday. | 322 | * @param wday The weekday [0-6] where 0 = Sunday. |
3422 | 178 | * @param mday The month day (1-31). | 323 | * @param mday The month day [1-31]. |
3423 | 179 | * @param mon The month (0-11). | 324 | * @param mon The month [0-11]. |
3424 | 180 | * @param year The year. | 325 | * @param year The year. |
3425 | 181 | * @return Returns \a true only if the given weekday is valid. | 326 | * @return Returns \a true only if the given weekday is valid. |
3426 | 182 | */ | 327 | */ |
3427 | 183 | inline bool is_wday_valid( unsigned wday, unsigned mday, unsigned mon, | 328 | inline bool is_wday_valid( unsigned wday, unsigned mday, unsigned mon, |
3428 | 184 | unsigned year ) { | 329 | unsigned year ) { |
3430 | 185 | return wday == calc_wday( mday, mon, year ); | 330 | return (int)wday == calc_wday( mday, mon, year ); |
3431 | 186 | } | 331 | } |
3432 | 187 | 332 | ||
3433 | 188 | /** | 333 | /** |
3434 | 189 | * Checks whether the given day of the year is valid. | 334 | * Checks whether the given day of the year is valid. |
3435 | 190 | * | 335 | * |
3439 | 191 | * @param yday The day of the year (0-365). | 336 | * @param yday The day of the year [0-365]. |
3440 | 192 | * @param mday The month day (1-31). | 337 | * @param mday The month day [1-31]. |
3441 | 193 | * @param mon The month (0-11). | 338 | * @param mon The month [0-11]. |
3442 | 194 | * @param year The year. | 339 | * @param year The year. |
3443 | 195 | * @return Returns \a true only if the given day of the year is valid. | 340 | * @return Returns \a true only if the given day of the year is valid. |
3444 | 196 | */ | 341 | */ |
3445 | 197 | inline bool is_yday_valid( unsigned yday, unsigned mday, unsigned mon, | 342 | inline bool is_yday_valid( unsigned yday, unsigned mday, unsigned mon, |
3446 | 198 | unsigned year ) { | 343 | unsigned year ) { |
3448 | 199 | return yday == calc_yday( mday, mon, year ); | 344 | return (int)yday == calc_yday( mday, mon, year ); |
3449 | 200 | } | 345 | } |
3450 | 201 | 346 | ||
3451 | 202 | /////////////////////////////////////////////////////////////////////////////// | 347 | /////////////////////////////////////////////////////////////////////////////// |
3452 | 203 | 348 | ||
3453 | === modified file 'src/util/unicode_util.cpp' | |||
3454 | --- src/util/unicode_util.cpp 2013-02-07 17:24:36 +0000 | |||
3455 | +++ src/util/unicode_util.cpp 2013-03-21 16:00:34 +0000 | |||
3456 | @@ -28,6 +28,7 @@ | |||
3457 | 28 | # include <unicode/ustring.h> | 28 | # include <unicode/ustring.h> |
3458 | 29 | #endif /* ZORBA_NO_ICU */ | 29 | #endif /* ZORBA_NO_ICU */ |
3459 | 30 | 30 | ||
3460 | 31 | #include "ascii_util.h" | ||
3461 | 31 | #include "cxx_util.h" | 32 | #include "cxx_util.h" |
3462 | 32 | #include "unicode_util.h" | 33 | #include "unicode_util.h" |
3463 | 33 | #include "utf8_util.h" | 34 | #include "utf8_util.h" |
3464 | @@ -2205,6 +2206,23 @@ | |||
3465 | 2205 | return is_case<upper>( c ); | 2206 | return is_case<upper>( c ); |
3466 | 2206 | } | 2207 | } |
3467 | 2207 | 2208 | ||
3468 | 2209 | ostream& printable_cp( ostream &o, code_point cp ) { | ||
3469 | 2210 | if ( ascii::is_print( cp ) ) | ||
3470 | 2211 | o << static_cast<char>( cp ); | ||
3471 | 2212 | else | ||
3472 | 2213 | switch ( cp ) { | ||
3473 | 2214 | case '\n': o << "\\n"; break; | ||
3474 | 2215 | case '\r': o << "\\r"; break; | ||
3475 | 2216 | case '\t': o << "\\t"; break; | ||
3476 | 2217 | default: { | ||
3477 | 2218 | ios::fmtflags const old_flags = o.flags(); | ||
3478 | 2219 | o << "#x" << uppercase << hex << static_cast<uint32_t>( cp ); | ||
3479 | 2220 | o.flags( old_flags ); | ||
3480 | 2221 | } | ||
3481 | 2222 | } | ||
3482 | 2223 | return o; | ||
3483 | 2224 | } | ||
3484 | 2225 | |||
3485 | 2208 | code_point to_lower( code_point c ) { | 2226 | code_point to_lower( code_point c ) { |
3486 | 2209 | return to_case<lower>( c ); | 2227 | return to_case<lower>( c ); |
3487 | 2210 | } | 2228 | } |
3488 | 2211 | 2229 | ||
3489 | === modified file 'src/util/unicode_util.h' | |||
3490 | --- src/util/unicode_util.h 2013-02-28 11:15:32 +0000 | |||
3491 | +++ src/util/unicode_util.h 2013-03-21 16:00:34 +0000 | |||
3492 | @@ -32,6 +32,7 @@ | |||
3493 | 32 | # include <unicode/unistr.h> | 32 | # include <unicode/unistr.h> |
3494 | 33 | #endif /* ZORBA_NO_ICU */ | 33 | #endif /* ZORBA_NO_ICU */ |
3495 | 34 | 34 | ||
3496 | 35 | #include "omanip.h" | ||
3497 | 35 | #include "stl_util.h" | 36 | #include "stl_util.h" |
3498 | 36 | 37 | ||
3499 | 37 | namespace zorba { | 38 | namespace zorba { |
3500 | @@ -426,6 +427,22 @@ | |||
3501 | 426 | return c >= 0x10000 && c <= 0x10FFFF; | 427 | return c >= 0x10000 && c <= 0x10FFFF; |
3502 | 427 | } | 428 | } |
3503 | 428 | 429 | ||
3504 | 430 | ////////// Miscellaneous ////////////////////////////////////////////////////// | ||
3505 | 431 | |||
3506 | 432 | /** | ||
3507 | 433 | * Prints the given code-point in a printable way: if \c ascii::is_print(c) is | ||
3508 | 434 | * \c true, prints \a c as-is; otherwise prints \c #x followed by the | ||
3509 | 435 | * hexadecimal value of the character. | ||
3510 | 436 | * | ||
3511 | 437 | * @param o The ostream to print to. | ||
3512 | 438 | * @param cp The \c code-point to print. | ||
3513 | 439 | * @return Returns \a o. | ||
3514 | 440 | */ | ||
3515 | 441 | std::ostream& printable_cp( std::ostream &o, code_point cp ); | ||
3516 | 442 | |||
3517 | 443 | // An ostream manipulator version of the above. | ||
3518 | 444 | DEF_OMANIP1( printable_cp, code_point ) | ||
3519 | 445 | |||
3520 | 429 | /////////////////////////////////////////////////////////////////////////////// | 446 | /////////////////////////////////////////////////////////////////////////////// |
3521 | 430 | 447 | ||
3522 | 431 | } // namespace unicode | 448 | } // namespace unicode |
3523 | 432 | 449 | ||
3524 | === modified file 'src/util/utf8_string.h' | |||
3525 | --- src/util/utf8_string.h 2013-02-07 17:24:36 +0000 | |||
3526 | +++ src/util/utf8_string.h 2013-03-21 16:00:34 +0000 | |||
3527 | @@ -207,8 +207,12 @@ | |||
3528 | 207 | typedef typename StringType::const_pointer const_storage_pointer; | 207 | typedef typename StringType::const_pointer const_storage_pointer; |
3529 | 208 | typedef typename StringType::reference storage_reference; | 208 | typedef typename StringType::reference storage_reference; |
3530 | 209 | typedef typename StringType::const_reference const_storage_reference; | 209 | typedef typename StringType::const_reference const_storage_reference; |
3531 | 210 | |||
3532 | 210 | typedef typename StringType::iterator storage_iterator; | 211 | typedef typename StringType::iterator storage_iterator; |
3533 | 211 | typedef typename StringType::const_iterator const_storage_iterator; | 212 | typedef typename StringType::const_iterator const_storage_iterator; |
3534 | 213 | typedef typename StringType::reverse_iterator storage_reverse_iterator; | ||
3535 | 214 | typedef typename StringType::const_reverse_iterator | ||
3536 | 215 | const_storage_reverse_iterator; | ||
3537 | 212 | 216 | ||
3538 | 213 | typedef typename utf8::iterator<storage_iterator> iterator; | 217 | typedef typename utf8::iterator<storage_iterator> iterator; |
3539 | 214 | typedef typename utf8::iterator<const_storage_iterator> const_iterator; | 218 | typedef typename utf8::iterator<const_storage_iterator> const_iterator; |
3540 | @@ -1005,6 +1009,16 @@ | |||
3541 | 1005 | } | 1009 | } |
3542 | 1006 | 1010 | ||
3543 | 1007 | /** | 1011 | /** |
3544 | 1012 | * Returns a read-only iterator positioned at the same byte as the given | ||
3545 | 1013 | * iterator of the string. | ||
3546 | 1014 | * | ||
3547 | 1015 | * @return Returns said iterator. | ||
3548 | 1016 | */ | ||
3549 | 1017 | const_iterator current( const_storage_iterator const &i ) const { | ||
3550 | 1018 | return const_iterator( i ); | ||
3551 | 1019 | } | ||
3552 | 1020 | |||
3553 | 1021 | /** | ||
3554 | 1008 | * Returns a read-only reverse iterator positioned at the first character | 1022 | * Returns a read-only reverse iterator positioned at the first character |
3555 | 1009 | * (not byte) of the string. | 1023 | * (not byte) of the string. |
3556 | 1010 | * | 1024 | * |
3557 | @@ -1024,6 +1038,17 @@ | |||
3558 | 1024 | return const_reverse_iterator( begin() ); | 1038 | return const_reverse_iterator( begin() ); |
3559 | 1025 | } | 1039 | } |
3560 | 1026 | 1040 | ||
3561 | 1041 | /** | ||
3562 | 1042 | * Returns a read-only reverse iterator positioned at the same byte as the | ||
3563 | 1043 | * given reverse iterator of the string. | ||
3564 | 1044 | * | ||
3565 | 1045 | * @return Returns said iterator. | ||
3566 | 1046 | */ | ||
3567 | 1047 | const_reverse_iterator | ||
3568 | 1048 | current( const_storage_reverse_iterator const &i ) const { | ||
3569 | 1049 | return const_reverse_iterator( i ); | ||
3570 | 1050 | } | ||
3571 | 1051 | |||
3572 | 1027 | ////////// miscellaneous //////////////////////////////////////////////////// | 1052 | ////////// miscellaneous //////////////////////////////////////////////////// |
3573 | 1028 | 1053 | ||
3574 | 1029 | /** | 1054 | /** |
3575 | 1030 | 1055 | ||
3576 | === modified file 'src/util/utf8_util.cpp' | |||
3577 | --- src/util/utf8_util.cpp 2013-02-07 17:24:36 +0000 | |||
3578 | +++ src/util/utf8_util.cpp 2013-03-21 16:00:34 +0000 | |||
3579 | @@ -15,6 +15,9 @@ | |||
3580 | 15 | */ | 15 | */ |
3581 | 16 | #include "stdafx.h" | 16 | #include "stdafx.h" |
3582 | 17 | 17 | ||
3583 | 18 | #include <algorithm> | ||
3584 | 19 | #include <cstring> | ||
3585 | 20 | |||
3586 | 18 | #ifndef ZORBA_NO_ICU | 21 | #ifndef ZORBA_NO_ICU |
3587 | 19 | #include <unicode/ustring.h> | 22 | #include <unicode/ustring.h> |
3588 | 20 | #endif /* ZORBA_NO_ICU */ | 23 | #endif /* ZORBA_NO_ICU */ |
3589 | @@ -144,6 +147,35 @@ | |||
3590 | 144 | return len; | 147 | return len; |
3591 | 145 | } | 148 | } |
3592 | 146 | 149 | ||
3593 | 150 | storage_type* itou( unsigned long long n, storage_type *buf, | ||
3594 | 151 | unicode::code_point zero ) { | ||
3595 | 152 | storage_type *s = buf; | ||
3596 | 153 | encoded_char_type utf8_digit[10]; // cache of UTF-8 bytes for each digit | ||
3597 | 154 | size_type utf8_size[10]; // number of UTF-8 bytes for each digit | ||
3598 | 155 | |||
3599 | 156 | std::fill( utf8_size, utf8_size + 10, 0 ); | ||
3600 | 157 | do { | ||
3601 | 158 | unsigned long long const n_prev = n; | ||
3602 | 159 | n /= 10; | ||
3603 | 160 | unsigned const digit = n_prev - n * 10; | ||
3604 | 161 | if ( !utf8_size[ digit ] ) // didn't cache previously: cache now | ||
3605 | 162 | utf8_size[ digit ] = encode( zero + digit, utf8_digit[ digit ] ); | ||
3606 | 163 | // | ||
3607 | 164 | // Copy the UTF-8 bytes into buf backwards so when we reverse the entire | ||
3608 | 165 | // buffer later (to reverse the digit order to put them the right way | ||
3609 | 166 | // around), we can treat buf as a simple string and ignore multi-byte UTF-8 | ||
3610 | 167 | // character boundaries. | ||
3611 | 168 | // | ||
3612 | 169 | for ( size_type i = utf8_size[ digit ]; i; ) | ||
3613 | 170 | *s++ = utf8_digit[ digit ][ --i ]; | ||
3614 | 171 | |||
3615 | 172 | } while ( n ); | ||
3616 | 173 | |||
3617 | 174 | *s = '\0'; | ||
3618 | 175 | std::reverse( buf, s ); | ||
3619 | 176 | return buf; | ||
3620 | 177 | } | ||
3621 | 178 | |||
3622 | 147 | size_type length( storage_type const *begin, storage_type const *end ) { | 179 | size_type length( storage_type const *begin, storage_type const *end ) { |
3623 | 148 | size_type len = 0; | 180 | size_type len = 0; |
3624 | 149 | while ( begin < end && *begin ) { | 181 | while ( begin < end && *begin ) { |
3625 | 150 | 182 | ||
3626 | === modified file 'src/util/utf8_util.h' | |||
3627 | --- src/util/utf8_util.h 2013-02-07 17:24:36 +0000 | |||
3628 | +++ src/util/utf8_util.h 2013-03-21 16:00:34 +0000 | |||
3629 | @@ -306,6 +306,31 @@ | |||
3630 | 306 | std::copy( u.begin(), u.end(), std::back_inserter( *c ) ); | 306 | std::copy( u.begin(), u.end(), std::back_inserter( *c ) ); |
3631 | 307 | } | 307 | } |
3632 | 308 | 308 | ||
3633 | 309 | ////////// Integer-to-string conversion /////////////////////////////////////// | ||
3634 | 310 | |||
3635 | 311 | /** | ||
3636 | 312 | * A type that can hold the largest possible C string equivalent of the largest | ||
3637 | 313 | * possible integral value using any Unicode numeric range within the Nd | ||
3638 | 314 | * ("Number, Decimal Digit") category. | ||
3639 | 315 | */ | ||
3640 | 316 | typedef storage_type itou_buf_type[ | ||
3641 | 317 | (sizeof( encoded_char_type ) - 1 /* subtract null */) * 20 + 1 /* add null */ | ||
3642 | 318 | ]; | ||
3643 | 319 | |||
3644 | 320 | /** | ||
3645 | 321 | * Converts an <code>unsigned long long</code> to a UTF-8 encoded string. | ||
3646 | 322 | * | ||
3647 | 323 | * @param n The <code>unsigned long long</code> to convert. | ||
3648 | 324 | * @param buf The buffer for the result. The caller must ensure it's of | ||
3649 | 325 | * sufficient size. | ||
3650 | 326 | * @param zero The Unicode code-point of the zero at the start of a 10 | ||
3651 | 327 | * code-point range [zero,zero+9] for the digits to use in the Nd ("Number, | ||
3652 | 328 | * Decimal Digit") category. | ||
3653 | 329 | * @return Returns \a buf for convenience. | ||
3654 | 330 | */ | ||
3655 | 331 | storage_type* itou( unsigned long long n, storage_type *buf, | ||
3656 | 332 | unicode::code_point zero ); | ||
3657 | 333 | |||
3658 | 309 | ////////// Encoding conversion //////////////////////////////////////////////// | 334 | ////////// Encoding conversion //////////////////////////////////////////////// |
3659 | 310 | 335 | ||
3660 | 311 | #ifndef ZORBA_NO_ICU | 336 | #ifndef ZORBA_NO_ICU |
3661 | @@ -737,6 +762,48 @@ | |||
3662 | 737 | ////////// Miscellaneous ////////////////////////////////////////////////////// | 762 | ////////// Miscellaneous ////////////////////////////////////////////////////// |
3663 | 738 | 763 | ||
3664 | 739 | /** | 764 | /** |
3665 | 765 | * Pads a string to the left with a given code-point until the string is the | ||
3666 | 766 | * given width. | ||
3667 | 767 | * | ||
3668 | 768 | * @param s The string to pad. | ||
3669 | 769 | * @param width The width to pad to. | ||
3670 | 770 | * @param cp The code-point to pad with. | ||
3671 | 771 | * @return Returns \c *s. | ||
3672 | 772 | */ | ||
3673 | 773 | template<class StringType> inline | ||
3674 | 774 | StringType& left_pad( StringType *s, typename StringType::size_type width, | ||
3675 | 775 | unicode::code_point cp ) { | ||
3676 | 776 | typedef typename utf8_stringify<StringType>::type u_type; | ||
3677 | 777 | typedef typename u_type::size_type u_size_type; | ||
3678 | 778 | u_type u( *s ); | ||
3679 | 779 | u_size_type const u_size( u.size() ); | ||
3680 | 780 | if ( u_size < width ) | ||
3681 | 781 | u.insert( static_cast<size_type>( 0 ), width - u_size, cp ); | ||
3682 | 782 | return *s; | ||
3683 | 783 | } | ||
3684 | 784 | |||
3685 | 785 | /** | ||
3686 | 786 | * Pads a string to the right with a given code-point until the string is the | ||
3687 | 787 | * given width. | ||
3688 | 788 | * | ||
3689 | 789 | * @param s The string to pad. | ||
3690 | 790 | * @param width The width to pad to. | ||
3691 | 791 | * @param cp The code-point to pad with. | ||
3692 | 792 | * @return Returns \c *s. | ||
3693 | 793 | */ | ||
3694 | 794 | template<class StringType> inline | ||
3695 | 795 | StringType& right_pad( StringType *s, typename StringType::size_type width, | ||
3696 | 796 | unicode::code_point cp ) { | ||
3697 | 797 | typedef typename utf8_stringify<StringType>::type u_type; | ||
3698 | 798 | typedef typename u_type::size_type u_size_type; | ||
3699 | 799 | u_type u( *s ); | ||
3700 | 800 | u_size_type const u_size( u.size() ); | ||
3701 | 801 | if ( u_size < width ) | ||
3702 | 802 | u.append( width - u_size, cp ); | ||
3703 | 803 | return *s; | ||
3704 | 804 | } | ||
3705 | 805 | |||
3706 | 806 | /** | ||
3707 | 740 | * Reverses the characters in a string. | 807 | * Reverses the characters in a string. |
3708 | 741 | * | 808 | * |
3709 | 742 | * @tparam InputStringType The input string type. | 809 | * @tparam InputStringType The input string type. |
3710 | 743 | 810 | ||
3711 | === modified file 'src/zorbatypes/datetime.h' | |||
3712 | --- src/zorbatypes/datetime.h 2013-03-12 17:03:31 +0000 | |||
3713 | +++ src/zorbatypes/datetime.h 2013-03-21 16:00:34 +0000 | |||
3714 | @@ -250,16 +250,10 @@ | |||
3715 | 250 | */ | 250 | */ |
3716 | 251 | static int parseGDay(const char* str, ascii::size_type strlen, DateTime& dt); | 251 | static int parseGDay(const char* str, ascii::size_type strlen, DateTime& dt); |
3717 | 252 | 252 | ||
3718 | 253 | static int getDayOfWeek(int year, int month, int day); | ||
3719 | 254 | |||
3720 | 255 | static int getDayOfYear(int year, int month, int day); | 253 | static int getDayOfYear(int year, int month, int day); |
3721 | 256 | 254 | ||
3722 | 257 | static int getWeekInYear(int year, int month, int day); | ||
3723 | 258 | |||
3724 | 259 | static int getWeekInMonth(int year, int month, int day); | 255 | static int getWeekInMonth(int year, int month, int day); |
3725 | 260 | 256 | ||
3726 | 261 | static bool isLeapYear(int year); | ||
3727 | 262 | |||
3728 | 263 | protected: | 257 | protected: |
3729 | 264 | static int parse_date( | 258 | static int parse_date( |
3730 | 265 | const char* str, | 259 | const char* str, |
3731 | @@ -361,11 +355,8 @@ | |||
3732 | 361 | * with the index being 0 based, with 0 being Sunday, 1 Monday, etc. If the give | 355 | * with the index being 0 based, with 0 being Sunday, 1 Monday, etc. If the give |
3733 | 362 | * DateTime does not have a Date or DateTime facet, the function will return -1. | 356 | * DateTime does not have a Date or DateTime facet, the function will return -1. |
3734 | 363 | */ | 357 | */ |
3735 | 364 | int getDayOfWeek() const; | ||
3736 | 365 | int getDayOfYear() const; | 358 | int getDayOfYear() const; |
3737 | 366 | int getWeekInYear() const; | ||
3738 | 367 | int getWeekInMonth() const; | 359 | int getWeekInMonth() const; |
3739 | 368 | bool isLeapYear() const; | ||
3740 | 369 | 360 | ||
3741 | 370 | protected: | 361 | protected: |
3742 | 371 | Duration* toDayTimeDuration() const; | 362 | Duration* toDayTimeDuration() const; |
3743 | 372 | 363 | ||
3744 | === modified file 'src/zorbatypes/datetime/datetimetype.cpp' | |||
3745 | --- src/zorbatypes/datetime/datetimetype.cpp 2013-03-12 17:03:31 +0000 | |||
3746 | +++ src/zorbatypes/datetime/datetimetype.cpp 2013-03-21 16:00:34 +0000 | |||
3747 | @@ -39,6 +39,7 @@ | |||
3748 | 39 | #include "zorbatypes/datetime/parse.h" | 39 | #include "zorbatypes/datetime/parse.h" |
3749 | 40 | 40 | ||
3750 | 41 | #include "util/ascii_util.h" | 41 | #include "util/ascii_util.h" |
3751 | 42 | #include "util/time_util.h" | ||
3752 | 42 | 43 | ||
3753 | 43 | 44 | ||
3754 | 44 | namespace zorba | 45 | namespace zorba |
3755 | @@ -47,7 +48,7 @@ | |||
3756 | 47 | static const char separators[] = { '-', '-', 'T', ':', ':', '.'}; | 48 | static const char separators[] = { '-', '-', 'T', ':', ':', '.'}; |
3757 | 48 | 49 | ||
3758 | 49 | static const char min_length[] = { 4, 2, 2, 2, 2, 2, 0}; | 50 | static const char min_length[] = { 4, 2, 2, 2, 2, 2, 0}; |
3760 | 50 | 51 | ||
3761 | 51 | 52 | ||
3762 | 52 | const int DateTime::FACET_MEMBERS[][8] = | 53 | const int DateTime::FACET_MEMBERS[][8] = |
3763 | 53 | { | 54 | { |
3764 | @@ -79,7 +80,7 @@ | |||
3765 | 79 | 80 | ||
3766 | 80 | for (int i = YEAR_DATA; i <= DAY_DATA; i++) | 81 | for (int i = YEAR_DATA; i <= DAY_DATA; i++) |
3767 | 81 | data[i] = 1; | 82 | data[i] = 1; |
3769 | 82 | 83 | ||
3770 | 83 | for (int i = HOUR_DATA; i <= FRACSECONDS_DATA; i++) | 84 | for (int i = HOUR_DATA; i <= FRACSECONDS_DATA; i++) |
3771 | 84 | data[i] = 0; | 85 | data[i] = 0; |
3772 | 85 | 86 | ||
3773 | @@ -158,10 +159,10 @@ | |||
3774 | 158 | dt.data[MINUTE_DATA] = std::abs(minutes); | 159 | dt.data[MINUTE_DATA] = std::abs(minutes); |
3775 | 159 | dt.data[SECONDS_DATA] = std::floor(std::fabs(seconds)); | 160 | dt.data[SECONDS_DATA] = std::floor(std::fabs(seconds)); |
3776 | 160 | dt.data[FRACSECONDS_DATA] = round(frac(std::fabs(seconds)) * FRAC_SECONDS_UPPER_LIMIT); | 161 | dt.data[FRACSECONDS_DATA] = round(frac(std::fabs(seconds)) * FRAC_SECONDS_UPPER_LIMIT); |
3778 | 161 | 162 | ||
3779 | 162 | if (tz != NULL) | 163 | if (tz != NULL) |
3780 | 163 | dt.the_time_zone = *tz; | 164 | dt.the_time_zone = *tz; |
3782 | 164 | 165 | ||
3783 | 165 | return 0; | 166 | return 0; |
3784 | 166 | } | 167 | } |
3785 | 167 | 168 | ||
3786 | @@ -185,7 +186,7 @@ | |||
3787 | 185 | dt.data[MINUTE_DATA] = std::abs(minutes); | 186 | dt.data[MINUTE_DATA] = std::abs(minutes); |
3788 | 186 | dt.data[SECONDS_DATA] = std::abs(seconds); | 187 | dt.data[SECONDS_DATA] = std::abs(seconds); |
3789 | 187 | dt.data[FRACSECONDS_DATA] = std::abs(fractional_seconds); | 188 | dt.data[FRACSECONDS_DATA] = std::abs(fractional_seconds); |
3791 | 188 | 189 | ||
3792 | 189 | if (tz != NULL) | 190 | if (tz != NULL) |
3793 | 190 | dt.the_time_zone = *tz; | 191 | dt.the_time_zone = *tz; |
3794 | 191 | 192 | ||
3795 | @@ -211,7 +212,7 @@ | |||
3796 | 211 | 212 | ||
3797 | 212 | if (tz != NULL) | 213 | if (tz != NULL) |
3798 | 213 | dt.the_time_zone = *tz; | 214 | dt.the_time_zone = *tz; |
3800 | 214 | 215 | ||
3801 | 215 | return 0; | 216 | return 0; |
3802 | 216 | } | 217 | } |
3803 | 217 | 218 | ||
3804 | @@ -231,10 +232,10 @@ | |||
3805 | 231 | dt.data[MINUTE_DATA] = std::abs(minutes); | 232 | dt.data[MINUTE_DATA] = std::abs(minutes); |
3806 | 232 | dt.data[SECONDS_DATA] = std::floor(std::fabs(seconds)); | 233 | dt.data[SECONDS_DATA] = std::floor(std::fabs(seconds)); |
3807 | 233 | dt.data[FRACSECONDS_DATA] = round(frac(std::fabs(seconds)) * FRAC_SECONDS_UPPER_LIMIT); | 234 | dt.data[FRACSECONDS_DATA] = round(frac(std::fabs(seconds)) * FRAC_SECONDS_UPPER_LIMIT); |
3809 | 234 | 235 | ||
3810 | 235 | if (tz != NULL) | 236 | if (tz != NULL) |
3811 | 236 | dt.the_time_zone = *tz; | 237 | dt.the_time_zone = *tz; |
3813 | 237 | 238 | ||
3814 | 238 | return 0; | 239 | return 0; |
3815 | 239 | } | 240 | } |
3816 | 240 | 241 | ||
3817 | @@ -352,7 +353,7 @@ | |||
3818 | 352 | ascii::skip_whitespace(str, len, &pos); | 353 | ascii::skip_whitespace(str, len, &pos); |
3819 | 353 | 354 | ||
3820 | 354 | dt.facet = DATETIME_FACET; | 355 | dt.facet = DATETIME_FACET; |
3822 | 355 | 356 | ||
3823 | 356 | if (parse_date(str, | 357 | if (parse_date(str, |
3824 | 357 | len, | 358 | len, |
3825 | 358 | pos, | 359 | pos, |
3826 | @@ -363,7 +364,7 @@ | |||
3827 | 363 | 364 | ||
3828 | 364 | if (pos == len || str[pos++] != 'T') | 365 | if (pos == len || str[pos++] != 'T') |
3829 | 365 | return 1; | 366 | return 1; |
3831 | 366 | 367 | ||
3832 | 367 | if (parse_time(str, | 368 | if (parse_time(str, |
3833 | 368 | len, | 369 | len, |
3834 | 369 | pos, | 370 | pos, |
3835 | @@ -372,7 +373,7 @@ | |||
3836 | 372 | dt.data[SECONDS_DATA], | 373 | dt.data[SECONDS_DATA], |
3837 | 373 | dt.data[FRACSECONDS_DATA])) | 374 | dt.data[FRACSECONDS_DATA])) |
3838 | 374 | return 1; | 375 | return 1; |
3840 | 375 | 376 | ||
3841 | 376 | ascii::size_type savepos = pos; | 377 | ascii::size_type savepos = pos; |
3842 | 377 | 378 | ||
3843 | 378 | ascii::skip_whitespace(str, len, &pos); | 379 | ascii::skip_whitespace(str, len, &pos); |
3844 | @@ -387,7 +388,7 @@ | |||
3845 | 387 | dt.the_time_zone)) | 388 | dt.the_time_zone)) |
3846 | 388 | return 1; | 389 | return 1; |
3847 | 389 | } | 390 | } |
3849 | 390 | 391 | ||
3850 | 391 | if (dt.data[HOUR_DATA] == 24) | 392 | if (dt.data[HOUR_DATA] == 24) |
3851 | 392 | { | 393 | { |
3852 | 393 | dt.data[HOUR_DATA] = 0; | 394 | dt.data[HOUR_DATA] = 0; |
3853 | @@ -408,7 +409,7 @@ | |||
3854 | 408 | ascii::skip_whitespace(str, len, &pos); | 409 | ascii::skip_whitespace(str, len, &pos); |
3855 | 409 | 410 | ||
3856 | 410 | dt.facet = DATE_FACET; | 411 | dt.facet = DATE_FACET; |
3858 | 411 | 412 | ||
3859 | 412 | if (parse_date(str, | 413 | if (parse_date(str, |
3860 | 413 | len, | 414 | len, |
3861 | 414 | pos, | 415 | pos, |
3862 | @@ -429,7 +430,7 @@ | |||
3863 | 429 | if (0 != TimeZone::parseTimeZone(str + pos, len - pos, dt.the_time_zone)) | 430 | if (0 != TimeZone::parseTimeZone(str + pos, len - pos, dt.the_time_zone)) |
3864 | 430 | return 1; | 431 | return 1; |
3865 | 431 | } | 432 | } |
3867 | 432 | 433 | ||
3868 | 433 | return 0; | 434 | return 0; |
3869 | 434 | } | 435 | } |
3870 | 435 | 436 | ||
3871 | @@ -441,14 +442,14 @@ | |||
3872 | 441 | ascii::skip_whitespace(str, len, &pos); | 442 | ascii::skip_whitespace(str, len, &pos); |
3873 | 442 | 443 | ||
3874 | 443 | dt.facet = TIME_FACET; | 444 | dt.facet = TIME_FACET; |
3876 | 444 | 445 | ||
3877 | 445 | if (parse_time(str, len, pos, | 446 | if (parse_time(str, len, pos, |
3878 | 446 | dt.data[HOUR_DATA], | 447 | dt.data[HOUR_DATA], |
3879 | 447 | dt.data[MINUTE_DATA], | 448 | dt.data[MINUTE_DATA], |
3880 | 448 | dt.data[SECONDS_DATA], | 449 | dt.data[SECONDS_DATA], |
3881 | 449 | dt.data[FRACSECONDS_DATA])) | 450 | dt.data[FRACSECONDS_DATA])) |
3882 | 450 | return 1; | 451 | return 1; |
3884 | 451 | 452 | ||
3885 | 452 | ascii::size_type savepos = pos; | 453 | ascii::size_type savepos = pos; |
3886 | 453 | 454 | ||
3887 | 454 | ascii::skip_whitespace(str, len, &pos); | 455 | ascii::skip_whitespace(str, len, &pos); |
3888 | @@ -461,7 +462,7 @@ | |||
3889 | 461 | if (0 != TimeZone::parseTimeZone(str + pos, len - pos, dt.the_time_zone)) | 462 | if (0 != TimeZone::parseTimeZone(str + pos, len - pos, dt.the_time_zone)) |
3890 | 462 | return 1; | 463 | return 1; |
3891 | 463 | } | 464 | } |
3893 | 464 | 465 | ||
3894 | 465 | if (dt.data[HOUR_DATA] == 24) | 466 | if (dt.data[HOUR_DATA] == 24) |
3895 | 466 | dt.data[HOUR_DATA] = 0; | 467 | dt.data[HOUR_DATA] = 0; |
3896 | 467 | 468 | ||
3897 | @@ -476,11 +477,11 @@ | |||
3898 | 476 | zstring temp; | 477 | zstring temp; |
3899 | 477 | 478 | ||
3900 | 478 | // GYearMonth of form: '-'? yyyy '-' mm zzzzzz? | 479 | // GYearMonth of form: '-'? yyyy '-' mm zzzzzz? |
3902 | 479 | 480 | ||
3903 | 480 | ascii::skip_whitespace(str, len, &pos); | 481 | ascii::skip_whitespace(str, len, &pos); |
3904 | 481 | 482 | ||
3905 | 482 | dt.facet = GYEARMONTH_FACET; | 483 | dt.facet = GYEARMONTH_FACET; |
3907 | 483 | 484 | ||
3908 | 484 | if (str[pos] == '-') | 485 | if (str[pos] == '-') |
3909 | 485 | { | 486 | { |
3910 | 486 | temp.append(str + pos, (8 < len - pos ? 8 : len - pos)); | 487 | temp.append(str + pos, (8 < len - pos ? 8 : len - pos)); |
3911 | @@ -500,7 +501,7 @@ | |||
3912 | 500 | dt.data[MONTH_DATA], | 501 | dt.data[MONTH_DATA], |
3913 | 501 | dt.data[DAY_DATA])) | 502 | dt.data[DAY_DATA])) |
3914 | 502 | return 1; | 503 | return 1; |
3916 | 503 | 504 | ||
3917 | 504 | pos += 7; | 505 | pos += 7; |
3918 | 505 | 506 | ||
3919 | 506 | ascii::size_type savepos = pos; | 507 | ascii::size_type savepos = pos; |
3920 | @@ -527,11 +528,11 @@ | |||
3921 | 527 | zstring temp; | 528 | zstring temp; |
3922 | 528 | 529 | ||
3923 | 529 | // GYear of form: '-'? yyyy zzzzzz? | 530 | // GYear of form: '-'? yyyy zzzzzz? |
3925 | 530 | 531 | ||
3926 | 531 | ascii::skip_whitespace(str, len, &pos); | 532 | ascii::skip_whitespace(str, len, &pos); |
3927 | 532 | 533 | ||
3928 | 533 | dt.facet = GYEAR_FACET; | 534 | dt.facet = GYEAR_FACET; |
3930 | 534 | 535 | ||
3931 | 535 | temp.reserve(12); | 536 | temp.reserve(12); |
3932 | 536 | 537 | ||
3933 | 537 | if (str[pos] == '-') | 538 | if (str[pos] == '-') |
3934 | @@ -553,7 +554,7 @@ | |||
3935 | 553 | dt.data[MONTH_DATA], | 554 | dt.data[MONTH_DATA], |
3936 | 554 | dt.data[DAY_DATA])) | 555 | dt.data[DAY_DATA])) |
3937 | 555 | return 1; | 556 | return 1; |
3939 | 556 | 557 | ||
3940 | 557 | pos += 4; | 558 | pos += 4; |
3941 | 558 | 559 | ||
3942 | 559 | ascii::size_type savepos = pos; | 560 | ascii::size_type savepos = pos; |
3943 | @@ -581,11 +582,11 @@ | |||
3944 | 581 | 582 | ||
3945 | 582 | // GMonth of form: --MM zzzzzz? | 583 | // GMonth of form: --MM zzzzzz? |
3946 | 583 | // preceding - is not allowed. | 584 | // preceding - is not allowed. |
3948 | 584 | 585 | ||
3949 | 585 | ascii::skip_whitespace(str, len, &pos); | 586 | ascii::skip_whitespace(str, len, &pos); |
3950 | 586 | 587 | ||
3951 | 587 | dt.facet = GMONTH_FACET; | 588 | dt.facet = GMONTH_FACET; |
3953 | 588 | 589 | ||
3954 | 589 | if (str[pos++] != '-') | 590 | if (str[pos++] != '-') |
3955 | 590 | return 1; | 591 | return 1; |
3956 | 591 | 592 | ||
3957 | @@ -601,7 +602,7 @@ | |||
3958 | 601 | dt.data[MONTH_DATA], | 602 | dt.data[MONTH_DATA], |
3959 | 602 | dt.data[DAY_DATA])) | 603 | dt.data[DAY_DATA])) |
3960 | 603 | return 1; | 604 | return 1; |
3962 | 604 | 605 | ||
3963 | 605 | pos += 3; | 606 | pos += 3; |
3964 | 606 | 607 | ||
3965 | 607 | ascii::size_type savepos = pos; | 608 | ascii::size_type savepos = pos; |
3966 | @@ -633,10 +634,10 @@ | |||
3967 | 633 | ascii::skip_whitespace(str, len, &pos); | 634 | ascii::skip_whitespace(str, len, &pos); |
3968 | 634 | 635 | ||
3969 | 635 | dt.facet = GMONTHDAY_FACET; | 636 | dt.facet = GMONTHDAY_FACET; |
3971 | 636 | 637 | ||
3972 | 637 | if (str[pos++] != '-') | 638 | if (str[pos++] != '-') |
3973 | 638 | return 1; | 639 | return 1; |
3975 | 639 | 640 | ||
3976 | 640 | temp.reserve(12); | 641 | temp.reserve(12); |
3977 | 641 | temp = "0004"; | 642 | temp = "0004"; |
3978 | 642 | temp.append(str + pos, 6); // Year 4 to make it a leap year, to allow the MonthDay of 29 February | 643 | temp.append(str + pos, 6); // Year 4 to make it a leap year, to allow the MonthDay of 29 February |
3979 | @@ -650,7 +651,7 @@ | |||
3980 | 650 | return 1; | 651 | return 1; |
3981 | 651 | 652 | ||
3982 | 652 | dt.data[YEAR_DATA] = 1; | 653 | dt.data[YEAR_DATA] = 1; |
3984 | 653 | 654 | ||
3985 | 654 | pos += 6; | 655 | pos += 6; |
3986 | 655 | 656 | ||
3987 | 656 | ascii::size_type savepos = pos; | 657 | ascii::size_type savepos = pos; |
3988 | @@ -678,17 +679,17 @@ | |||
3989 | 678 | 679 | ||
3990 | 679 | // GDay of form: ---DD zzzzzz? | 680 | // GDay of form: ---DD zzzzzz? |
3991 | 680 | // preceding - is not allowed. | 681 | // preceding - is not allowed. |
3993 | 681 | 682 | ||
3994 | 682 | ascii::skip_whitespace(str, len, &pos); | 683 | ascii::skip_whitespace(str, len, &pos); |
3995 | 683 | 684 | ||
3996 | 684 | dt.facet = GDAY_FACET; | 685 | dt.facet = GDAY_FACET; |
4004 | 685 | 686 | ||
4005 | 686 | if (str[pos++] != '-') | 687 | if (str[pos++] != '-') |
4006 | 687 | return 1; | 688 | return 1; |
4007 | 688 | 689 | ||
4008 | 689 | if (str[pos++] != '-') | 690 | if (str[pos++] != '-') |
4009 | 690 | return 1; | 691 | return 1; |
4010 | 691 | 692 | ||
4011 | 692 | temp = "0001-01"; | 693 | temp = "0001-01"; |
4012 | 693 | temp.append(str + pos, 3); | 694 | temp.append(str + pos, 3); |
4013 | 694 | 695 | ||
4014 | @@ -699,7 +700,7 @@ | |||
4015 | 699 | dt.data[MONTH_DATA], | 700 | dt.data[MONTH_DATA], |
4016 | 700 | dt.data[DAY_DATA])) | 701 | dt.data[DAY_DATA])) |
4017 | 701 | return 1; | 702 | return 1; |
4019 | 702 | 703 | ||
4020 | 703 | pos += 3; | 704 | pos += 3; |
4021 | 704 | 705 | ||
4022 | 705 | ascii::size_type savepos = pos; | 706 | ascii::size_type savepos = pos; |
4023 | @@ -730,7 +731,7 @@ | |||
4024 | 730 | { | 731 | { |
4025 | 731 | bool is_negative = false; | 732 | bool is_negative = false; |
4026 | 732 | ascii::size_type temp_pos; | 733 | ascii::size_type temp_pos; |
4028 | 733 | 734 | ||
4029 | 734 | if (pos == len) | 735 | if (pos == len) |
4030 | 735 | return 1; | 736 | return 1; |
4031 | 736 | 737 | ||
4032 | @@ -765,18 +766,18 @@ | |||
4033 | 765 | // Parse day | 766 | // Parse day |
4034 | 766 | if (pos == len || parse_long(str, len, pos, day, 2, 2)) | 767 | if (pos == len || parse_long(str, len, pos, day, 2, 2)) |
4035 | 767 | return 1; | 768 | return 1; |
4037 | 768 | 769 | ||
4038 | 769 | // Validate the date | 770 | // Validate the date |
4039 | 770 | // year may not be 0 | 771 | // year may not be 0 |
4040 | 771 | if (year == 0) | 772 | if (year == 0) |
4041 | 772 | return 1; | 773 | return 1; |
4043 | 773 | 774 | ||
4044 | 774 | if (month < 1 || month > 12) | 775 | if (month < 1 || month > 12) |
4045 | 775 | return 1; | 776 | return 1; |
4046 | 776 | 777 | ||
4047 | 777 | if (day < 1 || day > get_last_day(year, month)) | 778 | if (day < 1 || day > get_last_day(year, month)) |
4048 | 778 | return 1; | 779 | return 1; |
4050 | 779 | 780 | ||
4051 | 780 | return 0; | 781 | return 0; |
4052 | 781 | } | 782 | } |
4053 | 782 | 783 | ||
4054 | @@ -793,7 +794,7 @@ | |||
4055 | 793 | { | 794 | { |
4056 | 794 | if (position == len) | 795 | if (position == len) |
4057 | 795 | return 1; | 796 | return 1; |
4059 | 796 | 797 | ||
4060 | 797 | // Parse hour | 798 | // Parse hour |
4061 | 798 | if (position == len || parse_long(str, len, position, hour, 2, 2)) | 799 | if (position == len || parse_long(str, len, position, hour, 2, 2)) |
4062 | 799 | return 1; | 800 | return 1; |
4063 | @@ -811,7 +812,7 @@ | |||
4064 | 811 | // Parse seconds | 812 | // Parse seconds |
4065 | 812 | if (position == len || parse_long(str, len, position, seconds, 2, 2)) | 813 | if (position == len || parse_long(str, len, position, seconds, 2, 2)) |
4066 | 813 | return 1; | 814 | return 1; |
4068 | 814 | 815 | ||
4069 | 815 | if (position < len && str[position] == '.') | 816 | if (position < len && str[position] == '.') |
4070 | 816 | { | 817 | { |
4071 | 817 | double temp_frac_seconds; | 818 | double temp_frac_seconds; |
4072 | @@ -830,19 +831,19 @@ | |||
4073 | 830 | // Validate the time | 831 | // Validate the time |
4074 | 831 | if (hour > 24) | 832 | if (hour > 24) |
4075 | 832 | return 1; | 833 | return 1; |
4077 | 833 | 834 | ||
4078 | 834 | if (minute > 59) | 835 | if (minute > 59) |
4079 | 835 | return 1; | 836 | return 1; |
4080 | 836 | 837 | ||
4081 | 837 | if (hour == 24 && minute != 0) | 838 | if (hour == 24 && minute != 0) |
4082 | 838 | return 1; | 839 | return 1; |
4084 | 839 | 840 | ||
4085 | 840 | if (seconds > 59) | 841 | if (seconds > 59) |
4086 | 841 | return 1; | 842 | return 1; |
4087 | 842 | 843 | ||
4088 | 843 | if (hour == 24 && (seconds != 0 || frac_seconds != 0)) | 844 | if (hour == 24 && (seconds != 0 || frac_seconds != 0)) |
4089 | 844 | return 1; | 845 | return 1; |
4091 | 845 | 846 | ||
4092 | 846 | return 0; | 847 | return 0; |
4093 | 847 | } | 848 | } |
4094 | 848 | 849 | ||
4095 | @@ -871,18 +872,18 @@ | |||
4096 | 871 | zstring DateTime::toString() const | 872 | zstring DateTime::toString() const |
4097 | 872 | { | 873 | { |
4098 | 873 | zstring result; | 874 | zstring result; |
4100 | 874 | 875 | ||
4101 | 875 | // output sign | 876 | // output sign |
4102 | 876 | if (FACET_MEMBERS[facet][0]) | 877 | if (FACET_MEMBERS[facet][0]) |
4103 | 877 | if (data[YEAR_DATA] < 0) | 878 | if (data[YEAR_DATA] < 0) |
4104 | 878 | result.append("-", 1); | 879 | result.append("-", 1); |
4106 | 879 | 880 | ||
4107 | 880 | // output preceding '-' for Gregorian dates, when needed | 881 | // output preceding '-' for Gregorian dates, when needed |
4108 | 881 | if (facet == GMONTH_FACET || facet == GMONTHDAY_FACET) | 882 | if (facet == GMONTH_FACET || facet == GMONTHDAY_FACET) |
4109 | 882 | result.append("--", 2); | 883 | result.append("--", 2); |
4110 | 883 | if (facet == GDAY_FACET) | 884 | if (facet == GDAY_FACET) |
4111 | 884 | result.append("---", 3); | 885 | result.append("---", 3); |
4113 | 885 | 886 | ||
4114 | 886 | for (int i=0; i<=5; i++) | 887 | for (int i=0; i<=5; i++) |
4115 | 887 | { | 888 | { |
4116 | 888 | if (FACET_MEMBERS[facet][i]) | 889 | if (FACET_MEMBERS[facet][i]) |
4117 | @@ -892,12 +893,12 @@ | |||
4118 | 892 | result.push_back(separators[i]); | 893 | result.push_back(separators[i]); |
4119 | 893 | } | 894 | } |
4120 | 894 | } | 895 | } |
4122 | 895 | 896 | ||
4123 | 896 | if (FACET_MEMBERS[facet][FRACSECONDS_DATA] && (data[FRACSECONDS_DATA] != 0)) | 897 | if (FACET_MEMBERS[facet][FRACSECONDS_DATA] && (data[FRACSECONDS_DATA] != 0)) |
4124 | 897 | { | 898 | { |
4125 | 898 | int temp; | 899 | int temp; |
4126 | 899 | result.append(".", 1); | 900 | result.append(".", 1); |
4128 | 900 | 901 | ||
4129 | 901 | // print leading 0s, if any | 902 | // print leading 0s, if any |
4130 | 902 | temp = FRAC_SECONDS_UPPER_LIMIT / 10; | 903 | temp = FRAC_SECONDS_UPPER_LIMIT / 10; |
4131 | 903 | while (temp > data[FRACSECONDS_DATA] && temp > 0) | 904 | while (temp > data[FRACSECONDS_DATA] && temp > 0) |
4132 | @@ -905,17 +906,17 @@ | |||
4133 | 905 | result.append("0", 1); | 906 | result.append("0", 1); |
4134 | 906 | temp /= 10; | 907 | temp /= 10; |
4135 | 907 | } | 908 | } |
4137 | 908 | 909 | ||
4138 | 909 | // strip trailing 0s, if any | 910 | // strip trailing 0s, if any |
4139 | 910 | temp = data[FRACSECONDS_DATA]; | 911 | temp = data[FRACSECONDS_DATA]; |
4140 | 911 | while (temp%10 == 0 && temp > 0) | 912 | while (temp%10 == 0 && temp > 0) |
4141 | 912 | temp = temp / 10; | 913 | temp = temp / 10; |
4143 | 913 | 914 | ||
4144 | 914 | result.append(ztd::to_string(temp)); | 915 | result.append(ztd::to_string(temp)); |
4145 | 915 | } | 916 | } |
4147 | 916 | 917 | ||
4148 | 917 | result.append(the_time_zone.toString()); | 918 | result.append(the_time_zone.toString()); |
4150 | 918 | 919 | ||
4151 | 919 | return result; | 920 | return result; |
4152 | 920 | } | 921 | } |
4153 | 921 | 922 | ||
4154 | @@ -984,7 +985,7 @@ | |||
4155 | 984 | assert(data[SECONDS_DATA] >= 0); | 985 | assert(data[SECONDS_DATA] >= 0); |
4156 | 985 | return data[SECONDS_DATA]; | 986 | return data[SECONDS_DATA]; |
4157 | 986 | } | 987 | } |
4159 | 987 | 988 | ||
4160 | 988 | 989 | ||
4161 | 989 | int DateTime::getFractionalSeconds() const | 990 | int DateTime::getFractionalSeconds() const |
4162 | 990 | { | 991 | { |
4163 | @@ -1003,21 +1004,21 @@ | |||
4164 | 1003 | { | 1004 | { |
4165 | 1004 | return !the_time_zone.timeZoneNotSet(); | 1005 | return !the_time_zone.timeZoneNotSet(); |
4166 | 1005 | } | 1006 | } |
4169 | 1006 | 1007 | ||
4170 | 1007 | 1008 | ||
4171 | 1008 | int DateTime::compare(const DateTime* dt, long timezone_seconds) const | 1009 | int DateTime::compare(const DateTime* dt, long timezone_seconds) const |
4172 | 1009 | { | 1010 | { |
4173 | 1010 | std::auto_ptr<DateTime> d1_t; | 1011 | std::auto_ptr<DateTime> d1_t; |
4174 | 1011 | std::auto_ptr<DateTime> d2_t; | 1012 | std::auto_ptr<DateTime> d2_t; |
4176 | 1012 | 1013 | ||
4177 | 1013 | d1_t.reset(normalizeTimeZone(timezone_seconds)); | 1014 | d1_t.reset(normalizeTimeZone(timezone_seconds)); |
4178 | 1014 | d2_t.reset(dt->normalizeTimeZone(timezone_seconds)); | 1015 | d2_t.reset(dt->normalizeTimeZone(timezone_seconds)); |
4180 | 1015 | 1016 | ||
4181 | 1016 | if (d1_t->data[YEAR_DATA] < d2_t->data[YEAR_DATA]) | 1017 | if (d1_t->data[YEAR_DATA] < d2_t->data[YEAR_DATA]) |
4182 | 1017 | return -1; | 1018 | return -1; |
4183 | 1018 | else if (d1_t->data[YEAR_DATA] > d2_t->data[YEAR_DATA]) | 1019 | else if (d1_t->data[YEAR_DATA] > d2_t->data[YEAR_DATA]) |
4184 | 1019 | return 1; | 1020 | return 1; |
4186 | 1020 | 1021 | ||
4187 | 1021 | // compare the rest of the data | 1022 | // compare the rest of the data |
4188 | 1022 | if (d1_t->data[YEAR_DATA] < 0 && d2_t->data[YEAR_DATA] < 0) | 1023 | if (d1_t->data[YEAR_DATA] < 0 && d2_t->data[YEAR_DATA] < 0) |
4189 | 1023 | { | 1024 | { |
4190 | @@ -1039,7 +1040,7 @@ | |||
4191 | 1039 | return 1; | 1040 | return 1; |
4192 | 1040 | } | 1041 | } |
4193 | 1041 | } | 1042 | } |
4195 | 1042 | 1043 | ||
4196 | 1043 | return 0; | 1044 | return 0; |
4197 | 1044 | } | 1045 | } |
4198 | 1045 | 1046 | ||
4199 | @@ -1048,7 +1049,7 @@ | |||
4200 | 1048 | { | 1049 | { |
4201 | 1049 | uint32_t hval = 0; | 1050 | uint32_t hval = 0; |
4202 | 1050 | std::auto_ptr<DateTime> dt(normalizeTimeZone(implicit_timezone_seconds)); | 1051 | std::auto_ptr<DateTime> dt(normalizeTimeZone(implicit_timezone_seconds)); |
4204 | 1051 | 1052 | ||
4205 | 1052 | hval = hashfun::h32<int>((int)dt->facet, hval); | 1053 | hval = hashfun::h32<int>((int)dt->facet, hval); |
4206 | 1053 | hval = hashfun::h32<int>(dt->data[YEAR_DATA], hval); | 1054 | hval = hashfun::h32<int>(dt->data[YEAR_DATA], hval); |
4207 | 1054 | hval = hashfun::h32<int>(dt->data[MONTH_DATA], hval); | 1055 | hval = hashfun::h32<int>(dt->data[MONTH_DATA], hval); |
4208 | @@ -1057,9 +1058,9 @@ | |||
4209 | 1057 | hval = hashfun::h32<int>(dt->data[MINUTE_DATA], hval); | 1058 | hval = hashfun::h32<int>(dt->data[MINUTE_DATA], hval); |
4210 | 1058 | hval = hashfun::h32<int>(dt->data[SECONDS_DATA], hval); | 1059 | hval = hashfun::h32<int>(dt->data[SECONDS_DATA], hval); |
4211 | 1059 | hval = hashfun::h32<int>(dt->data[FRACSECONDS_DATA], hval); | 1060 | hval = hashfun::h32<int>(dt->data[FRACSECONDS_DATA], hval); |
4213 | 1060 | 1061 | ||
4214 | 1061 | hval = dt->the_time_zone.hash(hval); | 1062 | hval = dt->the_time_zone.hash(hval); |
4216 | 1062 | 1063 | ||
4217 | 1063 | return hval; | 1064 | return hval; |
4218 | 1064 | } | 1065 | } |
4219 | 1065 | 1066 | ||
4220 | @@ -1086,13 +1087,13 @@ | |||
4221 | 1086 | data[MONTH_DATA], | 1087 | data[MONTH_DATA], |
4222 | 1087 | data[DAY_DATA])-1, | 1088 | data[DAY_DATA])-1, |
4223 | 1088 | 0, 0, 0, 0); | 1089 | 0, 0, 0, 0); |
4225 | 1089 | 1090 | ||
4226 | 1090 | Duration remainder(Duration::DAYTIMEDURATION_FACET, false, 0, 0, 0, | 1091 | Duration remainder(Duration::DAYTIMEDURATION_FACET, false, 0, 0, 0, |
4227 | 1091 | data[HOUR_DATA], | 1092 | data[HOUR_DATA], |
4228 | 1092 | data[MINUTE_DATA], | 1093 | data[MINUTE_DATA], |
4229 | 1093 | data[SECONDS_DATA], | 1094 | data[SECONDS_DATA], |
4230 | 1094 | data[FRACSECONDS_DATA]); | 1095 | data[FRACSECONDS_DATA]); |
4232 | 1095 | 1096 | ||
4233 | 1096 | return days + remainder; | 1097 | return days + remainder; |
4234 | 1097 | } | 1098 | } |
4235 | 1098 | } | 1099 | } |
4236 | @@ -1106,7 +1107,7 @@ | |||
4237 | 1106 | 1107 | ||
4238 | 1107 | // For the algorithm, see XML Schema 2 spec, Appendix E | 1108 | // For the algorithm, see XML Schema 2 spec, Appendix E |
4239 | 1108 | // http://www.w3.org/TR/xmlschema-2/#adding-durations-to-dateTimes | 1109 | // http://www.w3.org/TR/xmlschema-2/#adding-durations-to-dateTimes |
4241 | 1109 | 1110 | ||
4242 | 1110 | months = modulo<int>(data[MONTH_DATA] + d.getMonths() - 1, 12) + 1; | 1111 | months = modulo<int>(data[MONTH_DATA] + d.getMonths() - 1, 12) + 1; |
4243 | 1111 | 1112 | ||
4244 | 1112 | years = data[YEAR_DATA] + d.getYears() + | 1113 | years = data[YEAR_DATA] + d.getYears() + |
4245 | @@ -1118,7 +1119,7 @@ | |||
4246 | 1118 | int_seconds = modulo<int>(total_seconds, 60); | 1119 | int_seconds = modulo<int>(total_seconds, 60); |
4247 | 1119 | 1120 | ||
4248 | 1120 | frac_seconds = modulo<int>(temp_frac_seconds, DateTime::FRAC_SECONDS_UPPER_LIMIT); | 1121 | frac_seconds = modulo<int>(temp_frac_seconds, DateTime::FRAC_SECONDS_UPPER_LIMIT); |
4250 | 1121 | 1122 | ||
4251 | 1122 | minutes = data[MINUTE_DATA] + d.getMinutes() + quotient<int>(total_seconds, 60); | 1123 | minutes = data[MINUTE_DATA] + d.getMinutes() + quotient<int>(total_seconds, 60); |
4252 | 1123 | 1124 | ||
4253 | 1124 | hours = data[HOUR_DATA] + d.getHours() + quotient<int>(minutes, 60); | 1125 | hours = data[HOUR_DATA] + d.getHours() + quotient<int>(minutes, 60); |
4254 | @@ -1155,7 +1156,7 @@ | |||
4255 | 1155 | years += quotient<int>(months + carry-1, 12); | 1156 | years += quotient<int>(months + carry-1, 12); |
4256 | 1156 | months = modulo<int>(months + carry -1, 12) + 1; | 1157 | months = modulo<int>(months + carry -1, 12) + 1; |
4257 | 1157 | } | 1158 | } |
4259 | 1158 | 1159 | ||
4260 | 1159 | if (data[YEAR_DATA] > 0 && d.isNegative() && years <= 0) | 1160 | if (data[YEAR_DATA] > 0 && d.isNegative() && years <= 0) |
4261 | 1160 | years--; | 1161 | years--; |
4262 | 1161 | if (data[YEAR_DATA] < 0 && !d.isNegative() && years >= 0) | 1162 | if (data[YEAR_DATA] < 0 && !d.isNegative() && years >= 0) |
4263 | @@ -1167,7 +1168,7 @@ | |||
4264 | 1167 | int_seconds, frac_seconds, &the_time_zone, | 1168 | int_seconds, frac_seconds, &the_time_zone, |
4265 | 1168 | *new_dt)) | 1169 | *new_dt)) |
4266 | 1169 | assert(0); | 1170 | assert(0); |
4268 | 1170 | 1171 | ||
4269 | 1171 | new_dt->facet = facet; | 1172 | new_dt->facet = facet; |
4270 | 1172 | if (adjust_facet) | 1173 | if (adjust_facet) |
4271 | 1173 | new_dt->adjustToFacet(); | 1174 | new_dt->adjustToFacet(); |
4272 | @@ -1199,13 +1200,13 @@ | |||
4273 | 1199 | { | 1200 | { |
4274 | 1200 | DateTime* dt; | 1201 | DateTime* dt; |
4275 | 1201 | Duration d; | 1202 | Duration d; |
4277 | 1202 | 1203 | ||
4278 | 1203 | if( the_time_zone.timeZoneNotSet() ) | 1204 | if( the_time_zone.timeZoneNotSet() ) |
4279 | 1204 | { | 1205 | { |
4280 | 1205 | // validate timezone value (-14 .. +14 H) | 1206 | // validate timezone value (-14 .. +14 H) |
4281 | 1206 | if (tz_seconds > 14*3600 || tz_seconds < -14*3600) | 1207 | if (tz_seconds > 14*3600 || tz_seconds < -14*3600) |
4282 | 1207 | throw InvalidTimezoneException( tz_seconds ); | 1208 | throw InvalidTimezoneException( tz_seconds ); |
4284 | 1208 | 1209 | ||
4285 | 1209 | d = Duration(Duration::DAYTIMEDURATION_FACET, | 1210 | d = Duration(Duration::DAYTIMEDURATION_FACET, |
4286 | 1210 | (tz_seconds < 0), 0, 0, 0, 0, 0, tz_seconds, 0); | 1211 | (tz_seconds < 0), 0, 0, 0, 0, 0, tz_seconds, 0); |
4287 | 1211 | } | 1212 | } |
4288 | @@ -1214,10 +1215,10 @@ | |||
4289 | 1214 | if (0 != Duration::fromTimezone(the_time_zone, d)) | 1215 | if (0 != Duration::fromTimezone(the_time_zone, d)) |
4290 | 1215 | assert(0); | 1216 | assert(0); |
4291 | 1216 | } | 1217 | } |
4293 | 1217 | 1218 | ||
4294 | 1218 | dt = subtractDuration(d, false); // do not adjust to facet | 1219 | dt = subtractDuration(d, false); // do not adjust to facet |
4295 | 1219 | dt->the_time_zone = TimeZone(0); | 1220 | dt->the_time_zone = TimeZone(0); |
4297 | 1220 | 1221 | ||
4298 | 1221 | return dt; | 1222 | return dt; |
4299 | 1222 | } | 1223 | } |
4300 | 1223 | 1224 | ||
4301 | @@ -1227,7 +1228,7 @@ | |||
4302 | 1227 | std::auto_ptr<Duration> dtduration; | 1228 | std::auto_ptr<Duration> dtduration; |
4303 | 1228 | std::auto_ptr<Duration> context_tz; | 1229 | std::auto_ptr<Duration> context_tz; |
4304 | 1229 | std::auto_ptr<DateTime> dt; | 1230 | std::auto_ptr<DateTime> dt; |
4306 | 1230 | 1231 | ||
4307 | 1231 | // validate timezone value (-14 .. +14 H) | 1232 | // validate timezone value (-14 .. +14 H) |
4308 | 1232 | if (tz_seconds > 14*3600 || tz_seconds < -14*3600) | 1233 | if (tz_seconds > 14*3600 || tz_seconds < -14*3600) |
4309 | 1233 | throw InvalidTimezoneException( tz_seconds ); | 1234 | throw InvalidTimezoneException( tz_seconds ); |
4310 | @@ -1236,7 +1237,7 @@ | |||
4311 | 1236 | context_tz = std::auto_ptr<Duration>(new Duration(Duration::DAYTIMEDURATION_FACET, (tz_seconds<0), 0, 0, 0, 0, 0, tz_seconds, 0)); | 1237 | context_tz = std::auto_ptr<Duration>(new Duration(Duration::DAYTIMEDURATION_FACET, (tz_seconds<0), 0, 0, 0, 0, 0, tz_seconds, 0)); |
4312 | 1237 | 1238 | ||
4313 | 1238 | dt = std::auto_ptr<DateTime>(new DateTime(*this)); | 1239 | dt = std::auto_ptr<DateTime>(new DateTime(*this)); |
4315 | 1239 | 1240 | ||
4316 | 1240 | // If $arg does not have a timezone component and $timezone is not the empty sequence, | 1241 | // If $arg does not have a timezone component and $timezone is not the empty sequence, |
4317 | 1241 | // then the result is $arg with $timezone as the timezone component. | 1242 | // then the result is $arg with $timezone as the timezone component. |
4318 | 1242 | if (the_time_zone.timeZoneNotSet()) | 1243 | if (the_time_zone.timeZoneNotSet()) |
4319 | @@ -1274,9 +1275,9 @@ | |||
4320 | 1274 | 1275 | ||
4321 | 1275 | // A dynamic error is raised [err:FODT0003] if $timezone is less than -PT14H | 1276 | // A dynamic error is raised [err:FODT0003] if $timezone is less than -PT14H |
4322 | 1276 | // or greater than PT14H or if does not contain an integral number of minutes. | 1277 | // or greater than PT14H or if does not contain an integral number of minutes. |
4324 | 1277 | 1278 | ||
4325 | 1278 | dt = std::auto_ptr<DateTime>(new DateTime(*this)); | 1279 | dt = std::auto_ptr<DateTime>(new DateTime(*this)); |
4327 | 1279 | 1280 | ||
4328 | 1280 | if (d == NULL) | 1281 | if (d == NULL) |
4329 | 1281 | { | 1282 | { |
4330 | 1282 | if (!the_time_zone.timeZoneNotSet()) | 1283 | if (!the_time_zone.timeZoneNotSet()) |
4331 | @@ -1291,7 +1292,7 @@ | |||
4332 | 1291 | d->getHours()*3600 + d->getMinutes()*60 > 14*3600 || | 1292 | d->getHours()*3600 + d->getMinutes()*60 > 14*3600 || |
4333 | 1292 | d->getHours()*3600 + d->getMinutes()*60 < -14*3600) | 1293 | d->getHours()*3600 + d->getMinutes()*60 < -14*3600) |
4334 | 1293 | throw InvalidTimezoneException( d->getHours()*3600 + d->getMinutes()*60 ); | 1294 | throw InvalidTimezoneException( d->getHours()*3600 + d->getMinutes()*60 ); |
4336 | 1294 | 1295 | ||
4337 | 1295 | // If $arg does not have a timezone component and $timezone is not the | 1296 | // If $arg does not have a timezone component and $timezone is not the |
4338 | 1296 | // empty sequence, then the result is $arg with $timezone as the timezone | 1297 | // empty sequence, then the result is $arg with $timezone as the timezone |
4339 | 1297 | // component. | 1298 | // component. |
4340 | @@ -1385,79 +1386,18 @@ | |||
4341 | 1385 | } | 1386 | } |
4342 | 1386 | 1387 | ||
4343 | 1387 | 1388 | ||
4344 | 1388 | int DateTime::getDayOfWeek(int year, int month, int day) | ||
4345 | 1389 | { | ||
4346 | 1390 | if (month < 3) | ||
4347 | 1391 | { | ||
4348 | 1392 | month = month + 12; | ||
4349 | 1393 | year = year - 1; | ||
4350 | 1394 | } | ||
4351 | 1395 | |||
4352 | 1396 | return (day | ||
4353 | 1397 | + (2 * month) | ||
4354 | 1398 | + int(6 * (month + 1) / 10) | ||
4355 | 1399 | + year | ||
4356 | 1400 | + int(year / 4) | ||
4357 | 1401 | - int(year / 100) | ||
4358 | 1402 | + int(year / 400) | ||
4359 | 1403 | + 1 // CalendarSystem, 1 for Gregorian | ||
4360 | 1404 | ) % 7; | ||
4361 | 1405 | } | ||
4362 | 1406 | |||
4363 | 1407 | |||
4364 | 1408 | int DateTime::getWeekInYear(int year, int month, int day) | ||
4365 | 1409 | { | ||
4366 | 1410 | int day_of_year = DateTime::getDayOfYear(year, month, day); | ||
4367 | 1411 | int year_first_day_of_week = DateTime::getDayOfWeek(year, 1, 1); | ||
4368 | 1412 | |||
4369 | 1413 | if (year_first_day_of_week > 4 && (year_first_day_of_week + day_of_year) <= 8) | ||
4370 | 1414 | return getWeekInYear(year-1, 12, 31); | ||
4371 | 1415 | |||
4372 | 1416 | return ((day_of_year + year_first_day_of_week - 2) / 7) + year_first_day_of_week < 5 ? 1 : 0; | ||
4373 | 1417 | } | ||
4374 | 1418 | |||
4375 | 1419 | |||
4376 | 1420 | int DateTime::getDayOfYear(int year, int month, int day) | 1389 | int DateTime::getDayOfYear(int year, int month, int day) |
4377 | 1421 | { | 1390 | { |
4378 | 1422 | static const int days[] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365}; | ||
4379 | 1423 | |||
4380 | 1424 | if (month > 12) | 1391 | if (month > 12) |
4381 | 1425 | return -1; | 1392 | return -1; |
4398 | 1426 | 1393 | return time::calc_yday( day, month - 1, year ) + 1; | |
4383 | 1427 | if (isLeapYear(year) && month >= 3) | ||
4384 | 1428 | day++; | ||
4385 | 1429 | |||
4386 | 1430 | return days[month-1] + day; | ||
4387 | 1431 | } | ||
4388 | 1432 | |||
4389 | 1433 | |||
4390 | 1434 | bool DateTime::isLeapYear(int year) | ||
4391 | 1435 | { | ||
4392 | 1436 | if (((year%4 == 0) && (year%100 != 0)) | ||
4393 | 1437 | || | ||
4394 | 1438 | (year%400 == 0)) | ||
4395 | 1439 | return true; | ||
4396 | 1440 | else | ||
4397 | 1441 | return false; | ||
4399 | 1442 | } | 1394 | } |
4400 | 1443 | 1395 | ||
4401 | 1444 | 1396 | ||
4402 | 1445 | int DateTime::getWeekInMonth(int year, int month, int day) | 1397 | int DateTime::getWeekInMonth(int year, int month, int day) |
4403 | 1446 | { | 1398 | { |
4418 | 1447 | int first_day_of_week = DateTime::getDayOfWeek(year, month, 1); | 1399 | int const wday = time::calc_wday( 1, month - 1, year ); |
4419 | 1448 | return ((day + first_day_of_week - 2) / 7) + (first_day_of_week < 5 ? 1 : 0); | 1400 | return ((day + wday - 2) / 7) + (wday < 5 ? 1 : 0); |
4406 | 1449 | } | ||
4407 | 1450 | |||
4408 | 1451 | |||
4409 | 1452 | bool DateTime::isLeapYear() const | ||
4410 | 1453 | { | ||
4411 | 1454 | return isLeapYear(data[YEAR_DATA]); | ||
4412 | 1455 | } | ||
4413 | 1456 | |||
4414 | 1457 | |||
4415 | 1458 | int DateTime::getDayOfWeek() const | ||
4416 | 1459 | { | ||
4417 | 1460 | return getDayOfWeek(data[YEAR_DATA], data[MONTH_DATA], data[DAY_DATA]); | ||
4420 | 1461 | } | 1401 | } |
4421 | 1462 | 1402 | ||
4422 | 1463 | 1403 | ||
4423 | @@ -1467,12 +1407,6 @@ | |||
4424 | 1467 | } | 1407 | } |
4425 | 1468 | 1408 | ||
4426 | 1469 | 1409 | ||
4427 | 1470 | int DateTime::getWeekInYear() const | ||
4428 | 1471 | { | ||
4429 | 1472 | return getWeekInYear(data[YEAR_DATA], data[MONTH_DATA], data[DAY_DATA]); | ||
4430 | 1473 | } | ||
4431 | 1474 | |||
4432 | 1475 | |||
4433 | 1476 | int DateTime::getWeekInMonth() const | 1410 | int DateTime::getWeekInMonth() const |
4434 | 1477 | { | 1411 | { |
4435 | 1478 | return getWeekInMonth(data[YEAR_DATA], data[MONTH_DATA], data[DAY_DATA]); | 1412 | return getWeekInMonth(data[YEAR_DATA], data[MONTH_DATA], data[DAY_DATA]); |
4436 | 1479 | 1413 | ||
4437 | === modified file 'src/zorbautils/locale.cpp' | |||
4438 | --- src/zorbautils/locale.cpp 2013-03-18 05:13:50 +0000 | |||
4439 | +++ src/zorbautils/locale.cpp 2013-03-21 16:00:34 +0000 | |||
4440 | @@ -169,6 +169,8 @@ | |||
4441 | 169 | LPCWSTR wlocale_name; | 169 | LPCWSTR wlocale_name; |
4442 | 170 | unique_ptr<WCHAR[]> wlocale_name_ptr; | 170 | unique_ptr<WCHAR[]> wlocale_name_ptr; |
4443 | 171 | 171 | ||
4444 | 172 | if ( !country ) | ||
4445 | 173 | country = iso3166_1::get_default( lang ); | ||
4446 | 172 | if ( lang && country ) { | 174 | if ( lang && country ) { |
4447 | 173 | wlocale_name_ptr = get_wlocale_name( lang, country ); | 175 | wlocale_name_ptr = get_wlocale_name( lang, country ); |
4448 | 174 | wlocale_name = wlocale_name_ptr.get(); | 176 | wlocale_name = wlocale_name_ptr.get(); |
4449 | @@ -278,6 +280,8 @@ | |||
4450 | 278 | static zstring get_locale_info( nl_item item, iso639_1::type lang, | 280 | static zstring get_locale_info( nl_item item, iso639_1::type lang, |
4451 | 279 | iso3166_1::type country ) { | 281 | iso3166_1::type country ) { |
4452 | 280 | if ( lang ) { | 282 | if ( lang ) { |
4453 | 283 | if ( !country ) | ||
4454 | 284 | country = iso3166_1::get_default( lang ); | ||
4455 | 281 | if ( locale_t const loc = get_unix_locale_t( lang, country ) ) { | 285 | if ( locale_t const loc = get_unix_locale_t( lang, country ) ) { |
4456 | 282 | char const *const info = nl_langinfo_l( item, loc ); | 286 | char const *const info = nl_langinfo_l( item, loc ); |
4457 | 283 | ::freelocale( loc ); | 287 | ::freelocale( loc ); |
4458 | @@ -549,6 +553,205 @@ | |||
4459 | 549 | return FIND( country ); | 553 | return FIND( country ); |
4460 | 550 | } | 554 | } |
4461 | 551 | 555 | ||
4462 | 556 | type get_default( iso639_1::type lang ) { | ||
4463 | 557 | // | ||
4464 | 558 | // In cases where a language maps to multiple countries, if the language is | ||
4465 | 559 | // the official language of a single country, that country is the one the | ||
4466 | 560 | // language is mapped to. | ||
4467 | 561 | // | ||
4468 | 562 | static type const lang_to_country[] = { | ||
4469 | 563 | unknown, | ||
4470 | 564 | DJ , // aa: Afar => Djibouti | ||
4471 | 565 | GE , // ab: Abkhazian => Georgia | ||
4472 | 566 | IR , // ae: Avestan => Iran | ||
4473 | 567 | ZA , // af: Afrikaans => South Africa | ||
4474 | 568 | GH , // ak: Akan => Ghana | ||
4475 | 569 | ET , // am: Amharic => Ethiopia | ||
4476 | 570 | ES , // an: Aragonese => Spain | ||
4477 | 571 | unknown, // ar: Arabic => (maps to multiple countries) | ||
4478 | 572 | IN_ , // as: Assamese => India | ||
4479 | 573 | AZ , // av: Avaric => Azerbaijan | ||
4480 | 574 | BO , // ay: Aymara => Bolivia | ||
4481 | 575 | AZ , // az: Azerbaijani => Azerbaijan | ||
4482 | 576 | RU , // ba: Bashkir => Russian Federation | ||
4483 | 577 | RU , // be: Byelorussian => Russian Federation | ||
4484 | 578 | BG , // bg: Bulgarian => Bulgaria | ||
4485 | 579 | IN_ , // bh: Bihari => India | ||
4486 | 580 | VU , // bi: Bislama => Vanuatu | ||
4487 | 581 | ML , // bm: Bambara => Mali | ||
4488 | 582 | BD , // bn: Bengali; Bangla => Bangladesh | ||
4489 | 583 | CN , // bo: Tibetan => China | ||
4490 | 584 | FR , // br: Breton => France | ||
4491 | 585 | BA , // bs: Bosnian => Bosnia | ||
4492 | 586 | AD , // ca: Catalan => Andorra | ||
4493 | 587 | RU , // ce: Chechen => Russian Federation | ||
4494 | 588 | MP , // ch: Chamorro => Northern Mariana Islands | ||
4495 | 589 | FR , // co: Corsican => France | ||
4496 | 590 | US , // cr: Cree => United States | ||
4497 | 591 | CZ , // cs: Czech => Czech Republic | ||
4498 | 592 | RU , // cu: Church Slavic; Church Slavonic => Russian Federation | ||
4499 | 593 | RU , // cv: Chuvash => Russian Federation | ||
4500 | 594 | GB , // cy: Welsh => United Kingdom | ||
4501 | 595 | DK , // da: Danish => Denmark | ||
4502 | 596 | DE , // de: German => Germany | ||
4503 | 597 | MV , // dv: Divehi => Maldives | ||
4504 | 598 | PK , // dz: Bhutani => Pakistan | ||
4505 | 599 | unknown, // ee: Ewe => (maps to multiple countries) | ||
4506 | 600 | GR , // el: Greek => Greece | ||
4507 | 601 | GB , // en: English => United Kingdom | ||
4508 | 602 | unknown, // eo: Esperanto => (constructed language) | ||
4509 | 603 | ES , // es: Spanish => Spain | ||
4510 | 604 | EE , // et: Estonian => Estonia | ||
4511 | 605 | ES , // eu: Basque => Spain | ||
4512 | 606 | IR , // fa: Persian => Iran | ||
4513 | 607 | unknown, // ff: Fulah => (maps to multiple countries) | ||
4514 | 608 | FI , // fi: Finnish => Finland | ||
4515 | 609 | FJ , // fj: Fiji => Fiji | ||
4516 | 610 | FO , // fo: Faroese => Faroe Islands | ||
4517 | 611 | FR , // fr: French => France | ||
4518 | 612 | NL , // fy: Frisian => Netherlands | ||
4519 | 613 | IE , // ga: Irish => Ireland | ||
4520 | 614 | GB , // gd: Scots Gaelic => United Kingdom | ||
4521 | 615 | ES , // gl: Galician => Spain | ||
4522 | 616 | PY , // gn: Guarani => Paraguay | ||
4523 | 617 | IN_ , // gu: Gujarati => India | ||
4524 | 618 | IM , // gv: Manx => Isle of Man | ||
4525 | 619 | unknown, // ha: Hausa => (maps to multiple languages) | ||
4526 | 620 | IL , // he: Hebrew => Israel | ||
4527 | 621 | IN_ , // hi: Hindi => India | ||
4528 | 622 | PG , // ho: Hiri Motu => Papua New Guinea | ||
4529 | 623 | HR , // hr: Croatian => Croatia | ||
4530 | 624 | HT , // ht: Haitian Creole => Haiti | ||
4531 | 625 | HU , // hu: Hungarian => Hungary | ||
4532 | 626 | AM , // hy: Armenian => Armenia | ||
4533 | 627 | unknown, // hz: Herero => (maps to multiple countries) | ||
4534 | 628 | unknown, // ia: Interlingua => (constructed language) | ||
4535 | 629 | ID , // id: Indonesian => Indonesia | ||
4536 | 630 | unknown, // ie: Interlingue => (constructed language) | ||
4537 | 631 | NG , // ig: Igbo => Nigeria | ||
4538 | 632 | CN , // ii: Nuosu => China | ||
4539 | 633 | US , // ik: Inupiak => United States | ||
4540 | 634 | unknown, // io: Ido => (constructed language) | ||
4541 | 635 | IS , // is: Icelandic => Island | ||
4542 | 636 | IT , // it: Italian => Italy | ||
4543 | 637 | CA , // iu: Inuktitut => Canada | ||
4544 | 638 | JP , // ja: Japanese => Japan | ||
4545 | 639 | ID , // jv: Javanese => Indonesia | ||
4546 | 640 | GE , // ka: Georgian => Georgia | ||
4547 | 641 | unknown, // kg: Kongo => (maps to multiple countries) | ||
4548 | 642 | KE , // ki: Gikuyu => Kenya | ||
4549 | 643 | unknown, // kj: Kuanyama => (maps to multiple countries) | ||
4550 | 644 | KZ , // kk: Kazakh => Kazakhstan | ||
4551 | 645 | GL , // kl: Greenlandic => Greenland | ||
4552 | 646 | KH , // km: Cambodian => Cambodia | ||
4553 | 647 | IN_ , // kn: Kannada => India | ||
4554 | 648 | KR , // ko: Korean => Korea | ||
4555 | 649 | unknown, // kr: Kanuri => (maps to multiple countries) | ||
4556 | 650 | IN_ , // ks: Kashmiri => India | ||
4557 | 651 | IQ , // ku: Kurdish => Iraq | ||
4558 | 652 | RU , // kv: Komi => Russian Federation | ||
4559 | 653 | GB , // kw: Cornish => United Kingdom | ||
4560 | 654 | KG , // ky: Kirghiz => Kyrgyzstan | ||
4561 | 655 | unknown, // la: Latin => (maps to multiple countries) | ||
4562 | 656 | LU , // lb: Letzeburgesch => Luxembourg | ||
4563 | 657 | UG , // lg: Ganda => Uganda | ||
4564 | 658 | NL , // li: Limburgan; Limburger; Limburgish => Netherands | ||
4565 | 659 | unknown, // ln: Lingala => (maps to multiple countries) | ||
4566 | 660 | LA , // lo: Laotian => Lao | ||
4567 | 661 | LT , // lt: Lithuanian => Lithuania | ||
4568 | 662 | CD , // lu: Luba-Katanga => Democratic Republic of the Congo | ||
4569 | 663 | LV , // lv: Latvian => Latvia | ||
4570 | 664 | MG , // mg: Malagasy => Madagascar | ||
4571 | 665 | MH , // mh: Marshallese => Marshall Islands | ||
4572 | 666 | NZ , // mi: Maori => New Zealand | ||
4573 | 667 | MK , // mk: Macedonian => Macedonia | ||
4574 | 668 | IN_ , // ml: Malayalam => India | ||
4575 | 669 | MN , // mn: Mongolian => Mongolia | ||
4576 | 670 | MD , // mo: Moldavian => Moldova | ||
4577 | 671 | IN_ , // mr: Marathi => India | ||
4578 | 672 | MY , // ms: Malay => Malaysia | ||
4579 | 673 | MT , // mt: Maltese => Malta | ||
4580 | 674 | MM , // my: Burmese => Myanmar (Burma) | ||
4581 | 675 | NR , // na: Nauru => Nauru | ||
4582 | 676 | NO , // nb: Norwegian Bokmal => Norway | ||
4583 | 677 | ZW , // nd: Ndebele, North => Zimbabwe | ||
4584 | 678 | NP , // ne: Nepali => Nepal | ||
4585 | 679 | NA , // ng: Ndonga => Namibia | ||
4586 | 680 | NL , // nl: Dutch => Netherlands | ||
4587 | 681 | NO , // nn: Norwegian Nynorsk => Norway | ||
4588 | 682 | NO , // no: Norwegian => Norway | ||
4589 | 683 | ZA , // nr: Ndebele, South => South Africa | ||
4590 | 684 | US , // nv: Navajo; Navaho => United States | ||
4591 | 685 | MW , // ny: Chichewa; Chewa; Nyanja => Malawi | ||
4592 | 686 | unknown, // oc: Occitan => (maps to multiple countries) | ||
4593 | 687 | CA , // oj: Ojibwa => Canada | ||
4594 | 688 | unknown, // om: Oromo => (maps to multiple countries) | ||
4595 | 689 | IN_ , // or: Oriya => India | ||
4596 | 690 | unknown, // os: Ossetian; Ossetic => (maps to multiple countries) | ||
4597 | 691 | PK , // pa: Panjabi; Punjabi => Pakistan | ||
4598 | 692 | unknown, // pi: Pali => (maps to multiple countries) | ||
4599 | 693 | PL , // pl: Polish => Poland | ||
4600 | 694 | AF , // ps: Pashto, Pushto => Afghanistan | ||
4601 | 695 | PT , // pt: Portuguese => Portugal | ||
4602 | 696 | unknown, // qu: Quechua => (maps to multiple countries) | ||
4603 | 697 | CH , // rm: Romansh => Switzerland | ||
4604 | 698 | BI , // rn: Kirundi => Burundi | ||
4605 | 699 | RO , // ro: Romanian => Romania | ||
4606 | 700 | RU , // ru: Russian => Russian Federation | ||
4607 | 701 | RW , // rw: Kinyarwanda => Rwanda | ||
4608 | 702 | IN_ , // sa: Sanskrit => India | ||
4609 | 703 | IT , // sc: Sardinian => Italy | ||
4610 | 704 | PK , // sd: Sindhi => Pakistan | ||
4611 | 705 | NO , // se: Northern Sami => Norway | ||
4612 | 706 | CF , // sg: Sangho => Central African Republic | ||
4613 | 707 | RS , // sh: Serbo-Croatian => Serbia | ||
4614 | 708 | LK , // si: Sinhalese => Sri Lanka | ||
4615 | 709 | SK , // sk: Slovak => Slovakia | ||
4616 | 710 | SI , // sl: Slovenian => Slovenia | ||
4617 | 711 | AS , // sm: Samoan => American Samoa | ||
4618 | 712 | ZW , // sn: Shona => Zimbabwe | ||
4619 | 713 | SO , // so: Somali => Somalia | ||
4620 | 714 | AL , // sq: Albanian => Albania | ||
4621 | 715 | RS , // sr: Serbian => Serbia | ||
4622 | 716 | SZ , // ss: Siswati => Swaziland | ||
4623 | 717 | LS , // st: Sesotho => Lesotho | ||
4624 | 718 | SD , // su: Sundanese => Sudan | ||
4625 | 719 | SE , // sv: Swedish => Sweden | ||
4626 | 720 | KE , // sw: Swahili => Kenya | ||
4627 | 721 | IN_ , // ta: Tamil => India | ||
4628 | 722 | IN_ , // te: Telugu => India | ||
4629 | 723 | TJ , // tg: Tajik => Tajikistan | ||
4630 | 724 | TH , // th: Thai => Thailand | ||
4631 | 725 | ER , // ti: Tigrinya => Eritrea | ||
4632 | 726 | TM , // tk: Turkmen => Turkmenistan | ||
4633 | 727 | PH , // tl: Tagalog => Philippines | ||
4634 | 728 | ZA , // tn: Setswana => South Africa | ||
4635 | 729 | TO , // to: Tonga => Tonga | ||
4636 | 730 | TR , // tr: Turkish => Turkey | ||
4637 | 731 | ZA , // ts: Tsonga => South Africa | ||
4638 | 732 | RU , // tt: Tatar => Russian Federation | ||
4639 | 733 | GH , // tw: Twi => Ghana | ||
4640 | 734 | PF , // ty: Tahitian => French Polynesia | ||
4641 | 735 | CN , // ug: Uighur => China | ||
4642 | 736 | UA , // uk: Ukrainian => Ukrain | ||
4643 | 737 | PK , // ur: Urdu => Pakistan | ||
4644 | 738 | UZ , // uz: Uzbek => Uzbekistan | ||
4645 | 739 | ZA , // ve: Venda => South Africa | ||
4646 | 740 | VN , // vi: Vietnamese => Viet Nam | ||
4647 | 741 | DE , // vo: Volapuk => Germany | ||
4648 | 742 | BE , // wa: Walloon => Belgium | ||
4649 | 743 | SN , // wo: Wolof => Senegal | ||
4650 | 744 | ZA , // xh: Xhosa => South Africa | ||
4651 | 745 | IL , // yi: Yiddish => Israel | ||
4652 | 746 | NG , // yo: Yoruba => Nigeria | ||
4653 | 747 | CN , // za: Zhuang => China | ||
4654 | 748 | CN , // zh: Chinese => China | ||
4655 | 749 | ZA , // zu: Zulu => South Africa | ||
4656 | 750 | }; | ||
4657 | 751 | assert( lang < iso639_1::NUM_ENTRIES ); | ||
4658 | 752 | return lang_to_country[ lang ]; | ||
4659 | 753 | } | ||
4660 | 754 | |||
4661 | 552 | } // namespace iso3166_1 | 755 | } // namespace iso3166_1 |
4662 | 553 | 756 | ||
4663 | 554 | /////////////////////////////////////////////////////////////////////////////// | 757 | /////////////////////////////////////////////////////////////////////////////// |
4664 | @@ -1302,6 +1505,8 @@ | |||
4665 | 1302 | } | 1505 | } |
4666 | 1303 | 1506 | ||
4667 | 1304 | bool is_supported( iso639_1::type lang, iso3166_1::type country ) { | 1507 | bool is_supported( iso639_1::type lang, iso3166_1::type country ) { |
4668 | 1508 | if ( !country ) | ||
4669 | 1509 | country = iso3166_1::get_default( lang ); | ||
4670 | 1305 | #ifdef WIN32 | 1510 | #ifdef WIN32 |
4671 | 1306 | unique_ptr<WCHAR[]> const wlocale_name( get_wlocale_name( lang, country ) ); | 1511 | unique_ptr<WCHAR[]> const wlocale_name( get_wlocale_name( lang, country ) ); |
4672 | 1307 | return Zorba_IsValidLocaleName( wlocale_name.get() ); | 1512 | return Zorba_IsValidLocaleName( wlocale_name.get() ); |
4673 | 1308 | 1513 | ||
4674 | === modified file 'src/zorbautils/locale.h' | |||
4675 | --- src/zorbautils/locale.h 2013-03-08 04:26:02 +0000 | |||
4676 | +++ src/zorbautils/locale.h 2013-03-21 16:00:34 +0000 | |||
4677 | @@ -62,6 +62,15 @@ | |||
4678 | 62 | find( StringType const &country ) { | 62 | find( StringType const &country ) { |
4679 | 63 | return find( country.c_str() ); | 63 | return find( country.c_str() ); |
4680 | 64 | } | 64 | } |
4681 | 65 | |||
4682 | 66 | /** | ||
4683 | 67 | * Gets the "default" country that speaks the given language. | ||
4684 | 68 | * | ||
4685 | 69 | * @param lang The language to get the default country for. | ||
4686 | 70 | * @return Returns said country or \c unknown. | ||
4687 | 71 | */ | ||
4688 | 72 | type get_default( iso639_1::type lang ); | ||
4689 | 73 | |||
4690 | 65 | } // namespace iso3166_1 | 74 | } // namespace iso3166_1 |
4691 | 66 | 75 | ||
4692 | 67 | /////////////////////////////////////////////////////////////////////////// | 76 | /////////////////////////////////////////////////////////////////////////// |
4693 | 68 | 77 | ||
4694 | === modified file 'test/fots/CMakeLists.txt' | |||
4695 | --- test/fots/CMakeLists.txt 2013-03-20 22:49:58 +0000 | |||
4696 | +++ test/fots/CMakeLists.txt 2013-03-21 16:00:34 +0000 | |||
4697 | @@ -158,37 +158,8 @@ | |||
4698 | 158 | EXPECTED_FOTS_FAILURE (fn-environment-variable environment-variable-005 0) | 158 | EXPECTED_FOTS_FAILURE (fn-environment-variable environment-variable-005 0) |
4699 | 159 | EXPECTED_FOTS_FAILURE (fn-environment-variable environment-variable-006 0) | 159 | EXPECTED_FOTS_FAILURE (fn-environment-variable environment-variable-006 0) |
4700 | 160 | EXPECTED_FOTS_FAILURE (fn-environment-variable environment-variable-007 0) | 160 | EXPECTED_FOTS_FAILURE (fn-environment-variable environment-variable-007 0) |
4701 | 161 | EXPECTED_FOTS_FAILURE (fn-format-date format-date-001d 0) | ||
4702 | 162 | EXPECTED_FOTS_FAILURE (fn-format-date format-date-001g 0) | ||
4703 | 163 | EXPECTED_FOTS_FAILURE (fn-format-date format-date-005 0) | 161 | EXPECTED_FOTS_FAILURE (fn-format-date format-date-005 0) |
4704 | 164 | EXPECTED_FOTS_FAILURE (fn-format-date format-date-006 0) | 162 | EXPECTED_FOTS_FAILURE (fn-format-date format-date-006 0) |
4705 | 165 | EXPECTED_FOTS_FAILURE (fn-format-date format-date-007a 0) | ||
4706 | 166 | EXPECTED_FOTS_FAILURE (fn-format-date format-date-007b 0) | ||
4707 | 167 | EXPECTED_FOTS_FAILURE (fn-format-date format-date-007c 0) | ||
4708 | 168 | EXPECTED_FOTS_FAILURE (fn-format-date format-date-008a 0) | ||
4709 | 169 | EXPECTED_FOTS_FAILURE (fn-format-date format-date-008b 0) | ||
4710 | 170 | EXPECTED_FOTS_FAILURE (fn-format-date format-date-008c 0) | ||
4711 | 171 | EXPECTED_FOTS_FAILURE (fn-format-date format-date-009 0) | ||
4712 | 172 | EXPECTED_FOTS_FAILURE (fn-format-date format-date-010 0) | ||
4713 | 173 | EXPECTED_FOTS_FAILURE (fn-format-date format-date-014 0) | ||
4714 | 174 | EXPECTED_FOTS_FAILURE (fn-format-date format-date-015 0) | ||
4715 | 175 | EXPECTED_FOTS_FAILURE (fn-format-date format-date-016 0) | ||
4716 | 176 | EXPECTED_FOTS_FAILURE (fn-format-date format-date-017 0) | ||
4717 | 177 | EXPECTED_FOTS_FAILURE (fn-format-date format-date-018 0) | ||
4718 | 178 | EXPECTED_FOTS_FAILURE (fn-format-date format-date-019 0) | ||
4719 | 179 | EXPECTED_FOTS_FAILURE (fn-format-date format-date-020 0) | ||
4720 | 180 | EXPECTED_FOTS_FAILURE (fn-format-date format-date-021 0) | ||
4721 | 181 | EXPECTED_FOTS_FAILURE (fn-format-date format-date-022 0) | ||
4722 | 182 | EXPECTED_FOTS_FAILURE (fn-format-date format-date-023 0) | ||
4723 | 183 | EXPECTED_FOTS_FAILURE (fn-format-date format-date-024 0) | ||
4724 | 184 | EXPECTED_FOTS_FAILURE (fn-format-date format-date-025 0) | ||
4725 | 185 | EXPECTED_FOTS_FAILURE (fn-format-date format-date-026 0) | ||
4726 | 186 | EXPECTED_FOTS_FAILURE (fn-format-date format-date-027 0) | ||
4727 | 187 | EXPECTED_FOTS_FAILURE (fn-format-date format-date-en117 0) | ||
4728 | 188 | EXPECTED_FOTS_FAILURE (fn-format-date format-date-en118 0) | ||
4729 | 189 | EXPECTED_FOTS_FAILURE (fn-format-date format-date-en123 0) | ||
4730 | 190 | EXPECTED_FOTS_FAILURE (fn-format-date format-date-en124 0) | ||
4731 | 191 | EXPECTED_FOTS_FAILURE (fn-format-date format-date-en125 0) | ||
4732 | 192 | EXPECTED_FOTS_FAILURE (fn-format-date format-date-en126 0) | 163 | EXPECTED_FOTS_FAILURE (fn-format-date format-date-en126 0) |
4733 | 193 | EXPECTED_FOTS_FAILURE (fn-format-date format-date-en127 0) | 164 | EXPECTED_FOTS_FAILURE (fn-format-date format-date-en127 0) |
4734 | 194 | EXPECTED_FOTS_FAILURE (fn-format-date format-date-en128 0) | 165 | EXPECTED_FOTS_FAILURE (fn-format-date format-date-en128 0) |
4735 | @@ -198,34 +169,9 @@ | |||
4736 | 198 | EXPECTED_FOTS_FAILURE (fn-format-date format-date-en132 0) | 169 | EXPECTED_FOTS_FAILURE (fn-format-date format-date-en132 0) |
4737 | 199 | EXPECTED_FOTS_FAILURE (fn-format-date format-date-en133 0) | 170 | EXPECTED_FOTS_FAILURE (fn-format-date format-date-en133 0) |
4738 | 200 | EXPECTED_FOTS_FAILURE (fn-format-date format-date-en134 0) | 171 | EXPECTED_FOTS_FAILURE (fn-format-date format-date-en134 0) |
4739 | 201 | EXPECTED_FOTS_FAILURE (fn-format-date format-date-en141 0) | ||
4740 | 202 | EXPECTED_FOTS_FAILURE (fn-format-date format-date-en151 0) | ||
4741 | 203 | EXPECTED_FOTS_FAILURE (fn-format-dateTime format-dateTime-001d 0) | ||
4742 | 204 | EXPECTED_FOTS_FAILURE (fn-format-dateTime format-dateTime-001g 0) | ||
4743 | 205 | EXPECTED_FOTS_FAILURE (fn-format-dateTime format-dateTime-002g 0) | ||
4744 | 206 | EXPECTED_FOTS_FAILURE (fn-format-dateTime format-dateTime-002h 0) | ||
4745 | 207 | EXPECTED_FOTS_FAILURE (fn-format-dateTime format-dateTime-002i 0) | ||
4746 | 208 | EXPECTED_FOTS_FAILURE (fn-format-dateTime format-dateTime-003d 0) | ||
4747 | 209 | EXPECTED_FOTS_FAILURE (fn-format-dateTime format-dateTime-003g 0) | ||
4748 | 210 | EXPECTED_FOTS_FAILURE (fn-format-dateTime format-dateTime-003m 0) | ||
4749 | 211 | EXPECTED_FOTS_FAILURE (fn-format-dateTime format-dateTime-003n 0) | ||
4750 | 212 | EXPECTED_FOTS_FAILURE (fn-format-dateTime format-dateTime-003p 0) | ||
4751 | 213 | EXPECTED_FOTS_FAILURE (fn-format-dateTime format-dateTime-005 0) | 172 | EXPECTED_FOTS_FAILURE (fn-format-dateTime format-dateTime-005 0) |
4752 | 214 | EXPECTED_FOTS_FAILURE (fn-format-dateTime format-dateTime-006 0) | 173 | EXPECTED_FOTS_FAILURE (fn-format-dateTime format-dateTime-006 0) |
4753 | 215 | EXPECTED_FOTS_FAILURE (fn-format-dateTime format-dateTime-009 0) | ||
4754 | 216 | EXPECTED_FOTS_FAILURE (fn-format-dateTime format-dateTime-010 0) | ||
4755 | 217 | EXPECTED_FOTS_FAILURE (fn-format-dateTime format-dateTime-011 0) | 174 | EXPECTED_FOTS_FAILURE (fn-format-dateTime format-dateTime-011 0) |
4756 | 218 | EXPECTED_FOTS_FAILURE (fn-format-dateTime format-dateTime-012 0) | ||
4757 | 219 | EXPECTED_FOTS_FAILURE (fn-format-dateTime format-dateTime-013p 0) | ||
4758 | 220 | EXPECTED_FOTS_FAILURE (fn-format-dateTime format-dateTime-013s 0) | ||
4759 | 221 | EXPECTED_FOTS_FAILURE (fn-format-dateTime format-dateTime-013u 0) | ||
4760 | 222 | EXPECTED_FOTS_FAILURE (fn-format-dateTime format-dateTime-014 0) | ||
4761 | 223 | EXPECTED_FOTS_FAILURE (fn-format-dateTime format-dateTime-015 0) | ||
4762 | 224 | EXPECTED_FOTS_FAILURE (fn-format-dateTime format-dateTime-016 0) | ||
4763 | 225 | EXPECTED_FOTS_FAILURE (fn-format-dateTime format-dateTime-017 0) | ||
4764 | 226 | EXPECTED_FOTS_FAILURE (fn-format-dateTime format-dateTime-018 0) | ||
4765 | 227 | EXPECTED_FOTS_FAILURE (fn-format-dateTime format-dateTime-en141 0) | ||
4766 | 228 | EXPECTED_FOTS_FAILURE (fn-format-dateTime format-dateTime-en151 0) | ||
4767 | 229 | EXPECTED_FOTS_FAILURE (fn-format-integer format-integer-030 0) | 175 | EXPECTED_FOTS_FAILURE (fn-format-integer format-integer-030 0) |
4768 | 230 | EXPECTED_FOTS_FAILURE (fn-format-integer format-integer-031 0) | 176 | EXPECTED_FOTS_FAILURE (fn-format-integer format-integer-031 0) |
4769 | 231 | EXPECTED_FOTS_FAILURE (fn-format-integer format-integer-033 0) | 177 | EXPECTED_FOTS_FAILURE (fn-format-integer format-integer-033 0) |
4770 | @@ -265,18 +211,6 @@ | |||
4771 | 265 | EXPECTED_FOTS_FAILURE (fn-format-number numberformat86 0) | 211 | EXPECTED_FOTS_FAILURE (fn-format-number numberformat86 0) |
4772 | 266 | EXPECTED_FOTS_FAILURE (fn-format-number numberformat87 0) | 212 | EXPECTED_FOTS_FAILURE (fn-format-number numberformat87 0) |
4773 | 267 | EXPECTED_FOTS_FAILURE (fn-format-number numberformat88 0) | 213 | EXPECTED_FOTS_FAILURE (fn-format-number numberformat88 0) |
4774 | 268 | EXPECTED_FOTS_FAILURE (fn-format-time format-time-002g 0) | ||
4775 | 269 | EXPECTED_FOTS_FAILURE (fn-format-time format-time-002h 0) | ||
4776 | 270 | EXPECTED_FOTS_FAILURE (fn-format-time format-time-002i 0) | ||
4777 | 271 | EXPECTED_FOTS_FAILURE (fn-format-time format-time-013p 0) | ||
4778 | 272 | EXPECTED_FOTS_FAILURE (fn-format-time format-time-013s 0) | ||
4779 | 273 | EXPECTED_FOTS_FAILURE (fn-format-time format-time-013u 0) | ||
4780 | 274 | EXPECTED_FOTS_FAILURE (fn-format-time format-time-014 0) | ||
4781 | 275 | EXPECTED_FOTS_FAILURE (fn-format-time format-time-015 0) | ||
4782 | 276 | EXPECTED_FOTS_FAILURE (fn-format-time format-time-016 0) | ||
4783 | 277 | EXPECTED_FOTS_FAILURE (fn-format-time format-time-017 0) | ||
4784 | 278 | EXPECTED_FOTS_FAILURE (fn-format-time format-time-018 0) | ||
4785 | 279 | EXPECTED_FOTS_FAILURE (fn-format-time format-time-816err 0) | ||
4786 | 280 | EXPECTED_FOTS_FAILURE (fn-generate-id generate-id-001 0) | 214 | EXPECTED_FOTS_FAILURE (fn-generate-id generate-id-001 0) |
4787 | 281 | EXPECTED_FOTS_FAILURE (fn-generate-id generate-id-002 0) | 215 | EXPECTED_FOTS_FAILURE (fn-generate-id generate-id-002 0) |
4788 | 282 | EXPECTED_FOTS_FAILURE (fn-generate-id generate-id-003 0) | 216 | EXPECTED_FOTS_FAILURE (fn-generate-id generate-id-003 0) |
4789 | 283 | 217 | ||
4790 | === removed file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncYearMonth1.xml.res' | |||
4791 | --- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncYearMonth1.xml.res 2013-02-07 17:24:36 +0000 | |||
4792 | +++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncYearMonth1.xml.res 1970-01-01 00:00:00 +0000 | |||
4793 | @@ -1,1 +0,0 @@ | |||
4794 | 1 | true | ||
4795 | 2 | \ No newline at end of file | 0 | \ No newline at end of file |
4796 | 3 | 1 | ||
4797 | === removed file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncYearMonth2.xml.res' | |||
4798 | --- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncYearMonth2.xml.res 2013-02-07 17:24:36 +0000 | |||
4799 | +++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncYearMonth2.xml.res 1970-01-01 00:00:00 +0000 | |||
4800 | @@ -1,1 +0,0 @@ | |||
4801 | 1 | true | ||
4802 | 2 | \ No newline at end of file | 0 | \ No newline at end of file |
4803 | 3 | 1 | ||
4804 | === added file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-D.xml.res' | |||
4805 | --- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-D.xml.res 1970-01-01 00:00:00 +0000 | |||
4806 | +++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-D.xml.res 2013-03-21 16:00:34 +0000 | |||
4807 | @@ -0,0 +1,1 @@ | |||
4808 | 1 | true | ||
4809 | 0 | 2 | ||
4810 | === added file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-D01.xml.res' | |||
4811 | --- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-D01.xml.res 1970-01-01 00:00:00 +0000 | |||
4812 | +++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-D01.xml.res 2013-03-21 16:00:34 +0000 | |||
4813 | @@ -0,0 +1,1 @@ | |||
4814 | 1 | true | ||
4815 | 0 | 2 | ||
4816 | === added file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-D1o.xml.res' | |||
4817 | --- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-D1o.xml.res 1970-01-01 00:00:00 +0000 | |||
4818 | +++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-D1o.xml.res 2013-03-21 16:00:34 +0000 | |||
4819 | @@ -0,0 +1,1 @@ | |||
4820 | 1 | true | ||
4821 | 0 | 2 | ||
4822 | === added file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-DW-1.xml.res' | |||
4823 | --- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-DW-1.xml.res 1970-01-01 00:00:00 +0000 | |||
4824 | +++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-DW-1.xml.res 2013-03-21 16:00:34 +0000 | |||
4825 | @@ -0,0 +1,1 @@ | |||
4826 | 1 | true | ||
4827 | 0 | 2 | ||
4828 | === added file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-DWo-1.xml.res' | |||
4829 | --- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-DWo-1.xml.res 1970-01-01 00:00:00 +0000 | |||
4830 | +++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-DWo-1.xml.res 2013-03-21 16:00:34 +0000 | |||
4831 | @@ -0,0 +1,1 @@ | |||
4832 | 1 | true | ||
4833 | 0 | 2 | ||
4834 | === added file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-DWw.xml.res' | |||
4835 | --- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-DWw.xml.res 1970-01-01 00:00:00 +0000 | |||
4836 | +++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-DWw.xml.res 2013-03-21 16:00:34 +0000 | |||
4837 | @@ -0,0 +1,1 @@ | |||
4838 | 1 | true | ||
4839 | 0 | 2 | ||
4840 | === added file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-DWwo.xml.res' | |||
4841 | --- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-DWwo.xml.res 1970-01-01 00:00:00 +0000 | |||
4842 | +++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-DWwo.xml.res 2013-03-21 16:00:34 +0000 | |||
4843 | @@ -0,0 +1,1 @@ | |||
4844 | 1 | true | ||
4845 | 0 | 2 | ||
4846 | === added file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-Dw-2.xml.res' | |||
4847 | --- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-Dw-2.xml.res 1970-01-01 00:00:00 +0000 | |||
4848 | +++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-Dw-2.xml.res 2013-03-21 16:00:34 +0000 | |||
4849 | @@ -0,0 +1,1 @@ | |||
4850 | 1 | true | ||
4851 | 0 | 2 | ||
4852 | === added file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-Dwo-2.xml.res' | |||
4853 | --- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-Dwo-2.xml.res 1970-01-01 00:00:00 +0000 | |||
4854 | +++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-Dwo-2.xml.res 2013-03-21 16:00:34 +0000 | |||
4855 | @@ -0,0 +1,1 @@ | |||
4856 | 1 | true | ||
4857 | 0 | 2 | ||
4858 | === added file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-FN-1.xml.res' | |||
4859 | --- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-FN-1.xml.res 1970-01-01 00:00:00 +0000 | |||
4860 | +++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-FN-1.xml.res 2013-03-21 16:00:34 +0000 | |||
4861 | @@ -0,0 +1,1 @@ | |||
4862 | 1 | true | ||
4863 | 0 | 2 | ||
4864 | === added file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-FN-3.xml.res' | |||
4865 | --- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-FN-3.xml.res 1970-01-01 00:00:00 +0000 | |||
4866 | +++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-FN-3.xml.res 2013-03-21 16:00:34 +0000 | |||
4867 | @@ -0,0 +1,1 @@ | |||
4868 | 1 | true | ||
4869 | 0 | 2 | ||
4870 | === added file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-FNn-1.xml.res' | |||
4871 | --- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-FNn-1.xml.res 1970-01-01 00:00:00 +0000 | |||
4872 | +++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-FNn-1.xml.res 2013-03-21 16:00:34 +0000 | |||
4873 | @@ -0,0 +1,1 @@ | |||
4874 | 1 | true | ||
4875 | 0 | 2 | ||
4876 | === added file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-FNn-2.xml.res' | |||
4877 | --- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-FNn-2.xml.res 1970-01-01 00:00:00 +0000 | |||
4878 | +++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-FNn-2.xml.res 2013-03-21 16:00:34 +0000 | |||
4879 | @@ -0,0 +1,1 @@ | |||
4880 | 1 | true | ||
4881 | 0 | 2 | ||
4882 | === added file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-Fn-2.xml.res' | |||
4883 | --- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-Fn-2.xml.res 1970-01-01 00:00:00 +0000 | |||
4884 | +++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-Fn-2.xml.res 2013-03-21 16:00:34 +0000 | |||
4885 | @@ -0,0 +1,1 @@ | |||
4886 | 1 | true | ||
4887 | 0 | 2 | ||
4888 | === added file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-Fn-4.xml.res' | |||
4889 | --- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-Fn-4.xml.res 1970-01-01 00:00:00 +0000 | |||
4890 | +++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-Fn-4.xml.res 2013-03-21 16:00:34 +0000 | |||
4891 | @@ -0,0 +1,1 @@ | |||
4892 | 1 | true | ||
4893 | 0 | 2 | ||
4894 | === renamed file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncMonthDefault.xml.res' => 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-M.xml.res' | |||
4895 | --- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncMonthDefault.xml.res 2013-02-07 17:24:36 +0000 | |||
4896 | +++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-M.xml.res 2013-03-21 16:00:34 +0000 | |||
4897 | @@ -1,1 +1,1 @@ | |||
4898 | 1 | true | ||
4899 | 2 | \ No newline at end of file | 1 | \ No newline at end of file |
4900 | 2 | true | ||
4901 | 3 | 3 | ||
4902 | === renamed file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncMonthNumber.xml.res' => 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-M01.xml.res' | |||
4903 | --- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncMonthNumber.xml.res 2013-02-07 17:24:36 +0000 | |||
4904 | +++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-M01.xml.res 2013-03-21 16:00:34 +0000 | |||
4905 | @@ -1,1 +1,1 @@ | |||
4906 | 1 | true | ||
4907 | 2 | \ No newline at end of file | 1 | \ No newline at end of file |
4908 | 2 | true | ||
4909 | 3 | 3 | ||
4910 | === renamed file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncMonthUpperCase.xml.res' => 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-MN-1.xml.res' | |||
4911 | --- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncMonthUpperCase.xml.res 2013-02-07 17:24:36 +0000 | |||
4912 | +++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-MN-1.xml.res 2013-03-21 16:00:34 +0000 | |||
4913 | @@ -1,1 +1,1 @@ | |||
4914 | 1 | true | ||
4915 | 2 | \ No newline at end of file | 1 | \ No newline at end of file |
4916 | 2 | true | ||
4917 | 3 | 3 | ||
4918 | === renamed file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncMonthTitleCase.xml.res' => 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-MNn.xml.res' | |||
4919 | --- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncMonthTitleCase.xml.res 2013-02-07 17:24:36 +0000 | |||
4920 | +++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-MNn.xml.res 2013-03-21 16:00:34 +0000 | |||
4921 | @@ -1,1 +1,1 @@ | |||
4922 | 1 | true | ||
4923 | 2 | \ No newline at end of file | 1 | \ No newline at end of file |
4924 | 2 | true | ||
4925 | 3 | 3 | ||
4926 | === renamed file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncMonthLowerCase.xml.res' => 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-Mn-2.xml.res' | |||
4927 | --- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncMonthLowerCase.xml.res 2013-02-07 17:24:36 +0000 | |||
4928 | +++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-Mn-2.xml.res 2013-03-21 16:00:34 +0000 | |||
4929 | @@ -1,1 +1,1 @@ | |||
4930 | 1 | true | ||
4931 | 2 | \ No newline at end of file | 1 | \ No newline at end of file |
4932 | 2 | true | ||
4933 | 3 | 3 | ||
4934 | === renamed file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncYearMaxWidth.xml.res' => 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-Y-2-2.xml.res' | |||
4935 | --- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncYearMaxWidth.xml.res 2013-02-07 17:24:36 +0000 | |||
4936 | +++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-Y-2-2.xml.res 2013-03-21 16:00:34 +0000 | |||
4937 | @@ -1,1 +1,1 @@ | |||
4938 | 1 | true | ||
4939 | 2 | \ No newline at end of file | 1 | \ No newline at end of file |
4940 | 2 | true | ||
4941 | 3 | 3 | ||
4942 | === renamed file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncReflexivity.xml.res' => 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-Y-M01-D01.xml.res' | |||
4943 | --- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncReflexivity.xml.res 2013-02-07 17:24:36 +0000 | |||
4944 | +++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-Y-M01-D01.xml.res 2013-03-21 16:00:34 +0000 | |||
4945 | @@ -1,1 +1,1 @@ | |||
4946 | 1 | true | ||
4947 | 2 | \ No newline at end of file | 1 | \ No newline at end of file |
4948 | 2 | true | ||
4949 | 3 | 3 | ||
4950 | === added file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-Y-Thai-1.xml.res' | |||
4951 | --- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-Y-Thai-1.xml.res 1970-01-01 00:00:00 +0000 | |||
4952 | +++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-Y-Thai-1.xml.res 2013-03-21 16:00:34 +0000 | |||
4953 | @@ -0,0 +1,1 @@ | |||
4954 | 1 | true | ||
4955 | 0 | 2 | ||
4956 | === added file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-Y-Thai-2.xml.res' | |||
4957 | --- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-Y-Thai-2.xml.res 1970-01-01 00:00:00 +0000 | |||
4958 | +++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-Y-Thai-2.xml.res 2013-03-21 16:00:34 +0000 | |||
4959 | @@ -0,0 +1,1 @@ | |||
4960 | 1 | true | ||
4961 | 0 | 2 | ||
4962 | === renamed file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncYearDefault.xml.res' => 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-Y.xml.res' | |||
4963 | --- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncYearDefault.xml.res 2013-02-07 17:24:36 +0000 | |||
4964 | +++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-Y.xml.res 2013-03-21 16:00:34 +0000 | |||
4965 | @@ -1,1 +1,1 @@ | |||
4966 | 1 | true | ||
4967 | 2 | \ No newline at end of file | 1 | \ No newline at end of file |
4968 | 2 | true | ||
4969 | 3 | 3 | ||
4970 | === added file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-YI-1.xml.res' | |||
4971 | --- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-YI-1.xml.res 1970-01-01 00:00:00 +0000 | |||
4972 | +++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-YI-1.xml.res 2013-03-21 16:00:34 +0000 | |||
4973 | @@ -0,0 +1,1 @@ | |||
4974 | 1 | true | ||
4975 | 0 | 2 | ||
4976 | === added file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-Yi-2.xml.res' | |||
4977 | --- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-Yi-2.xml.res 1970-01-01 00:00:00 +0000 | |||
4978 | +++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-Yi-2.xml.res 2013-03-21 16:00:34 +0000 | |||
4979 | @@ -0,0 +1,1 @@ | |||
4980 | 1 | true | ||
4981 | 0 | 2 | ||
4982 | === renamed file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncYearDefaultExtraChars.xml.res' => 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-chars.xml.res' | |||
4983 | --- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncYearDefaultExtraChars.xml.res 2013-02-07 17:24:36 +0000 | |||
4984 | +++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-chars.xml.res 2013-03-21 16:00:34 +0000 | |||
4985 | @@ -1,1 +1,1 @@ | |||
4986 | 1 | true | ||
4987 | 2 | \ No newline at end of file | 1 | \ No newline at end of file |
4988 | 2 | true | ||
4989 | 3 | 3 | ||
4990 | === renamed file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncMonthNumberSpaces.xml.res' => 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-whitespace.xml.res' | |||
4991 | --- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncMonthNumberSpaces.xml.res 2013-02-07 17:24:36 +0000 | |||
4992 | +++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-whitespace.xml.res 2013-03-21 16:00:34 +0000 | |||
4993 | @@ -1,1 +1,1 @@ | |||
4994 | 1 | true | ||
4995 | 2 | \ No newline at end of file | 1 | \ No newline at end of file |
4996 | 2 | true | ||
4997 | 3 | 3 | ||
4998 | === renamed file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/FormatDateTimeFuncReflexivity.xml.res' => 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-dateTime-01.xml.res' | |||
4999 | --- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/FormatDateTimeFuncReflexivity.xml.res 2013-02-07 17:24:36 +0000 | |||
5000 | +++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-dateTime-01.xml.res 2013-03-21 16:00:34 +0000 |
Validation queue starting for merge proposal. zorbatest. lambda. nu:8080/ remotequeue/ bug-1123162- 2013-03- 20T22-17- 21.086Z/ log.html
Log at: http://