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