zorba-coders team mailing list archive
-
zorba-coders team
-
Mailing list archive
-
Message #19118
[Merge] lp:~zorba-coders/zorba/bug-1123162 into lp:zorba
Paul J. Lucas has proposed merging lp:~zorba-coders/zorba/bug-1123162 into lp:zorba.
Commit message:
Fixed many date/time formatting bugs by completely rewriting the code; added basic support for multiple calendar systems; added default countries-for-languages look-up for locales.
Requested reviews:
Paul J. Lucas (paul-lucas)
Related bugs:
Bug #1123162 in Zorba: "FOTS: formatting dates and times failures"
https://bugs.launchpad.net/zorba/+bug/1123162
For more details, see:
https://code.launchpad.net/~zorba-coders/zorba/bug-1123162/+merge/154529
Fixed many date/time formatting bugs by completely rewriting the code; added basic support for multiple calendar systems; added default countries-for-languages look-up for locales.
--
https://code.launchpad.net/~zorba-coders/zorba/bug-1123162/+merge/154529
Your team Zorba Coders is subscribed to branch lp:zorba.
=== modified file 'ChangeLog'
--- ChangeLog 2013-03-20 18:39:54 +0000
+++ ChangeLog 2013-03-20 21:54:22 +0000
@@ -14,6 +14,8 @@
* In store API, added ability to specify a stream's originating URI (file)
for streamable strings and base64Binary.
* Added millis-to-dateTime() function in datetime module.
+ * Added setCalendar(), getCalendar(), setLocale(), and getLocale() to
+ DynamicContext class in C++ API.
* fn:trace outputs "empty-sequence()" if the input is the empty-sequence.
* Allow multiple default function namespaces.
* Added xqxq:variable-value function.
@@ -33,6 +35,7 @@
* Fixed bug #1095889 (Improve error message for xml-parsing error).
* Fixed bug in index join rule (no index join if inner clause has positional var).
* Fixed bug in index join rule (copy var ids after cloning index domain expr).
+ * Fixed bug #1123162 (FOTS: formatting dates and times failures)
* Added missing wrapper expressions around some variable references.
* Fixed bug in the throwing of error XQTY0086 during node construction.
* Fixed bug #1148335 (where-clause expression was not always reset when it should be)
=== modified file 'include/zorba/dynamic_context.h'
--- include/zorba/dynamic_context.h 2013-03-08 04:26:02 +0000
+++ include/zorba/dynamic_context.h 2013-03-20 21:54:22 +0000
@@ -22,6 +22,7 @@
#include <zorba/config.h>
#include <zorba/locale.h>
+#include <zorba/time.h>
#include <zorba/api_shared_types.h>
#include <zorba/static_context_consts.h>
#include <zorba/xmldatamanager.h>
@@ -268,6 +269,20 @@
getLocale( locale::iso639_1::type *aLang,
locale::iso3166_1::type *aCountry ) const = 0;
+ /** \brief Sets the calendar.
+ *
+ * @param aCalendar The calendar to use.
+ */
+ virtual void
+ setCalendar( time::calendar::type aCalendar ) = 0;
+
+ /** \brief Gets the current calendar.
+ *
+ * @return the current calendar.
+ */
+ virtual time::calendar::type
+ getCalendar() const = 0;
+
/** \brief Add a name-value pair to this context.
* The value can be accessed in the evaluate method
* of external functions (see ContextualExternalFunction).
=== modified file 'include/zorba/locale.h'
--- include/zorba/locale.h 2013-03-08 04:26:02 +0000
+++ include/zorba/locale.h 2013-03-20 21:54:22 +0000
@@ -263,7 +263,7 @@
BZ, ///< Belize
CA, ///< Canada
CC, ///< Cocos Islands
- CD, ///< Congo
+ CD, ///< Congo, the Democratic Republic of the
CF, ///< Central African Republic
CG, ///< Congo
CH, ///< Switzerland
=== modified file 'include/zorba/pregenerated/diagnostic_list.h'
--- include/zorba/pregenerated/diagnostic_list.h 2013-03-06 10:37:33 +0000
+++ include/zorba/pregenerated/diagnostic_list.h 2013-03-20 21:54:22 +0000
@@ -192,9 +192,9 @@
extern ZORBA_DLL_PUBLIC XQueryErrorCode XTDE1310;
-extern ZORBA_DLL_PUBLIC XQueryErrorCode XTDE1340;
+extern ZORBA_DLL_PUBLIC XQueryErrorCode FOFD1340;
-extern ZORBA_DLL_PUBLIC XQueryErrorCode XTDE1350;
+extern ZORBA_DLL_PUBLIC XQueryErrorCode FOFD1350;
#if !defined(ZORBA_NO_FULL_TEXT)
extern ZORBA_DLL_PUBLIC XQueryErrorCode FTST0008;
=== added file 'include/zorba/time.h'
--- include/zorba/time.h 1970-01-01 00:00:00 +0000
+++ include/zorba/time.h 2013-03-20 21:54:22 +0000
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2006-2008 The FLWOR Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ZORBA_TIME_API_H
+#define ZORBA_TIME_API_H
+
+namespace zorba {
+namespace time {
+
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+ * XQuery 3.0 F&O: 9.8.4.3: The calendars listed below were known to be in use
+ * during the last hundred years.
+ */
+namespace calendar {
+ enum type {
+ unknown,
+ AD, ///< Anno Domini (Christian Era)
+ AH, ///< Anno Hegirae (Muhammedan Era)
+ AM, ///< Anno Mundi (Jewish Calendar)
+ AME, ///< Mauludi Era (solar years since Mohammed's birth)
+ AP, ///< Anno Persici
+ AS, ///< Aji Saka Era (Java)
+ BE, ///< Buddhist Era
+ CB, ///< Cooch Behar Era
+ CE, ///< Common Era
+ CL, ///< Chinese Lunar Era
+ CS, ///< Chula Sakarat Era
+ EE, ///< Ethiopian Era
+ FE, ///< Fasli Era
+ ISO, ///< ISO 8601 calendar
+ JE, ///< Japanese Calendar
+ KE, ///< Khalsa Era (Sikh calendar)
+ KY, ///< Kali Yuga
+ ME, ///< Malabar Era
+ MS, ///< Monarchic Solar Era
+ OS, ///< Old Style (Julian Calendar)
+ RS, ///< Rattanakosin (Bangkok) Era
+ SE, ///< Saka Era
+ SH, ///< Mohammedan Solar Era (Iran)
+ SS, ///< Saka Samvat
+ TE, ///< Tripurabda Era
+ VE, ///< Vikrama Era
+ VS ///< Vikrama Samvat Era
+ };
+
+} // namespace calendar
+
+///////////////////////////////////////////////////////////////////////////////
+
+} // namespace time
+} // namespace zorba
+#endif /* ZORBA_TIME_API_H */
+/* vim:set et sw=2 ts=2: */
=== modified file 'modules/org/expath/ns/file.xq.src/file.cpp'
--- modules/org/expath/ns/file.xq.src/file.cpp 2013-03-06 02:54:03 +0000
+++ modules/org/expath/ns/file.xq.src/file.cpp 2013-03-20 21:54:22 +0000
@@ -657,7 +657,7 @@
int
LastModifiedFunction::getGmtOffset()
{
- time_t t = time(0);
+ time_t t = ::time(0);
struct tm* data;
data = localtime(&t);
data->tm_isdst = 0;
=== modified file 'modules/w3c/pregenerated/xqt-errors.xq'
--- modules/w3c/pregenerated/xqt-errors.xq 2013-03-06 10:37:33 +0000
+++ modules/w3c/pregenerated/xqt-errors.xq 2013-03-20 21:54:22 +0000
@@ -861,17 +861,17 @@
:
: @see http://www.w3.org/2005/xqt-errors
:)
-declare variable $err:XTDE1340 as xs:QName := fn:QName($err:NS, "err:XTDE1340");
+declare variable $err:FOFD1340 as xs:QName := fn:QName($err:NS, "err:FOFD1340");
(:~
:
- : It is a non-recoverable dynamic error if a component specifier within the
- : picture refers to components that are not available in the given type of
- : \c $value.
+ : It is a non-recoverable dynamic error if a component specifier within
+ : the picture refers to components that are not available in the given
+ : type of $value.
:
: @see http://www.w3.org/2005/xqt-errors
:)
-declare variable $err:XTDE1350 as xs:QName := fn:QName($err:NS, "err:XTDE1350");
+declare variable $err:FOFD1350 as xs:QName := fn:QName($err:NS, "err:FOFD1350");
(:~
:
=== modified file 'modules/xqxq/xqxq.xq.src/xqxq.cpp'
--- modules/xqxq/xqxq.xq.src/xqxq.cpp 2013-02-22 17:09:54 +0000
+++ modules/xqxq/xqxq.xq.src/xqxq.cpp 2013-03-20 21:54:22 +0000
@@ -238,7 +238,7 @@
:
theModule(aModule)
{
- srand(time(NULL));
+ srand(::time(NULL));
}
=== modified file 'src/api/dynamiccontextimpl.cpp'
--- src/api/dynamiccontextimpl.cpp 2013-03-08 04:26:02 +0000
+++ src/api/dynamiccontextimpl.cpp 2013-03-20 21:54:22 +0000
@@ -691,6 +691,17 @@
/****************************************************************************//**
********************************************************************************/
+void DynamicContextImpl::setCalendar( time::calendar::type aCalendar ) {
+ theCtx->set_calendar( aCalendar );
+}
+
+time::calendar::type DynamicContextImpl::getCalendar() const {
+ return theCtx->get_calendar();
+}
+
+/****************************************************************************//**
+
+********************************************************************************/
bool DynamicContextImpl::addExternalFunctionParam(
const String& aName,
void* aValue)
=== modified file 'src/api/dynamiccontextimpl.h'
--- src/api/dynamiccontextimpl.h 2013-03-08 04:26:02 +0000
+++ src/api/dynamiccontextimpl.h 2013-03-20 21:54:22 +0000
@@ -151,6 +151,12 @@
getLocale( locale::iso639_1::type *aLang,
locale::iso3166_1::type *aCountry ) const;
+ virtual void
+ setCalendar( time::calendar::type aCalendar );
+
+ virtual time::calendar::type
+ getCalendar() const;
+
virtual bool
addExternalFunctionParam(const String& aName, void* aValue);
=== modified file 'src/context/dynamic_context.cpp'
--- src/context/dynamic_context.cpp 2013-03-12 17:03:31 +0000
+++ src/context/dynamic_context.cpp 2013-03-20 21:54:22 +0000
@@ -137,6 +137,7 @@
reset_current_date_time();
theLang = locale::get_host_lang();
theCountry = locale::get_host_country();
+ theCalendar = time::calendar::get_default();
}
else
{
@@ -145,6 +146,7 @@
theDefaultCollectionUri = parent->theDefaultCollectionUri;
theLang = parent->theLang;
theCountry = parent->theCountry;
+ theCalendar = parent->theCalendar;
}
}
=== modified file 'src/context/dynamic_context.h'
--- src/context/dynamic_context.h 2013-03-12 17:03:31 +0000
+++ src/context/dynamic_context.h 2013-03-20 21:54:22 +0000
@@ -18,6 +18,7 @@
#define ZORBA_DYNAMIC_CONTEXT_H
#include <zorba/external_function_parameter.h>
+#include <zorba/time.h>
#include "zorbautils/hashmap_zstring.h"
#include "zorbautils/hashmap_itemp.h"
@@ -141,6 +142,7 @@
locale::iso639_1::type theLang;
locale::iso3166_1::type theCountry;
+ time::calendar::type theCalendar;
public:
double theDocLoadingUserTime;
@@ -189,6 +191,14 @@
*country = theCountry;
}
+ void set_calendar( time::calendar::type calendar ) {
+ theCalendar = calendar;
+ }
+
+ time::calendar::type get_calendar() const {
+ return theCalendar;
+ }
+
const std::vector<VarValue>& get_variables() const { return theVarValues; }
void add_variable(ulong varid, store::Item_t& value);
=== modified file 'src/diagnostics/diagnostic_en.xml'
--- src/diagnostics/diagnostic_en.xml 2013-03-07 10:10:10 +0000
+++ src/diagnostics/diagnostic_en.xml 2013-03-20 21:54:22 +0000
@@ -1012,21 +1012,51 @@
<value>"$1": picture string does not satisfy format-number() function rules</value>
</diagnostic>
- <diagnostic code="XTDE1340">
+ <diagnostic code="FOFD1340">
<comment>
- It is a non-recoverable dynamic error if the syntax of the picture is
- incorrect.
+ It is a non-recoverable dynamic error if the syntax of the picture is
+ incorrect.
</comment>
- <value>"$1": invalid picture string for date/time</value>
+ <value>"$1": invalid picture string for date/time${: 2}</value>
+ <entry key="BadComponent_3">
+ <value>'$3': invalid component specifier</value>
+ </entry>
+ <entry key="BadWidthModifier">
+ <value>invalid width modifier</value>
+ </entry>
+ <entry key="DigitNotSameFamily_34">
+ <value>"$3": digit not from same digit family as $4</value>
+ </entry>
+ <entry key="MultipleComponent_3">
+ <value>'$3': multiple component specifiers between []</value>
+ </entry>
+ <entry key="MustBeOneMandatoryDigit">
+ <value>there must be at least one mandatory-digit-sign</value>
+ </entry>
+ <entry key="NoComponent">
+ <value>component specifier expected between []</value>
+ </entry>
+ <entry key="NoAdjacentGroupSep_3">
+ <value>"$3": grouping separator must not be adjacent to others</value>
+ </entry>
+ <entry key="NoGroupSepAtStart_3">
+ <value>"$3": grouping separator illegal at start of decimal-digit-pattern</value>
+ </entry>
+ <entry key="NoGroupSepAtEnd_3">
+ <value>"$3": grouping separator illegal at end of decimal-digit-pattern</value>
+ </entry>
+ <entry key="NoOptDigitAfterMandatory">
+ <value>"#": optional-digit-sign must precede all mandatory-digit-signs</value>
+ </entry>
</diagnostic>
- <diagnostic code="XTDE1350">
+ <diagnostic code="FOFD1350">
<comment>
- It is a non-recoverable dynamic error if a component specifier within the
- picture refers to components that are not available in the given type of
- \c $value.
+ It is a non-recoverable dynamic error if a component specifier within
+ the picture refers to components that are not available in the given
+ type of $value.
</comment>
- <value>component specifier not available</value>
+ <value>"$1": component specifier not available</value>
</diagnostic>
<!--////////// XQuery Full-Text Errors /////////////////////////////////-->
=== modified file 'src/diagnostics/pregenerated/diagnostic_list.cpp'
--- src/diagnostics/pregenerated/diagnostic_list.cpp 2013-03-06 10:37:33 +0000
+++ src/diagnostics/pregenerated/diagnostic_list.cpp 2013-03-20 21:54:22 +0000
@@ -271,10 +271,10 @@
XQueryErrorCode XTDE1310( "XTDE1310" );
-XQueryErrorCode XTDE1340( "XTDE1340" );
-
-
-XQueryErrorCode XTDE1350( "XTDE1350" );
+XQueryErrorCode FOFD1340( "FOFD1340" );
+
+
+XQueryErrorCode FOFD1350( "FOFD1350" );
#if !defined(ZORBA_NO_FULL_TEXT)
=== modified file 'src/diagnostics/pregenerated/dict_en.cpp'
--- src/diagnostics/pregenerated/dict_en.cpp 2013-03-07 10:10:10 +0000
+++ src/diagnostics/pregenerated/dict_en.cpp 2013-03-20 21:54:22 +0000
@@ -53,6 +53,8 @@
{ "FODT0002", "overflow/underflow in duration operation" },
{ "FODT0003", "\"$1\": invalid timezone value (in seconds)" },
{ "FOER0000", "unidentifier error" },
+ { "FOFD1340", "\"$1\": invalid picture string for date/time${: 2}" },
+ { "FOFD1350", "\"$1\": component specifier not available" },
{ "FOFI0001", "\"$1\": not castable to xs:language" },
{ "FOFI0002", "invalid argument in format-integer: $1" },
{ "FONS0004", "\"$1\": no namespace found for prefix" },
@@ -270,8 +272,6 @@
{ "XSST0009", "\"break loop\" statement not inside while statement" },
{ "XSST0010", "\"continue loop\" statement not inside while statement" },
{ "XTDE1310", "\"$1\": picture string does not satisfy format-number() function rules" },
- { "XTDE1340", "\"$1\": invalid picture string for date/time" },
- { "XTDE1350", "component specifier not available" },
{ "XUDY0009", "node has no parent in \"replace\" expression (without \"value of\")" },
{ "XUDY0014", "\"modify\" can not modify node not created by \"copy\"" },
{ "XUDY0015", "node is target of multiple \"rename\" expressions in same query" },
@@ -613,6 +613,16 @@
{ "~FOCA0002_BadLexicalQName_2", "\"$2\": value is not a valid lexical QName" },
{ "~FOCA0002_NoCastTo_234", "\"$2\": value of type $3 is not castable to type $4" },
{ "~FOCA0002_NoURIforPrefix_2", "no namespace URI provided for prefix in lexical QName \"$2\"" },
+ { "~FOFD1340_BadComponent_3", "'$3': invalid component specifier" },
+ { "~FOFD1340_BadWidthModifier", "invalid width modifier" },
+ { "~FOFD1340_DigitNotSameFamily_34", "\"$3\": digit not from same digit family as $4" },
+ { "~FOFD1340_MultipleComponent_3", "'$3': multiple component specifiers between []" },
+ { "~FOFD1340_MustBeOneMandatoryDigit", "there must be at least one mandatory-digit-sign" },
+ { "~FOFD1340_NoAdjacentGroupSep_3", "\"$3\": grouping separator must not be adjacent to others" },
+ { "~FOFD1340_NoComponent", "component specifier expected between []" },
+ { "~FOFD1340_NoGroupSepAtEnd_3", "\"$3\": grouping separator illegal at end of decimal-digit-pattern" },
+ { "~FOFD1340_NoGroupSepAtStart_3", "\"$3\": grouping separator illegal at start of decimal-digit-pattern" },
+ { "~FOFD1340_NoOptDigitAfterMandatory", "\"#\": optional-digit-sign must precede all mandatory-digit-signs" },
{ "~FORG0001_BadHexDigit_2", "'$2': invalid hexedecimal digit" },
{ "~FORG0001_Base64BadChar_2", "\"$2\": invalid Base64 character" },
{ "~FORG0001_Base64Multiple4", "Base64 data must be a multiple of 4 characters" },
=== modified file 'src/diagnostics/pregenerated/dict_zed_keys.h'
--- src/diagnostics/pregenerated/dict_zed_keys.h 2013-03-07 10:10:10 +0000
+++ src/diagnostics/pregenerated/dict_zed_keys.h 2013-03-20 21:54:22 +0000
@@ -63,6 +63,16 @@
#define ZED_XQDY0074_NotCastToQName "~XQDY0074_NotCastToQName"
#define ZED_XQDY0074_NoEmptyLocalname "~XQDY0074_NoEmptyLocalname"
#define ZED_XQDY0074_NameSapceConstructor "~XQDY0074_NameSapceConstructor"
+#define ZED_FOFD1340_BadComponent_3 "~FOFD1340_BadComponent_3"
+#define ZED_FOFD1340_BadWidthModifier "~FOFD1340_BadWidthModifier"
+#define ZED_FOFD1340_DigitNotSameFamily_34 "~FOFD1340_DigitNotSameFamily_34"
+#define ZED_FOFD1340_MultipleComponent_3 "~FOFD1340_MultipleComponent_3"
+#define ZED_FOFD1340_MustBeOneMandatoryDigit "~FOFD1340_MustBeOneMandatoryDigit"
+#define ZED_FOFD1340_NoComponent "~FOFD1340_NoComponent"
+#define ZED_FOFD1340_NoAdjacentGroupSep_3 "~FOFD1340_NoAdjacentGroupSep_3"
+#define ZED_FOFD1340_NoGroupSepAtStart_3 "~FOFD1340_NoGroupSepAtStart_3"
+#define ZED_FOFD1340_NoGroupSepAtEnd_3 "~FOFD1340_NoGroupSepAtEnd_3"
+#define ZED_FOFD1340_NoOptDigitAfterMandatory "~FOFD1340_NoOptDigitAfterMandatory"
#define ZED_FTST0009_BadStopWordsLang "~FTST0009_BadStopWordsLang"
#define ZED_FTST0009_BadStemmerLang "~FTST0009_BadStemmerLang"
#define ZED_FTST0009_BadThesaurusLang "~FTST0009_BadThesaurusLang"
=== modified file 'src/functions/func_durations_dates_times_impl.cpp'
--- src/functions/func_durations_dates_times_impl.cpp 2013-02-07 17:24:36 +0000
+++ src/functions/func_durations_dates_times_impl.cpp 2013-03-20 21:54:22 +0000
@@ -19,6 +19,7 @@
#include "functions/function_impl.h"
#include "runtime/durations_dates_times/DurationsDatesTimesImpl.h"
+#include "runtime/durations_dates_times/format_dateTime.h"
#include "runtime/numerics/NumericsImpl.h"
#include "runtime/core/arithmetic_impl.h"
#include "zorbamisc/ns_consts.h"
=== modified file 'src/runtime/CMakeLists.txt'
--- src/runtime/CMakeLists.txt 2013-02-07 17:24:36 +0000
+++ src/runtime/CMakeLists.txt 2013-03-20 21:54:22 +0000
@@ -125,6 +125,7 @@
core/gflwor/outerfor_iterator.cpp
core/internal_operators.cpp
durations_dates_times/DurationsDatesTimesImpl.cpp
+ durations_dates_times/format_dateTime.cpp
indexing/doc_indexer.cpp
indexing/index_ddl.cpp
json/common.cpp
=== modified file 'src/runtime/durations_dates_times/DurationsDatesTimesImpl.cpp'
--- src/runtime/durations_dates_times/DurationsDatesTimesImpl.cpp 2013-02-28 11:15:32 +0000
+++ src/runtime/durations_dates_times/DurationsDatesTimesImpl.cpp 2013-03-20 21:54:22 +0000
@@ -45,8 +45,6 @@
{
SERIALIZABLE_CLASS_VERSIONS(FnDateTimeConstructorIterator)
-SERIALIZABLE_CLASS_VERSIONS(FnFormatDateTimeIterator)
-
SERIALIZABLE_CLASS_VERSIONS(FnAdjustToTimeZoneIterator_1)
SERIALIZABLE_CLASS_VERSIONS(FnAdjustToTimeZoneIterator_2)
@@ -54,19 +52,11 @@
BINARY_ACCEPT(FnDateTimeConstructorIterator);
-NARY_ACCEPT(FnFormatDateTimeIterator);
-
UNARY_ACCEPT(FnAdjustToTimeZoneIterator_1);
BINARY_ACCEPT(FnAdjustToTimeZoneIterator_2);
-static void skip_whitespace(zstring& str, ascii::size_type& position, int delta = 0)
-{
- while (position+delta < str.size() && ascii::is_space(str[position+delta]))
- position++;
-}
-
bool FnDateTimeConstructorIterator::nextImpl(store::Item_t& result, PlanState& planState) const
{
store::Item_t item0;
@@ -199,555 +189,5 @@
STACK_END(state);
}
-
-/**
- *______________________________________________________________________
- *
- * fn:format-dateTime()
- *
- *_______________________________________________________________________*/
-
-class Modifier
-{
-public:
- zstring presentation_modifier;
- zstring second_modifier;
-
- // for min_width and max_width
- // -3 means an error in the picture
- // -2 means width modifiers are not specified
- // -1 means '*'
- // >=0 means explicitly specified width
- long min_width_modifier;
- long max_width_modifier;
-
- Modifier()
- :
- presentation_modifier(""),
- second_modifier(""),
- min_width_modifier(-2),
- max_width_modifier(-2)
- {
- };
-};
-
-
-static void format_number(zstring& str, long number, Modifier& modifier)
-{
- // Presentation modifier can be:
- // 'Ww', "Nn', 'W', 'w', 'N', 'n'
- // 'i', 'I', '1', '00...01'
- // the modifier will not be checked if it is supported or not
- zstring temp;
-
- if (modifier.presentation_modifier.size() > 0 && modifier.presentation_modifier[0] == '0')
- {
- ztd::to_string(number, &temp);
- while (temp.size() < modifier.presentation_modifier.size())
- temp = "0" + temp;
- }
- else // "1" or fallback
- {
- ztd::to_string(number, &temp);
- }
-
- if (modifier.second_modifier == "o")
- {
- if ((number % 10) == 1 && (number % 100) != 11)
- temp.append("st");
- else if ((number % 10) == 2 && (number % 100) != 12)
- temp.append("nd");
- else if ((number % 10) == 3 && (number % 100) != 13)
- temp.append("rd");
- else
- temp.append("th");
- }
-
- if (modifier.min_width_modifier >= 0)
- while (temp.size() < (unsigned int)modifier.min_width_modifier)
- temp = "0" + temp;
-
- str.append(temp.c_str());
-}
-
-
-static void format_string_width(
- zstring& destination,
- zstring& source,
- Modifier& modifier)
-{
- zstring temp = source;
- while (modifier.max_width_modifier > 0 && temp.size() < (unsigned int)modifier.max_width_modifier)
- temp.append(" ");
- destination.append(temp.c_str());
-}
-
-
-static bool format_string(
- zstring& destination,
- zstring& source,
- Modifier& modifier)
-{
- zstring temp;
- if (modifier.presentation_modifier == "n")
- {
- zstring newcase = source;
- ascii::to_lower(newcase);
- temp.append(newcase);
- }
- else if (modifier.presentation_modifier == "N")
- {
- zstring newcase = source;
- ascii::to_upper(newcase);
- temp.append(newcase);
- }
- else if (modifier.presentation_modifier == "Nn")
- {
- zstring newcase;
-
- newcase = source.substr(0, 1);
- ascii::to_upper(newcase);
- temp.append(newcase);
-
- newcase = source.substr(1,source.size()-1);
- ascii::to_lower(newcase);
- temp.append(newcase);
- }
- else
- return false;
-
- format_string_width(destination, temp, modifier);
- return true;
-}
-
-
-static bool format_string(
- zstring& destination,
- const char* source,
- Modifier& modifier)
-{
- zstring temp(source);
- return format_string(destination, temp, modifier);
-}
-
-
-static void format_component(
- zstring& destination,
- long number,
- zstring& source,
- Modifier& modifier)
-{
- if (!format_string(destination, source, modifier))
- format_number(destination, number, modifier);
-}
-
-
-static void output_year(
- zstring& destination,
- long number,
- Modifier& modifier)
-{
- format_number(destination, number, modifier);
-
- if (modifier.max_width_modifier >= 0)
- {
- if ((unsigned int)modifier.max_width_modifier > destination.size())
- modifier.max_width_modifier = destination.size();
-
- destination = destination.substr(destination.size() - modifier.max_width_modifier, modifier.max_width_modifier);
- }
-}
-
-
-static void output_month(
- zstring& destination,
- long number,
- Modifier& modifier)
-{
- static const char* month[12] = { "january", "february", "march", "april", "may", "june", "july", "august", "september", "october", "november", "december"};
- zstring temp(month[number-1]);
- if (modifier.max_width_modifier > 0 && (unsigned int)modifier.max_width_modifier < temp.size())
- temp = temp.substr(0, modifier.max_width_modifier);
-
- format_component(destination, number, temp, modifier);
-}
-
-
-static void output_day_of_week(
- zstring& destination,
- long number,
- Modifier& modifier)
-{
- static const char* day[7] = { "sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday"};
- zstring temp(day[number]);
- if (modifier.max_width_modifier > 0 && (unsigned int)modifier.max_width_modifier < temp.size())
- temp = temp.substr(0, modifier.max_width_modifier);
-
- if (modifier.presentation_modifier.size() == 0)
- modifier.presentation_modifier = "n"; // Default for day of week is "n"
-
- format_component(destination, number, temp, modifier);
-}
-
-
-static void parse_presentation_modifier(
- zstring& str,
- ascii::size_type& position,
- zstring& result)
-{
- result = "";
-
- skip_whitespace(str, position, 1);
-
- if (position+1 >= str.size())
- return;
-
- zstring modifier = "";
-
- if (str[position+1] == '1' || str[position+1] == 'i' || str[position+1] == 'I'
- || str[position+1] == 'a' || str[position+1] == 'A'
- || str[position+1] == 'w' || str[position+1] == 'W'
- || str[position+1] == 'n' || str[position+1] == 'N' )
- {
- modifier.append(str, position+1, 1);
- position++;
-
- skip_whitespace(str, position, 1);
-
- if (position+1 < str.size() &&
- ((modifier[0] == 'W' && str[position+1] == 'w')
- ||
- (modifier[0] == 'N' && str[position+1] == 'n')))
- {
- modifier.append(str, position+1, 1);
- position++;
- }
- }
- else if (str[position+1] == '0')
- {
- ascii::size_type start = position;
- while (position+1 < str.size() && (str[position+1] == '0' || ascii::is_space(str[position+1])))
- {
- if (str[position+1] == '0')
- modifier.append(str, position+1, 1);
- position++;
- }
-
- if (position+1 >= str.size() || str[position+1] != '1')
- {
- position = start;
- return;
- }
-
- modifier.append(str, position+1, 1);
- position++;
- }
-
- result = modifier;
-}
-
-
-static void parse_second_modifier(
- zstring& str,
- ascii::size_type& position,
- zstring& result)
-{
- result = "";
-
- skip_whitespace(str, position, 1);
-
- if (position+1 >= str.size())
- return;
-
- position++;
- if (str[position] == 't')
- result = "t";
- else if (str[position] == 'o')
- result = "o";
- else
- position--;
-}
-
-
-// for min_width and max_width
-// -3 means an error in the picture
-// -2 means width modifiers are not specified
-// -1 means '*'
-// >=0 means explicitly specified width
-static void parse_width_modifier(
- zstring& str,
- ascii::size_type& position,
- long& min_width,
- long& max_width)
-{
- min_width = -2;
- max_width = -2;
-
- skip_whitespace(str, position, 1);
-
- if (position+1 >= str.size() || str[position+1] != ',')
- return;
-
- position++;
- skip_whitespace(str, position, 1);
-
- // The min_width must be present if there is a comma symbol
- min_width = -3;
- if (position+1 >= str.size())
- return;
-
- if (str[position+1] == '*')
- {
- min_width = -1;
- position++;
- }
- else
- {
- if (parse_long(str.data(), str.size(), position, min_width, -1, -1, 1))
- min_width = -3;
- }
-
- skip_whitespace(str, position, 1);
-
- if (position+1 >= str.size() || str[position+1] != '-')
- return;
-
- position++;
- skip_whitespace(str, position, 1);
-
- if (position+1 < str.size() && str[position+1] == '*')
- {
- max_width = -1;
- position++;
- }
- else
- {
- if (parse_long(str.data(), str.size(), position, max_width, -1, -1, 1))
- min_width = -3;
- }
-}
-
-
-static int get_data_type(char component)
-{
- switch (component)
- {
- case 'Y':
- return DateTime::YEAR_DATA;
- case 'M':
- return DateTime::MONTH_DATA;
- case 'D':
- return DateTime::DAY_DATA;
- case 'd': // day in year
- return DateTime::DAY_DATA;
- case 'F': // day of week
- return DateTime::DAY_DATA;
- case 'W': // week in year
- return DateTime::DAY_DATA;
- case 'w': // week in month
- return DateTime::DAY_DATA;
- case 'H': // hour in day (24 hours)
- return DateTime::HOUR_DATA;
- case 'h': // hour in half-day (12 hours)
- return DateTime::HOUR_DATA;
- case 'P': // am/pm marker
- return DateTime::HOUR_DATA;
- case 'm':
- return DateTime::MINUTE_DATA;
- case 's':
- return DateTime::SECONDS_DATA;
- case 'f': // fractional seconds
- return DateTime::FRACSECONDS_DATA;
- 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)
- return -1;
- case 'z': // timezone as a time offset using GMT, for example GMT+1
- return -1;
- case 'C': // calendar: the name or abbreviation of a calendar name
- return -1;
- case 'E': // era: the name of a baseline for the numbering of years, for example the reign of a monarch
- return -1;
- default:
- return -1;
- }
-}
-
-
-bool FnFormatDateTimeIterator::nextImpl(
- store::Item_t& result,
- PlanState& planState) const
-{
- bool variable_marker;
- zstring pictureString, resultString;
- store::Item_t dateTimeItem, picture;
- PlanIteratorState* state;
- DEFAULT_STACK_INIT(PlanIteratorState, state, planState);
-
- if (!consumeNext(dateTimeItem, theChildren[0].getp(), planState))
- {
- // Got void -- returning void
- STACK_PUSH(false, state);
- }
- else
- {
- consumeNext(picture, theChildren[1].getp(), planState);
-
- pictureString = picture->getStringValue().str();
- resultString = "";
- variable_marker = false;
-
- for (ascii::size_type i = 0; i < pictureString.size(); i++)
- {
- if (!variable_marker)
- {
- if (pictureString[i] == '[')
- {
- // check for quoted "[["
- if (i<pictureString.size()-1 && pictureString[i+1] == '[')
- i++;
- else
- {
- variable_marker = true;
- continue;
- }
- }
- else if (pictureString[i] == ']')
- {
- // check for quoted "]]"
- if (i<pictureString.size()-1 && pictureString[i+1] == ']')
- i++;
- }
-
- resultString.append(pictureString, i, 1);
- }
- else // variable_marker == true
- {
- char component = 0;
- Modifier modifier;
-
- switch (pictureString[i])
- {
- case 'Y': case 'M': case 'D': case 'd': case 'F': case 'W': case 'w':
- case 'H': case 'h': case 'P': case 'm': case 's': case 'f':
- case 'Z': case 'z': case 'C': case 'E':
- component = pictureString[i];
- break;
-
- case ' ': case '\f': case '\n': case '\r': case '\t': case '\v':
- continue; // ignore whitespace
- break;
-
- case ']':
- variable_marker = false;
- break;
-
- default:
- throw XQUERY_EXCEPTION(
- err::XTDE1340, ERROR_PARAMS( pictureString ), ERROR_LOC( loc )
- );
- }
-
- if (variable_marker == false)
- continue;
-
- parse_presentation_modifier(pictureString, i, modifier.presentation_modifier);
-
- parse_second_modifier(pictureString, i, modifier.second_modifier);
-
- parse_width_modifier(pictureString,
- i,
- modifier.min_width_modifier,
- modifier.max_width_modifier);
-
- // min_width_modifier is -3, there was an error in the picture
- if (modifier.min_width_modifier == -3)
- throw XQUERY_EXCEPTION(
- err::XTDE1340, ERROR_PARAMS( pictureString ), ERROR_LOC( loc )
- );
-
- int data_type = get_data_type(component);
- if (data_type != -1 && (!DateTime::FACET_MEMBERS[facet_type][data_type]))
- throw XQUERY_EXCEPTION(err::XTDE1350, ERROR_LOC(loc));
-
- switch (component)
- {
- case 'Y':
- output_year(resultString, std::abs(dateTimeItem->getDateTimeValue().getYear()), modifier);
- break;
- case 'M':
- output_month(resultString, dateTimeItem->getDateTimeValue().getMonth(), modifier);
- break;
- case 'D':
- format_number(resultString, dateTimeItem->getDateTimeValue().getDay(), modifier);
- break;
- case 'd': // day in year
- format_number(resultString, dateTimeItem->getDateTimeValue().getDayOfYear(), modifier);
- break;
- case 'F': // day of week
- output_day_of_week(resultString, dateTimeItem->getDateTimeValue().getDayOfWeek(), modifier);
- break;
- case 'W': // week in year
- format_number(resultString, dateTimeItem->getDateTimeValue().getWeekInYear(), modifier);
- break;
- case 'w': // week in month
- format_number(resultString, dateTimeItem->getDateTimeValue().getWeekInMonth(), modifier);
- break;
- case 'H': // hour in day (24 hours)
- format_number(resultString, dateTimeItem->getDateTimeValue().getHours(), modifier);
- break;
- case 'h': // hour in half-day (12 hours)
- // Convert hour from: 0 1 ... 12 13 ... 23 0
- // to: 12 1 ... 12 1 ... 11 12
- format_number(resultString, 1 + (11 + dateTimeItem->getDateTimeValue().getHours()) % 12,
- modifier);
- break;
- case 'P': // am/pm marker
- if (modifier.presentation_modifier.empty())
- modifier.presentation_modifier = "n"; // Default for the AM/PM marker is "n"
- format_string(resultString, dateTimeItem->getDateTimeValue().getHours() >= 12 ? "pm" : "am", modifier);
- break;
- case 'm':
- if (modifier.presentation_modifier.empty())
- modifier.presentation_modifier.append("01");
- format_number(resultString, dateTimeItem->getDateTimeValue().getMinutes(), modifier);
- break;
- case 's':
- if (modifier.presentation_modifier.empty())
- modifier.presentation_modifier.append("01");
- format_number(resultString, dateTimeItem->getDateTimeValue().getIntSeconds(), modifier);
- break;
- case 'f': // fractional seconds
- format_number(resultString, (long)(dateTimeItem->getDateTimeValue().getFractionalSeconds()*1000.0/DateTime::FRAC_SECONDS_UPPER_LIMIT),
- modifier);
- break;
- 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)
- // deliberate fall-through
- case 'z': // timezone as a time offset using GMT, for example GMT+1
- {
- zstring temp = "gmt";
- temp += dateTimeItem->getDateTimeValue().getTimezone().toString();
- format_string(resultString, temp.c_str(), modifier);
- }
- break;
- case 'C': // calendar: the name or abbreviation of a calendar name
- if (modifier.presentation_modifier.empty())
- modifier.presentation_modifier.append("n");
- format_string(resultString, "gregorian", modifier);
- break;
- case 'E': // era: the name of a baseline for the numbering of years, for example the reign of a monarch
- if (modifier.presentation_modifier.empty())
- modifier.presentation_modifier.append("n");
- format_string(resultString, dateTimeItem->getDateTimeValue().getYear() < 0 ? "ad" : "bc", modifier);
- break;
- } // switch
- } // if (!variable_marker)
-
- } // for
-
- STACK_PUSH(GENV_ITEMFACTORY->createString(result, resultString), state);
- }
-
- STACK_END (state);
-}
-
} // namespace zorba
/* vim:set et sw=2 ts=2: */
=== modified file 'src/runtime/durations_dates_times/DurationsDatesTimesImpl.h'
--- src/runtime/durations_dates_times/DurationsDatesTimesImpl.h 2013-02-07 17:24:36 +0000
+++ src/runtime/durations_dates_times/DurationsDatesTimesImpl.h 2013-03-20 21:54:22 +0000
@@ -24,53 +24,12 @@
#include "runtime/base/unarybase.h"
#include "runtime/base/narybase.h"
+namespace zorba {
-namespace zorba
-{
+///////////////////////////////////////////////////////////////////////////////
BINARY_ITER(FnDateTimeConstructorIterator);
-
-// XQuery 3.0 DateTime formatting
-class FnFormatDateTimeIterator : public NaryBaseIterator<FnFormatDateTimeIterator,
- PlanIteratorState >
-{
-private:
- DateTime::FACET_TYPE facet_type;
-
-public:
- SERIALIZABLE_CLASS(FnFormatDateTimeIterator);
-
- SERIALIZABLE_CLASS_CONSTRUCTOR2T(
- FnFormatDateTimeIterator,
- NaryBaseIterator<FnFormatDateTimeIterator, PlanIteratorState >);
-
- void serialize(::zorba::serialization::Archiver &ar)
- {
- serialize_baseclass(ar,
- (NaryBaseIterator<FnFormatDateTimeIterator, PlanIteratorState >*)this);
-
- SERIALIZE_ENUM(DateTime::FACET_TYPE, facet_type);
- }
-
-public:
- FnFormatDateTimeIterator(
- static_context* sctx,
- const QueryLoc& loc,
- std::vector<PlanIter_t>& aChildren,
- DateTime::FACET_TYPE a_facet_type = DateTime::DATETIME_FACET)
- :
- NaryBaseIterator<FnFormatDateTimeIterator, PlanIteratorState>(sctx, loc, aChildren),
- facet_type(a_facet_type)
- {
- }
-
- void accept(PlanIterVisitor& v) const;
-
- bool nextImpl(store::Item_t& result, PlanState& aPlanState) const;
-};
-
-
/*
10.7 Timezone Adjustment Functions on Dates and Time Values
*/
@@ -88,14 +47,14 @@
*/
BINARY_ITER(FnAdjustToTimeZoneIterator_2);
+///////////////////////////////////////////////////////////////////////////////
+
} // namespace zorba
-#endif
-
+#endif /* ZORBA_RUNTIME_DURATIONSDATESTIMES */
/*
* Local variables:
* mode: c++
* End:
*/
-
/* vim:set et sw=2 ts=2: */
=== added file 'src/runtime/durations_dates_times/format_dateTime.cpp'
--- src/runtime/durations_dates_times/format_dateTime.cpp 1970-01-01 00:00:00 +0000
+++ src/runtime/durations_dates_times/format_dateTime.cpp 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1377 @@
+/*
+ * Copyright 2006-2008 The FLWOR Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "stdafx.h"
+
+// standard
+#include <algorithm>
+#include <cctype>
+#include <cmath>
+#include <cstdlib>
+#include <functional>
+#include <iomanip>
+#include <iostream>
+#include <sstream>
+
+// Zorba
+#include "context/dynamic_context.h"
+#include "context/static_context.h"
+#include "runtime/core/arithmetic_impl.h"
+#include "runtime/visitors/planiter_visitor.h"
+#include "store/api/item.h"
+#include "store/api/item_factory.h"
+#include "store/api/store.h"
+#include "system/globalenv.h"
+#include "util/ascii_util.h"
+#include "util/stream_util.h"
+#include "util/string_util.h"
+#include "util/time_util.h"
+#include "util/utf8_util.h"
+#include "zorbatypes/datetime.h"
+#include "zorbatypes/datetime/parse.h"
+#include "zorbatypes/duration.h"
+#include "zorbatypes/zstring.h"
+#include "zorbautils/locale.h"
+
+// local
+#include "format_dateTime.h"
+
+using namespace std;
+using namespace zorba::locale;
+using namespace zorba::time;
+
+namespace zorba {
+
+SERIALIZABLE_CLASS_VERSIONS(FnFormatDateTimeIterator)
+NARY_ACCEPT(FnFormatDateTimeIterator);
+
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Holds presentation modifier data.
+ */
+struct modifier {
+ enum first_type {
+ arabic, // '1' : 0 1 2 ... 10 11 12 ...
+ alpha, // 'a' : a b c ... z aa ab ac ...
+ ALPHA, // 'A' : A B C ... Z AA AB AC ...
+ roman, // 'i' : i ii iii iv v vi vii viii ix x ...
+ ROMAN, // 'I' : I II III IV V VI VII VIII IX X ...
+ name, // 'n' : name
+ Name, // 'Nn': Name
+ NAME, // 'N' : NAME
+ words, // 'w' : one two three four ...
+ Words, // 'Ww': One Two Three Four ...
+ WORDS, // 'W' : ONE TWO THREE FOUR ...
+ military_tz // 'Z' : A B C ... J ... X Y Z
+ };
+
+ enum second_co_type {
+ no_second_co,
+ cardinal, // 'c': 7 or seven
+ ordinal // 'o': 7th or seventh
+ };
+
+ enum second_at_type {
+ no_second_at,
+ alphabetic, // 'a'
+ traditional // 't'
+ };
+
+ typedef unsigned width_type;
+
+ struct {
+ bool parsed;
+ first_type type;
+ zstring format;
+ bool has_grouping_separators;
+ unicode::code_point zero;
+ } first;
+
+ struct {
+ second_co_type co_type;
+ zstring co_string;
+ second_at_type at_type;
+ } second;
+
+ width_type min_width;
+ width_type max_width;
+
+ //
+ // This stuff isn't part of the "presentation modifier" as discussed in the
+ // XQuery3.0 F&O spec, but this is a convenient place to put it nonetheless.
+ //
+ iso639_1::type lang;
+ bool lang_is_fallback;
+ iso3166_1::type country;
+ calendar::type cal;
+ bool cal_is_fallback;
+
+ void append_if_fallback_lang( zstring *s ) const {
+ if ( lang_is_fallback ) {
+ //
+ // XQuery 3.0 F&O: 9.8.4.3: If the fallback representation uses a
+ // different language from that requested, the output string must
+ // identify the language actually used, for example by prefixing the
+ // string with [Language: Y] (where Y is the language actually used)
+ // localized in an implementation-dependent way.
+ //
+ ostringstream oss;
+ // TODO: localize "Language"
+ oss << "[Language: " << lang << ']';
+ *s += oss.str();
+ }
+ }
+
+ bool gt_max_width( width_type n ) const {
+ return max_width > 0 && n > max_width;
+ }
+
+ zstring const& left_pad_zero( zstring *s ) const {
+ if ( min_width )
+ utf8::left_pad( s, min_width, first.zero );
+ return *s;
+ }
+
+ zstring const& right_pad_space( zstring *s ) const {
+ if ( min_width )
+ utf8::right_pad( s, min_width, ' ' );
+ return *s;
+ }
+
+ void set_default_width( width_type width ) {
+ if ( !(first.parsed || min_width || max_width) )
+ min_width = max_width = width;
+ }
+
+ modifier() {
+ first.parsed = false;
+ first.type = arabic;
+ first.has_grouping_separators = false;
+ first.zero = '0';
+ second.co_type = cardinal;
+ second.at_type = no_second_at;
+ min_width = max_width = 0;
+ };
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+zstring alpha( unsigned n, bool capital ) {
+ zstring result;
+ if ( n ) {
+ char const c = capital ? 'A' : 'a';
+ while ( n ) {
+ unsigned const m = n - 1;
+ result.insert( (zstring::size_type)0, 1, c + m % 26 );
+ n = m / 26;
+ }
+ } else
+ result = "0";
+ return result;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+namespace english_impl {
+
+// Based on code from:
+// http://www.cprogramming.com/challenges/integer-to-english-sol.html
+
+static string const ones[][2] = {
+ { "", "" },
+ { "one", "first" },
+ { "two", "second" },
+ { "three", "third" },
+ { "four", "fourth" },
+ { "five", "fifth" },
+ { "six", "sixth" },
+ { "seven", "seventh" },
+ { "eight", "eighth" },
+ { "nine", "ninth" },
+ { "ten", "tenth" },
+ { "eleven", "eleventh" },
+ { "twelve", "twelveth" },
+ { "thirteen", "thirteenth" },
+ { "fourteen", "fourteenth" },
+ { "fifteen", "fifteenth" },
+ { "sixteen", "sixteenth" },
+ { "seventeen", "seventeenth" },
+ { "eighteen", "eighteenth" },
+ { "nineteen", "nineteenth" }
+};
+
+static zstring const tens[][2] = {
+ { "", "" },
+ { "", "" },
+ { "twenty", "twentieth" },
+ { "thirty", "thirtieth" },
+ { "forty", "fortieth" },
+ { "fifty", "fiftieth" },
+ { "sixty", "sixtieth" },
+ { "seventy", "seventieth" },
+ { "eighty", "eighteenth" },
+ { "ninety", "ninetieth" }
+};
+
+// Enough entries to print English for 64-bit integers.
+static zstring const big[][2] = {
+ { "", "" },
+ { "thousand", "thousandth" },
+ { "million", "millionth" },
+ { "billion", "billionth" },
+ { "trillion", "trillionth" },
+ { "quadrillion", "quadrillionth" },
+ { "quintillion", "quintillionth" }
+};
+
+inline zstring if_space( zstring const &s ) {
+ return s.empty() ? "" : ' ' + s;
+}
+
+static zstring hundreds( int64_t n, bool ordinal ) {
+ if ( n < 20 )
+ return ones[ n ][ ordinal ];
+ zstring const tmp( if_space( ones[ n % 10 ][ ordinal ] ) );
+ return tens[ n / 10 ][ ordinal && tmp.empty() ] + tmp;
+}
+
+} // namespace english_impl
+
+/**
+ * Converts a signed integer to English, e.g, 42 becomes "forty two".
+ *
+ * @param n The integer to convert.
+ * @param ordinal If \c true, ordinal words ("forty second") are returned.
+ * @return Returns \a n in English.
+ */
+static zstring english( int64_t n, bool ordinal = false ) {
+ using namespace english_impl;
+
+ if ( !n )
+ return ordinal ? "zeroth" : "zero";
+
+ bool const negative = n < 0;
+ if ( negative )
+ n = -n;
+
+ int big_count = 0;
+ bool big_ordinal = ordinal;
+ zstring r;
+
+ while ( n ) {
+ if ( int64_t const m = n % 1000 ) {
+ zstring s;
+ if ( m < 100 )
+ s = hundreds( m, ordinal );
+ else {
+ zstring const tmp( if_space( hundreds( m % 100, ordinal ) ) );
+ s = ones[ m / 100 ][0] + ' '
+ + (ordinal && tmp.empty() ? "hundredth" : "hundred") + tmp;
+ }
+ zstring const tmp( if_space( r ) );
+ r = s + if_space( big[ big_count ][ big_ordinal && tmp.empty() ] + tmp );
+ big_ordinal = false;
+ }
+ n /= 1000;
+ ++big_count;
+ ordinal = false;
+ }
+
+ if ( negative )
+ r = "negative " + r;
+ return r;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static bool is_grouping_separator( unicode::code_point cp ) {
+ using namespace unicode;
+ //
+ // XQuery 3.0 F&O: 4.6.1: a grouping-separator-sign is a non-alphanumeric
+ // character, that is a character whose Unicode category is other than Nd,
+ // Nl, No, Lu, Ll, Lt, Lm or Lo.
+ //
+ return !( is_category( cp, Nd )
+ || is_category( cp, Nl )
+ || is_category( cp, No )
+ || is_category( cp, Lu )
+ || is_category( cp, Ll )
+ || is_category( cp, Lt )
+ || is_category( cp, Lm )
+ || is_category( cp, Lo )
+ );
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Returns the English ordinal suffix for an integer, e.g., "st" for 1, "nd"
+ * for 2, etc.
+ *
+ * @param n The integer to return the ordinal suffix for.
+ * @return Returns said suffix.
+ */
+static char const* ordinal( int n ) {
+ n = std::abs( n );
+ switch ( n % 100 ) {
+ case 11:
+ case 12:
+ case 13:
+ break;
+ default:
+ switch ( n % 10 ) {
+ case 1: return "st";
+ case 2: return "nd";
+ case 3: return "rd";
+ }
+ }
+ return "th";
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+ * A unary_function to convert a (presumed) lower-case string to title-case
+ * "Like This."
+ */
+class to_title : public unary_function<char,char> {
+public:
+ to_title() : capitalize_( true ) { }
+
+ result_type operator()( argument_type c ) {
+ if ( ascii::is_alpha( c ) ) {
+ if ( capitalize_ ) {
+ c = ascii::to_upper( c );
+ capitalize_ = false;
+ }
+ } else if ( ascii::is_space( c ) )
+ capitalize_ = true;
+ return c;
+ };
+
+private:
+ bool capitalize_;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+static void append_number( int n, modifier const &mod, zstring *dest ) {
+ switch ( mod.first.type ) {
+ case modifier::arabic: {
+ utf8::itou_buf_type buf;
+ zstring tmp( utf8::itou( n, buf, mod.first.zero ) );
+ if ( mod.second.co_type == modifier::ordinal )
+ tmp += ordinal( n );
+ *dest += mod.left_pad_zero( &tmp );
+ break;
+ }
+
+ case modifier::alpha:
+ case modifier::ALPHA: {
+ zstring tmp( alpha( n, mod.first.type == modifier::ALPHA ) );
+ *dest += mod.right_pad_space( &tmp );
+ break;
+ }
+
+ case modifier::roman:
+ case modifier::ROMAN: {
+ ostringstream oss;
+ if ( mod.first.type == modifier::ROMAN )
+ oss << uppercase;
+ oss << roman( n );
+ zstring tmp( oss.str() );
+ *dest += mod.right_pad_space( &tmp );
+ break;
+ }
+
+ case modifier::words: {
+ zstring tmp( english( n, mod.second.co_type == modifier::ordinal ) );
+ *dest += mod.right_pad_space( &tmp );
+ break;
+ }
+
+ case modifier::Words: {
+ zstring tmp( english( n, mod.second.co_type == modifier::ordinal ) );
+ std::transform( tmp.begin(), tmp.end(), tmp.begin(), to_title() );
+ *dest += mod.right_pad_space( &tmp );
+ break;
+ }
+
+ case modifier::WORDS: {
+ zstring tmp( english( n, mod.second.co_type == modifier::ordinal ) );
+ ascii::to_upper( tmp );
+ *dest += mod.right_pad_space( &tmp );
+ break;
+ }
+
+ default:
+ /* handled elsewhere */;
+ }
+}
+
+static void append_fractional_seconds( int n, modifier const &mod,
+ zstring *dest ) {
+ switch ( mod.first.type ) {
+ case modifier::arabic:
+ if ( mod.min_width || mod.max_width ) {
+ if ( mod.max_width ) {
+ double const f = (double)n / DateTime::FRAC_SECONDS_UPPER_LIMIT;
+ double const p = ::pow( 10, mod.max_width );
+ n = (int)( f * p + 0.5 );
+ } else
+ n = (int)( n * 1000.0 / DateTime::FRAC_SECONDS_UPPER_LIMIT );
+
+ ascii::itoa_buf_type buf;
+ zstring tmp( ascii::itoa( n, buf ) );
+
+ if ( tmp.size() < mod.min_width )
+ ascii::right_pad( &tmp, mod.min_width, '0' );
+ else if ( mod.min_width > 0 )
+ while ( tmp.size() > mod.min_width &&
+ tmp[ tmp.size() - 1 ] == '0' ) {
+ tmp = tmp.substr( 0, tmp.size() - 1 );
+ }
+ *dest += tmp;
+ break;
+ }
+ n = (int)( n * 1000.0 / DateTime::FRAC_SECONDS_UPPER_LIMIT );
+ // no break;
+ default:
+ append_number( n, mod, dest );
+ }
+}
+
+static void append_string( zstring const &s, modifier const &mod,
+ zstring *dest ) {
+ zstring tmp;
+ switch ( mod.first.type ) {
+ case modifier::name:
+ utf8::to_lower( s, &tmp );
+ break;
+ case modifier::Name: {
+ utf8::to_upper( s.substr( 0, 1 ), &tmp );
+ zstring tmp2;
+ utf8::to_lower( s.substr( 1 ), &tmp2 );
+ tmp += tmp2;
+ break;
+ }
+ case modifier::NAME:
+ utf8::to_upper( s, &tmp );
+ break;
+ default:
+ break;
+ }
+ *dest += mod.right_pad_space( &tmp );
+}
+
+static void append_month( unsigned mon, modifier const &mod, zstring *dest ) {
+ switch ( mod.first.type ) {
+ case modifier::name:
+ case modifier::Name:
+ case modifier::NAME: {
+ zstring name( locale::get_month_name( mon, mod.lang, mod.country ) );
+ utf8_string<zstring> u_name( name );
+ if ( mod.gt_max_width( u_name.size() ) ) {
+ //
+ // XQuery 3.0 F&O: 9.8.4.1: If the full representation of the value
+ // exceeds the specified maximum width, then the processor should
+ // attempt to use an alternative shorter representation that fits
+ // within the maximum width. Where the presentation modifier is N, n,
+ // or Nn, this is done by abbreviating the name, using either
+ // conventional abbreviations if available, or crude right-truncation
+ // if not.
+ //
+ name = locale::get_month_abbr( mon, mod.lang, mod.country );
+ if ( mod.gt_max_width( u_name.size() ) )
+ u_name = u_name.substr( 0, mod.max_width );
+ }
+ mod.append_if_fallback_lang( dest );
+ append_string( name, mod, dest );
+ break;
+ }
+ default:
+ append_number( mon + 1, mod, dest );
+ }
+}
+
+static void append_timezone( char component, TimeZone const &tz,
+ modifier const &mod, zstring *dest ) {
+ ascii::itoa_buf_type buf;
+ zstring format, tmp;
+ bool has_grouping_separators;
+
+ if ( mod.first.format.empty() ) {
+ format = "01:01";
+ has_grouping_separators = true;
+ } else {
+ format = mod.first.format;
+ has_grouping_separators = mod.first.has_grouping_separators;
+ }
+
+ int hour = tz.getHours();
+ int const min = std::abs( tz.getMinutes() );
+
+ switch ( mod.first.type ) {
+ case modifier::NAME:
+ //
+ // XQuery 3.0 F&O: 9.8.4.2: If the first presentation modifier is N, then
+ // the timezone is output (where possible) as a timezone name, for
+ // example EST or CET. The same timezone offset has different names in
+ // different places; it is therefore recommended that this option should
+ // be used only if a country code or Olson timezone name is supplied in
+ // the $place argument. In the absence of this information, the
+ // implementation may apply a default, for example by using the timezone
+ // names that are conventional in North America. If no timezone name can
+ // be identified, the timezone offset is output using the fallback format
+ // +01:01.
+ //
+ if ( !min )
+ switch ( hour ) {
+ case 0: tmp += "GMT"; goto append;
+ case -5: tmp += "EST"; goto append;
+ case -6: tmp += "CST"; goto append;
+ case -7: tmp += "MST"; goto append;
+ case -8: tmp += "PST"; goto append;
+ }
+ // TODO: use Olson timezone names
+ goto fallback;
+
+ case modifier::military_tz:
+ //
+ // Ibid: If the first presentation modifier is Z, then the timezone is
+ // formatted as a military timezone letter, using the convention Z =
+ // +00:00, A = +01:00, B = +02:00, ..., M = +12:00, N = -01:00, O =
+ // -02:00, ... Y = -12:00.
+ //
+ if ( tz.timeZoneNotSet() ) {
+ //
+ // Ibid: The letter J (meaning local time) is used in the case of a
+ // value that does not specify a timezone offset.
+ //
+ tmp += 'J';
+ break;
+ }
+ if ( hour >= -12 && hour <= 12 && !min ) {
+ tmp += time::get_military_tz( hour );
+ break;
+ }
+ //
+ // Ibid: Timezone offsets that have no representation in this system
+ // (for example Indian Standard Time, +05:30) are output as if the
+ // format 01:01 had been requested.
+ //
+ // no break;
+
+fallback:
+ format = "01:01";
+ // no break;
+
+ default:
+ if ( component == 'z' ) {
+ //
+ // Ibid: When the component specifier is z, the output is the same as
+ // for component specifier Z, except that it is prefixed by the
+ // characters GMT or some localized equivalent. The prefix is omitted,
+ // however, in cases where the timezone is identified by name rather
+ // than by a numeric offset from UTC.
+ //
+ tmp = "GMT";
+ }
+
+ if ( mod.second.at_type == modifier::traditional && !hour && !min ) {
+ //
+ // Ibid: If the first presentation modifier is numeric, in any of the
+ // above formats, and the second presentation modifier is t, then a
+ // zero timezone offset (that is, UTC) is output as Z instead of a
+ // signed numeric value.
+ //
+ tmp += 'Z';
+ break;
+ }
+
+ if ( tz.isNegative() )
+ tmp += '-', hour = std::abs( hour );
+ else
+ tmp += '+';
+
+ if ( has_grouping_separators ) {
+ //
+ // Ibid: If the first presentation modifier is numeric with a grouping-
+ // separator (for example 1:01 or 01.01), then the timezone offset is
+ // output in hours and minutes, separated by the grouping separator,
+ // even if the number of minutes is zero: for example +5:00 or +10.30.
+ //
+ int grouping_separators = 0;
+ bool got_digit = false;
+ int hm_width[] = { 0, 0 }; // hour/minute widths
+ utf8_string<zstring const> const u_format( format );
+ utf8_string<zstring> u_tmp( tmp );
+
+ FOR_EACH( utf8_string<zstring const>, i, u_format ) {
+ unicode::code_point const cp = *i;
+ if ( unicode::is_Nd( cp ) ) {
+ got_digit = true;
+ if ( grouping_separators < 2 )
+ ++hm_width[ grouping_separators ];
+ continue;
+ }
+ if ( got_digit && is_grouping_separator( cp ) ) {
+ if ( ++grouping_separators == 1 ) {
+ zstring tmp2( utf8::itou( hour, buf, mod.first.zero ) );
+ tmp += utf8::left_pad( &tmp2, hm_width[0], mod.first.zero );
+ }
+ } else if ( grouping_separators )
+ grouping_separators = 99;
+ u_tmp += cp;
+ }
+
+ if ( hm_width[1] ) {
+ zstring tmp2( utf8::itou( min, buf, mod.first.zero ) );
+ tmp += utf8::left_pad( &tmp2, hm_width[1], mod.first.zero );
+ }
+ } else {
+ utf8_string<zstring const> const u_format( format );
+ utf8_string<zstring const>::size_type const u_size( u_format.size() );
+
+ if ( u_size <= 2 ) {
+ //
+ // Ibid: If the first presentation modifier is numeric and comprises
+ // one or two digits with no grouping-separator (for example 1 or
+ // 01), then the timezone is formatted as a displacement from UTC in
+ // hours, preceded by a plus or minus sign: for example -5 or +03. If
+ // the actual timezone offset is not an integral number of hours,
+ // then the minutes part of the offset is appended, separated by a
+ // colon: for example +10:30 or -1:15.
+ //
+ zstring tmp2( utf8::itou( hour, buf, mod.first.zero ) );
+ tmp += utf8::left_pad( &tmp2, u_size, mod.first.zero );
+ if ( min ) {
+ tmp2 = utf8::itou( min, buf, mod.first.zero );
+ tmp += ':';
+ tmp += utf8::left_pad( &tmp2, 2, mod.first.zero );
+ }
+ break;
+ }
+ if ( u_size <= 4 ) {
+ //
+ // Ibid: If the first presentation modifier is numeric and comprises
+ // three or four digits with no grouping-separator, for example 001
+ // or 0001, then the timezone offset is shown in hours and minutes
+ // with no separator, for example -0500 or +1030.
+ //
+ int const hhmm = hour * 100 + min;
+ zstring tmp2( utf8::itou( hhmm, buf, mod.first.zero ) );
+ tmp += utf8::left_pad( &tmp2, u_size, mod.first.zero );
+ break;
+ }
+ } // else
+ } // switch
+
+append:
+ *dest += tmp;
+}
+
+static void append_weekday( unsigned mday, unsigned mon, unsigned year,
+ modifier const &mod, zstring *dest ) {
+ int wday = time::calc_wday( mday, mon, year );
+
+ modifier mod_copy( mod );
+ if ( !mod.first.parsed )
+ mod_copy.first.type = modifier::name;
+
+ switch ( mod_copy.first.type ) {
+ case modifier::name:
+ case modifier::Name:
+ case modifier::NAME: {
+ zstring name( locale::get_weekday_name( wday, mod.lang, mod.country ) );
+ utf8_string<zstring> u_name( name );
+ if ( mod.gt_max_width( u_name.size() ) ) {
+ //
+ // XQuery 3.0 F&O: 9.8.4.1: If the full representation of the value
+ // exceeds the specified maximum width, then the processor should
+ // attempt to use an alternative shorter representation that fits
+ // within the maximum width. Where the presentation modifier is N, n,
+ // or Nn, this is done by abbreviating the name, using either
+ // conventional abbreviations if available, or crude right-truncation
+ // if not.
+ //
+ name = locale::get_weekday_abbr( wday, mod.lang, mod.country );
+ if ( mod.gt_max_width( u_name.size() ) )
+ u_name = u_name.substr( 0, mod.max_width );
+ }
+ mod.append_if_fallback_lang( dest );
+ append_string( name, mod_copy, dest );
+ break;
+ }
+ default: {
+ int const new_wday = calendar::convert_wday_to( wday, mod.cal );
+ if ( mod.cal_is_fallback || new_wday == -1 ) {
+ //
+ // Ibid: If the fallback representation uses a different calendar from
+ // that requested, the output string must identify the calendar
+ // actually used, for example by prefixing the string with [Calendar:
+ // X] (where X is the calendar actually used), localized as appropriate
+ // to the requested language.
+ //
+ ostringstream oss;
+ // TODO: localize "Calendar"
+ oss << "[Calendar: "
+ << ( new_wday == -1 ? calendar::get_default() : mod.cal ) << ']';
+ *dest += oss.str();
+ } else
+ wday = new_wday;
+ append_number( wday, mod_copy, dest );
+ }
+ }
+}
+
+static void append_week_in_year( unsigned mday, unsigned mon, unsigned year,
+ modifier const &mod, zstring *dest ) {
+ int week = time::calendar::calc_week_in_year( mday, mon, year, mod.cal );
+ if ( week == -1 ) {
+ week = time::calendar::calc_week_in_year( mday, mon, year, calendar::ISO );
+ ostringstream oss;
+ // TODO: localize "Calendar"
+ oss << "[Calendar: " << calendar::string_of[ calendar::ISO ] << ']';
+ *dest += oss.str();
+ }
+ append_number( week, mod, dest );
+}
+
+static void append_year( int year, modifier const &mod, zstring *s ) {
+ zstring tmp;
+ append_number( year, mod, &tmp );
+
+ if ( mod.first.type == modifier::arabic ) {
+ utf8_string<zstring> u_tmp( tmp );
+ utf8_string<zstring>::size_type const u_size = u_tmp.size();
+ if ( mod.gt_max_width( u_size ) ) {
+ //
+ // XQuery 3.0 F&O: 9.8.4.1: If the full representation of the value
+ // exceeds the specified maximum width, then the processor should attempt
+ // to use an alternative shorter representation that fits within the
+ // maximum width. ... In the case of the year component, setting
+ // max-width requests omission of high-order digits from the year, for
+ // example, if max-width is set to 2 then the year 2003 will be output as
+ // 03.
+ //
+ u_tmp = u_tmp.substr( u_size - mod.max_width );
+ }
+ }
+ *s += tmp;
+}
+
+static void parse_first_modifier( zstring const &picture_str,
+ zstring::const_iterator *i,
+ modifier *mod, QueryLoc const &loc ) {
+ zstring::const_iterator &j = *i;
+ ascii::skip_whitespace( picture_str, &j );
+ if ( j == picture_str.end() || *j == ',' ) {
+ //
+ // Assume that the ',' is the start of the width modifier (hence there is
+ // neither a first nor second modifier).
+ //
+ return;
+ }
+
+ utf8_string<zstring const> const u_picture_str( picture_str );
+ utf8_string<zstring const>::const_iterator u( u_picture_str.current( j ) );
+ utf8_string<zstring> u_mod_format( mod->first.format );
+ unicode::code_point cp = *u;
+
+ if ( cp != '#' && is_grouping_separator( cp ) ) {
+ //
+ // XQuery 3.0 F&O: 4.6.1: A grouping-separator-sign must not appear
+ // at the start ... of the decimal-digit-pattern ....
+ //
+ throw XQUERY_EXCEPTION(
+ err::FOFD1340,
+ ERROR_PARAMS(
+ picture_str,
+ ZED( FOFD1340_NoGroupSepAtStart_3 ),
+ unicode::printable_cp( cp )
+ ),
+ ERROR_LOC( loc )
+ );
+ }
+
+ //
+ // Because of:
+ //
+ // Ibid: if a variable marker contains one or more commas, then the last
+ // comma is treated as introducing the width modifier, and all others are
+ // treated as grouping separators.
+ //
+ // we have to count the number of commas in order to know when we've reached
+ // the last one.
+ //
+ int commas = 0;
+ for ( zstring::const_iterator c( *i ); c != picture_str.end(); ++c )
+ if ( *c == ',' )
+ ++commas;
+
+ unicode::code_point zero[2];
+
+ if ( cp == '#' || unicode::is_Nd( cp, &zero[0] ) ) {
+ bool got_grouping_separator = false;
+ bool got_mandatory_digit = cp != '#';
+
+ u_mod_format = *u;
+ while ( ++u != u_picture_str.end() ) {
+ cp = *u;
+ if ( cp == '#' ) {
+ if ( got_mandatory_digit ) {
+ //
+ // Ibid: There may be zero or more optional-digit-signs, and (if
+ // present) these must precede all mandatory-digit-signs.
+ //
+ throw XQUERY_EXCEPTION(
+ err::FOFD1340,
+ ERROR_PARAMS(
+ picture_str,
+ ZED( FOFD1340_NoOptDigitAfterMandatory )
+ ),
+ ERROR_LOC( loc )
+ );
+ }
+ got_grouping_separator = false;
+ } else if ( unicode::is_Nd( cp, &zero[ got_mandatory_digit ] ) ) {
+ if ( got_mandatory_digit ) {
+ if ( zero[1] != zero[0] ) {
+ //
+ // Ibid: All mandatory-digit-signs within the format token must be
+ // from the same digit family, where a digit family is a sequence
+ // of ten consecutive characters in Unicode category Nd, having
+ // digit values 0 through 9.
+ //
+ throw XQUERY_EXCEPTION(
+ err::FOFD1340,
+ ERROR_PARAMS(
+ picture_str,
+ ZED( FOFD1340_DigitNotSameFamily_34 ),
+ unicode::printable_cp( cp ),
+ unicode::printable_cp( zero[1] )
+ ),
+ ERROR_LOC( loc )
+ );
+ }
+ //
+ // Ibid: A format token containing more than one digit, such as 001
+ // or 9999, sets the minimum and maximum width to the number of
+ // digits appearing in the format token.
+ //
+ if ( !mod->min_width )
+ mod->min_width = mod->max_width = 2;
+ else
+ mod->min_width = ++mod->max_width;
+ } else
+ got_mandatory_digit = true;
+ got_grouping_separator = false;
+ } else if ( cp == ';' || cp == ']' )
+ break;
+ else if ( unicode::is_space( cp ) )
+ continue;
+ else if ( is_grouping_separator( cp ) ) {
+ if ( cp == ',' && !--commas ) {
+ //
+ // Ibid: if a variable marker contains one or more commas, then the
+ // last comma is treated as introducing the width modifier, and all
+ // others are treated as grouping separators.
+ //
+ break;
+ }
+ if ( got_grouping_separator ) {
+ //
+ // Ibid: A grouping-separator-sign must not appear ... adjacent to
+ // another grouping-separator-sign.
+ //
+ throw XQUERY_EXCEPTION(
+ err::FOFD1340,
+ ERROR_PARAMS(
+ picture_str,
+ ZED( FOFD1340_NoAdjacentGroupSep_3 ),
+ unicode::printable_cp( cp )
+ ),
+ ERROR_LOC( loc )
+ );
+ }
+ got_grouping_separator = true;
+ mod->first.has_grouping_separators = true;
+ } else
+ break;
+
+ u_mod_format += cp;
+ } // while
+ if ( got_grouping_separator ) {
+ //
+ // Ibid: A grouping-separator-sign must not appear at the ... end of the
+ // decimal-digit-pattern ....
+ //
+ throw XQUERY_EXCEPTION(
+ err::FOFD1340,
+ ERROR_PARAMS(
+ picture_str,
+ ZED( FOFD1340_NoGroupSepAtEnd_3 ),
+ unicode::printable_cp( cp )
+ ),
+ ERROR_LOC( loc )
+ );
+ }
+ if ( !got_mandatory_digit ) {
+ //
+ // Ibid: There must be at least one mandatory-digit-sign.
+ //
+ throw XQUERY_EXCEPTION(
+ err::FOFD1340,
+ ERROR_PARAMS( picture_str, ZED( FOFD1340_MustBeOneMandatoryDigit ) ),
+ ERROR_LOC( loc )
+ );
+ }
+ mod->first.zero = zero[0];
+ j = u.base();
+ } else {
+ switch ( *j++ ) {
+ case 'A':
+ mod->first.type = modifier::ALPHA;
+ break;
+ case 'a':
+ mod->first.type = modifier::alpha;
+ break;
+ case 'I':
+ mod->first.type = modifier::ROMAN;
+ break;
+ case 'i':
+ mod->first.type = modifier::roman;
+ break;
+ case 'N':
+ if ( j != picture_str.end() && *j == 'n' )
+ mod->first.type = modifier::Name, ++j;
+ else
+ mod->first.type = modifier::NAME;
+ break;
+ case 'n':
+ mod->first.type = modifier::name;
+ break;
+ case 'W':
+ if ( j != picture_str.end() && *j == 'w' )
+ mod->first.type = modifier::Words, ++j;
+ else
+ mod->first.type = modifier::WORDS;
+ break;
+ case 'w':
+ mod->first.type = modifier::words;
+ break;
+ case 'Z':
+ mod->first.type = modifier::military_tz;
+ break;
+ default:
+ //
+ // Ibid: If an implementation does not support a numbering sequence
+ // represented by the given token, it must use a format token of 1.
+ //
+ mod->first.type = modifier::arabic;
+ } // switch
+ }
+ mod->first.parsed = true;
+}
+
+static void parse_second_modifier( zstring const &picture_str,
+ zstring::const_iterator *i, modifier *mod,
+ QueryLoc const &loc ) {
+ zstring::const_iterator &j = *i;
+ ascii::skip_whitespace( picture_str, &j );
+ if ( j == picture_str.end() )
+ return;
+ switch ( *j ) {
+ case 'c': mod->second.co_type = modifier::cardinal ; break;
+ case 'o': mod->second.co_type = modifier::ordinal ; break;
+ case 'a': mod->second.at_type = modifier::alphabetic ; ++j; return;
+ case 't': mod->second.at_type = modifier::traditional; ++j; return;
+ default : return;
+ }
+ if ( ++j == picture_str.end() )
+ return;
+ if ( *j == '(' ) {
+ while ( true ) {
+ if ( ++j == picture_str.end() )
+ throw XQUERY_EXCEPTION(
+ err::FOFD1340,
+ ERROR_PARAMS( picture_str, ZED( CharExpected_3 ), ')' ),
+ ERROR_LOC( loc )
+ );
+ if ( *j == ')' )
+ break;
+ mod->second.co_string += *j;
+ }
+ ++j;
+ }
+}
+
+static void parse_width_modifier( zstring const &picture_str,
+ zstring::const_iterator *i, modifier *mod,
+ QueryLoc const &loc ) {
+ zstring::const_iterator &j = *i;
+
+ ascii::skip_whitespace( picture_str, &j );
+ if ( j == picture_str.end() || (*j != ',' && *j != ';') )
+ return;
+ ascii::skip_whitespace( picture_str, &++j );
+ if ( j == picture_str.end() )
+ goto bad_width_modifier;
+ if ( *j == '*' ) {
+ mod->min_width = 0;
+ ++j;
+ } else {
+ try {
+ mod->min_width = static_cast<modifier::width_type>(
+ ztd::atoull( j, picture_str.end(), &j )
+ );
+ }
+ catch ( std::exception const& ) {
+ goto bad_width_modifier;
+ }
+ }
+
+ mod->max_width = 0;
+
+ ascii::skip_whitespace( picture_str, &j );
+ if ( j == picture_str.end() || *j != '-' )
+ return;
+ ascii::skip_whitespace( picture_str, &++j );
+ if ( j == picture_str.end() )
+ goto bad_width_modifier;
+ if ( *j == '*' )
+ ++j;
+ else {
+ try {
+ mod->max_width = static_cast<modifier::width_type>(
+ ztd::atoull( j, picture_str.end(), &j )
+ );
+ }
+ catch ( std::exception const& ) {
+ goto bad_width_modifier;
+ }
+ }
+
+ return;
+
+bad_width_modifier:
+ throw XQUERY_EXCEPTION(
+ err::FOFD1340,
+ ERROR_PARAMS( picture_str, ZED( FOFD1340_BadWidthModifier ) ),
+ ERROR_LOC( loc )
+ );
+}
+
+static int get_data_type( char component ) {
+ switch ( component ) {
+ case 'D': return DateTime::DAY_DATA;
+ case 'd': return DateTime::DAY_DATA;
+ case 'E': return DateTime::YEAR_DATA;
+ case 'F': return DateTime::DAY_DATA;
+ case 'f': return DateTime::FRACSECONDS_DATA;
+ case 'H': return DateTime::HOUR_DATA;
+ case 'h': return DateTime::HOUR_DATA;
+ case 'm': return DateTime::MINUTE_DATA;
+ case 'M': return DateTime::MONTH_DATA;
+ case 'P': return DateTime::HOUR_DATA;
+ case 's': return DateTime::SECONDS_DATA;
+ case 'W': return DateTime::DAY_DATA;
+ case 'w': return DateTime::DAY_DATA;
+ case 'Y': return DateTime::YEAR_DATA;
+ default : return -1;
+ }
+}
+
+bool FnFormatDateTimeIterator::nextImpl( store::Item_t& result,
+ PlanState &planState ) const {
+ zstring picture_str, result_str, item_str;
+ xs_dateTime dateTime;
+ calendar::type cal = calendar::unknown;
+ iso639_1::type lang = iso639_1::unknown;
+ iso3166_1::type country = iso3166_1::unknown;
+ bool cal_is_fallback = false, lang_is_fallback = false;
+ bool in_variable_marker;
+ store::Item_t item;
+ PlanIteratorState *state;
+
+ DEFAULT_STACK_INIT( PlanIteratorState, state, planState);
+
+ if ( !consumeNext( item, theChildren[0].getp(), planState ) ) {
+ // Got the empty sequence -- return same
+ STACK_PUSH( false, state );
+ } else {
+ dateTime = item->getDateTimeValue();
+ consumeNext( item, theChildren[1].getp(), planState );
+ item->getStringValue2( picture_str );
+
+ if ( theChildren.size() > 2 ) {
+ consumeNext( item, theChildren[2].getp(), planState );
+ if ( !locale::parse( item->getStringValue(), &lang, &country ) ||
+ !locale::is_supported( lang, country ) ) {
+ lang = iso639_1::unknown;
+ lang_is_fallback = true;
+ }
+
+ consumeNext( item, theChildren[3].getp(), planState );
+ item->getStringValue2( item_str );
+ // TODO: handle calendar being a QName.
+ cal = calendar::find( item_str );
+ if ( !cal )
+ cal_is_fallback = true;
+
+ consumeNext( item, theChildren[4].getp(), planState );
+ item->getStringValue2( item_str );
+ // TODO: do something with place
+ }
+
+ if ( !cal ) {
+ //
+ // XQuery 3.0 F&O: 9.8.4.3: If the $calendar argument is omitted or is
+ // set to an empty sequence then the default calendar defined in the
+ // dynamic context is used.
+ //
+ cal = planState.theLocalDynCtx->get_calendar();
+ }
+
+ if ( !lang ) {
+ //
+ // Ibid: If the $language argument is omitted or is set to an empty
+ // sequence, or if it is set to an invalid value or a value that the
+ // implementation does not recognize, then the processor uses the default
+ // language defined in the dynamic context.
+ //
+ planState.theLocalDynCtx->get_locale( &lang, &country );
+ }
+
+ char component;
+ in_variable_marker = false;
+
+ FOR_EACH( zstring, i, picture_str ) {
+ if ( !in_variable_marker ) {
+ switch ( *i ) {
+ case '[':
+ if ( ztd::peek( picture_str, i ) == '[' )
+ ++i;
+ else {
+ component = 0;
+ in_variable_marker = true;
+ continue;
+ }
+ break;
+ case ']':
+ if ( ztd::peek( picture_str, i ) == ']' )
+ ++i;
+ break;
+ }
+ result_str += *i;
+ continue;
+ }
+
+ if ( ascii::is_space( *i ) )
+ continue; // ignore all whitespace
+
+ switch ( *i ) {
+ case ']':
+ if ( !component )
+ throw XQUERY_EXCEPTION(
+ err::FOFD1340,
+ ERROR_PARAMS( picture_str, ZED( FOFD1340_NoComponent ) ),
+ ERROR_LOC( loc )
+ );
+ component = 0;
+ in_variable_marker = false;
+ continue;
+ case 'C':
+ case 'D':
+ case 'd':
+ case 'E':
+ case 'F':
+ case 'f':
+ case 'H':
+ case 'h':
+ case 'M':
+ case 'm':
+ case 'P':
+ case 's':
+ case 'W':
+ case 'w':
+ case 'Y':
+ case 'Z':
+ case 'z':
+#if 0
+ if ( component )
+ throw XQUERY_EXCEPTION(
+ err::FOFD1340,
+ ERROR_PARAMS(
+ picture_str, ZED( FOFD1340_MultipleComponent_3 ), *i
+ ),
+ ERROR_LOC( loc )
+ );
+#endif
+ component = *i;
+ break;
+ default:
+ throw XQUERY_EXCEPTION(
+ err::FOFD1340,
+ ERROR_PARAMS( picture_str, ZED( FOFD1340_BadComponent_3 ), *i ),
+ ERROR_LOC( loc )
+ );
+ } // switch
+ if ( ++i == picture_str.end() )
+ goto eos;
+
+ modifier mod;
+ mod.lang = lang;
+ mod.lang_is_fallback = lang_is_fallback;
+ mod.country = country;
+ mod.cal = cal;
+ mod.cal_is_fallback = cal_is_fallback;
+
+ if ( *i != ']' ) {
+ parse_first_modifier( picture_str, &i, &mod, loc );
+ if ( i == picture_str.end() )
+ goto eos;
+ if ( *i != ']' ) {
+ parse_second_modifier( picture_str, &i, &mod, loc );
+ if ( i == picture_str.end() )
+ goto eos;
+ parse_width_modifier( picture_str, &i, &mod, loc );
+ if ( i == picture_str.end() )
+ goto eos;
+ }
+ }
+ if ( *i == ']' )
+ --i;
+
+ int const data_type = get_data_type( component );
+ if ( data_type != -1 && !DateTime::FACET_MEMBERS[facet_type][data_type] )
+ throw XQUERY_EXCEPTION(
+ err::FOFD1350, ERROR_PARAMS( component ), ERROR_LOC( loc )
+ );
+
+ switch ( component ) {
+ case 'C': { // calendar
+ modifier mod_copy( mod );
+ if ( !mod.first.parsed )
+ mod_copy.first.type = modifier::name;
+ append_string( "gregorian", mod_copy, &result_str );
+ break;
+ }
+ case 'D':
+ append_number( dateTime.getDay(), mod, &result_str );
+ break;
+ case 'd':
+ append_number( dateTime.getDayOfYear(), mod, &result_str );
+ break;
+ case 'E': { // era
+ modifier mod_copy( mod );
+ if ( !mod.first.parsed )
+ mod_copy.first.type = modifier::name;
+ int const year = dateTime.getYear();
+ zstring const era( year > 0 ? "ad" : year < 0 ? "bc" : "" );
+ append_string( era, mod_copy, &result_str );
+ break;
+ }
+ case 'F': {
+ modifier mod_copy( mod );
+ if ( !mod.first.parsed )
+ mod_copy.first.type = modifier::name;
+ append_weekday(
+ dateTime.getDay(), dateTime.getMonth() - 1, dateTime.getYear(),
+ mod_copy, &result_str
+ );
+ break;
+ }
+ case 'f':
+ append_fractional_seconds(
+ dateTime.getFractionalSeconds(), mod, &result_str
+ );
+ break;
+ case 'H': // hour (24 hours)
+ append_number( dateTime.getHours(), mod, &result_str );
+ break;
+ case 'h': // hour (12 hours)
+ // Convert hour from: 0 1 ... 12 13 ... 23
+ // to: 12 1 ... 12 1 ... 11
+ append_number(
+ 1 + (11 + dateTime.getHours()) % 12, mod, &result_str
+ );
+ break;
+ case 'M':
+ append_month( dateTime.getMonth() - 1, mod, &result_str );
+ break;
+ case 'm': {
+ modifier mod_copy( mod );
+ mod_copy.set_default_width( 2 );
+ append_number( dateTime.getMinutes(), mod_copy, &result_str );
+ break;
+ }
+ case 'P': {
+ modifier mod_copy( mod );
+ if ( !mod.first.parsed )
+ mod_copy.first.type = modifier::name;
+ append_string(
+ locale::get_time_ampm( dateTime.getHours() >= 12, lang, country ),
+ mod_copy, &result_str
+ );
+ break;
+ }
+ case 's': {
+ modifier mod_copy( mod );
+ mod_copy.set_default_width( 2 );
+ append_number( dateTime.getIntSeconds(), mod_copy, &result_str );
+ break;
+ }
+ case 'W':
+ append_week_in_year(
+ dateTime.getDay(), dateTime.getMonth() - 1, dateTime.getYear(),
+ mod, &result_str
+ );
+ break;
+ case 'w':
+ append_number( dateTime.getWeekInMonth(), mod, &result_str );
+ break;
+ case 'Y':
+ append_year( std::abs( dateTime.getYear() ), mod, &result_str );
+ break;
+ case 'Z':
+ case 'z':
+ append_timezone(
+ component, dateTime.getTimezone(), mod, &result_str
+ );
+ break;
+ } // switch
+ } // for
+
+ if ( in_variable_marker )
+eos: throw XQUERY_EXCEPTION(
+ err::FOFD1340,
+ ERROR_PARAMS( picture_str, ZED( CharExpected_3 ), ']' ),
+ ERROR_LOC( loc )
+ );
+
+ STACK_PUSH( GENV_ITEMFACTORY->createString( result, result_str ), state );
+ }
+
+ STACK_END( state );
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+} // namespace zorba
+/* vim:set et sw=2 ts=2: */
=== added file 'src/runtime/durations_dates_times/format_dateTime.h'
--- src/runtime/durations_dates_times/format_dateTime.h 1970-01-01 00:00:00 +0000
+++ src/runtime/durations_dates_times/format_dateTime.h 2013-03-20 21:54:22 +0000
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2006-2008 The FLWOR Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ZORBA_RUNTIME_FORMAT_DATETIME_H
+#define ZORBA_RUNTIME_FORMAT_DATETIME_H
+
+#include "common/shared_types.h"
+#include "zorbatypes/datetime.h"
+
+#include "runtime/base/binarybase.h"
+#include "runtime/base/unarybase.h"
+#include "runtime/base/narybase.h"
+
+namespace zorba {
+
+///////////////////////////////////////////////////////////////////////////////
+
+// XQuery 3.0 DateTime formatting
+class FnFormatDateTimeIterator :
+ public NaryBaseIterator<FnFormatDateTimeIterator,PlanIteratorState>
+{
+
+public:
+ SERIALIZABLE_CLASS(FnFormatDateTimeIterator);
+
+ SERIALIZABLE_CLASS_CONSTRUCTOR2T(
+ FnFormatDateTimeIterator,
+ NaryBaseIterator<FnFormatDateTimeIterator, PlanIteratorState >);
+
+ void serialize( ::zorba::serialization::Archiver &ar )
+ {
+ serialize_baseclass(ar,
+ (NaryBaseIterator<FnFormatDateTimeIterator, PlanIteratorState >*)this);
+
+ SERIALIZE_ENUM(DateTime::FACET_TYPE, facet_type);
+ }
+
+public:
+ FnFormatDateTimeIterator(
+ static_context *sctx,
+ QueryLoc const &loc,
+ std::vector<PlanIter_t> &aChildren,
+ DateTime::FACET_TYPE a_facet_type = DateTime::DATETIME_FACET)
+ :
+ NaryBaseIterator<FnFormatDateTimeIterator, PlanIteratorState>(sctx, loc, aChildren),
+ facet_type(a_facet_type)
+ {
+ }
+
+ void accept( PlanIterVisitor& ) const;
+
+ bool nextImpl( store::Item_t&, PlanState& ) const;
+
+private:
+ DateTime::FACET_TYPE facet_type;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+} // namespace zorba
+
+#endif /* ZORBA_RUNTIME_FORMAT_DATETIME_H */
+/*
+ * Local variables:
+ * mode: c++
+ * End:
+ */
+/* vim:set et sw=2 ts=2: */
=== modified file 'src/runtime/visitors/printer_visitor_impl.cpp'
--- src/runtime/visitors/printer_visitor_impl.cpp 2013-03-05 12:34:19 +0000
+++ src/runtime/visitors/printer_visitor_impl.cpp 2013-03-20 21:54:22 +0000
@@ -46,6 +46,7 @@
#include "runtime/core/arithmetic_impl.h"
#include "runtime/sequences/SequencesImpl.h"
#include "runtime/durations_dates_times/DurationsDatesTimesImpl.h"
+#include "runtime/durations_dates_times/format_dateTime.h"
#ifdef ZORBA_WITH_DEBUGGER
#include "runtime/debug/debug_iterator.h"
#endif
=== modified file 'src/unit_tests/CMakeLists.txt'
--- src/unit_tests/CMakeLists.txt 2013-02-26 04:12:43 +0000
+++ src/unit_tests/CMakeLists.txt 2013-03-20 21:54:22 +0000
@@ -21,6 +21,7 @@
test_mem_sizeof.cpp
test_parameters.cpp
test_string.cpp
+ test_time.cpp
test_time_parse.cpp
test_uri.cpp
test_uuid.cpp
=== added file 'src/unit_tests/test_time.cpp'
--- src/unit_tests/test_time.cpp 1970-01-01 00:00:00 +0000
+++ src/unit_tests/test_time.cpp 2013-03-20 21:54:22 +0000
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2006-2008 The FLWOR Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "stdafx.h"
+
+#include <cstring>
+#include <functional>
+#include <iostream>
+#include <stdexcept>
+#include <string>
+
+#include "util/ascii_util.h"
+#include "util/stl_util.h"
+#include "util/time_util.h"
+#include "zorbatypes/zstring.h"
+
+using namespace std;
+using namespace zorba;
+using namespace zorba::time;
+
+///////////////////////////////////////////////////////////////////////////////
+
+static int failures;
+static int test_no;
+
+static bool assert_true( int no, char const *expr, int line, bool result ) {
+ if ( !result ) {
+ cout << '#' << no << " FAILED, line " << line << ": " << expr << endl;
+ ++failures;
+ }
+ return result;
+}
+
+#define ASSERT_TRUE( NO, EXPR ) assert_true( NO, #EXPR, __LINE__, !!(EXPR) )
+
+///////////////////////////////////////////////////////////////////////////////
+
+static void test_calc_week_in_year() {
+ struct test_type {
+ unsigned mday, mon, year;
+ time::calendar::type cal;
+ int expected;
+ };
+ static test_type const test[] = {
+ /* 1 */ { 1, time::jan, 2013, calendar::AD, 1 },
+ /* 2 */ { 2, time::jan, 2013, calendar::AD, 1 },
+ /* 3 */ { 3, time::jan, 2013, calendar::AD, 1 },
+ /* 4 */ { 4, time::jan, 2013, calendar::AD, 1 },
+ /* 5 */ { 5, time::jan, 2013, calendar::AD, 1 },
+ /* 6 */ { 6, time::jan, 2013, calendar::AD, 2 },
+ /* 7 */ { 28, time::dec, 2013, calendar::AD, 52 },
+ /* 8 */ { 31, time::dec, 2013, calendar::AD, 53 },
+
+ /* 9 */ { 1, time::jan, 2013, calendar::ISO, 1 },
+ /* 10 */ { 2, time::jan, 2013, calendar::ISO, 1 },
+ /* 11 */ { 3, time::jan, 2013, calendar::ISO, 1 },
+ /* 12 */ { 4, time::jan, 2013, calendar::ISO, 1 },
+ /* 13 */ { 5, time::jan, 2013, calendar::ISO, 1 },
+ /* 14 */ { 6, time::jan, 2013, calendar::ISO, 1 },
+ /* 15 */ { 7, time::jan, 2013, calendar::ISO, 2 },
+
+ // Test cases taken from http://en.wikipedia.org/wiki/ISO_week_date
+ /* 16 */ { 1, time::jan, 2005, calendar::ISO, 53 },
+ /* 17 */ { 2, time::jan, 2005, calendar::ISO, 53 },
+ /* 18 */ { 31, time::dec, 2005, calendar::ISO, 52 },
+ /* 19 */ { 1, time::jan, 2007, calendar::ISO, 1 },
+ /* 20 */ { 30, time::dec, 2007, calendar::ISO, 52 },
+ /* 21 */ { 31, time::dec, 2007, calendar::ISO, 1 },
+ /* 22 */ { 1, time::jan, 2008, calendar::ISO, 1 },
+ /* 23 */ { 28, time::dec, 2008, calendar::ISO, 52 },
+ /* 24 */ { 29, time::dec, 2008, calendar::ISO, 1 },
+ /* 25 */ { 30, time::dec, 2008, calendar::ISO, 1 },
+ /* 26 */ { 31, time::dec, 2008, calendar::ISO, 1 },
+ /* 27 */ { 31, time::dec, 2009, calendar::ISO, 53 },
+ /* 28 */ { 1, time::jan, 2010, calendar::ISO, 53 },
+ /* 29 */ { 2, time::jan, 2010, calendar::ISO, 53 },
+ /* 30 */ { 3, time::jan, 2010, calendar::ISO, 53 },
+ /* 31 */ { 4, time::jan, 2010, calendar::ISO, 1 },
+
+ { 0 },
+ };
+
+ for ( test_type const *t = test; t->mday; ++t ) {
+ int w = calendar::calc_week_in_year( t->mday, t->mon, t->year, t->cal );
+ ++test_no;
+ ASSERT_TRUE( test_no, w == t->expected );
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+namespace zorba {
+namespace UnitTests {
+
+int test_time( int, char*[] ) {
+
+ test_calc_week_in_year();
+
+ cout << failures << " test(s) failed\n";
+ return failures ? 1 : 0;
+}
+
+} // namespace UnitTests
+} // namespace zorba
+/* vim:set et sw=2 ts=2: */
=== modified file 'src/unit_tests/unit_test_list.h'
--- src/unit_tests/unit_test_list.h 2013-02-26 04:12:43 +0000
+++ src/unit_tests/unit_test_list.h 2013-03-20 21:54:22 +0000
@@ -40,6 +40,7 @@
int test_mem_sizeof( int, char*[] );
int test_parameters( int, char*[] );
int test_string( int, char*[] );
+ int test_time( int, char*[] );
int test_time_parse( int, char*[] );
#ifdef ZORBA_WITH_FILE_ACCESS
=== modified file 'src/unit_tests/unit_tests.cpp'
--- src/unit_tests/unit_tests.cpp 2013-02-26 04:12:43 +0000
+++ src/unit_tests/unit_tests.cpp 2013-03-20 21:54:22 +0000
@@ -55,6 +55,7 @@
libunittests["json_parser"] = test_json_parser;
libunittests["parameters"] = test_parameters;
libunittests["string"] = test_string;
+ libunittests["time"] = test_time;
libunittests["time_parse"] = test_time_parse;
#ifndef ZORBA_NO_FULL_TEXT
=== modified file 'src/util/ascii_util.h'
--- src/util/ascii_util.h 2013-03-18 17:12:00 +0000
+++ src/util/ascii_util.h 2013-03-20 21:54:22 +0000
@@ -22,6 +22,7 @@
#include <cctype>
#include <cstddef>
#include <cstring>
+#include <iterator>
// local
#include "omanip.h"
@@ -1147,9 +1148,62 @@
*pos = trim_start_whitespace( s + *pos, s_len - *pos ) - s;
}
+/**
+ * Skips any consecutive whitespace chars that are found at a given starting
+ * position within a given string.
+ *
+ * @tparam StringType The string type.
+ * @param s The string.
+ * @param i A pointer to the iterator to advance past the whitespace.
+ * On return, \a *i is updated with the position of the 1st non-whitespace
+ * char.
+ */
+template<class StringType> inline
+void skip_whitespace( StringType const &s,
+ typename StringType::const_iterator *i ) {
+ typename StringType::difference_type const d = *i - s.begin();
+ char const *const sd = s.data() + d;
+ std::advance( *i, trim_start_whitespace( sd, s.size() - d ) - sd );
+}
+
////////// Miscellaneous //////////////////////////////////////////////////////
/**
+ * Pads a string to the left with a given character until the string is the
+ * given width.
+ *
+ * @param s The string to pad.
+ * @param width The width to pad to.
+ * @param c The character to pad with.
+ * @return Returns \c *s.
+ */
+template<class StringType> inline
+StringType& left_pad( StringType *s, typename StringType::size_type width,
+ char c ) {
+ typedef typename StringType::size_type size_type;
+ if ( s->size() < width )
+ s->insert( static_cast<size_type>( 0 ), width - s->size(), c );
+ return *s;
+}
+
+/**
+ * Pads a string to the right with a given character until the string is the
+ * given width.
+ *
+ * @param s The string to pad.
+ * @param width The width to pad to.
+ * @param c The character to pad with.
+ * @return Returns \c *s.
+ */
+template<class StringType> inline
+StringType& right_pad( StringType *s, typename StringType::size_type width,
+ char c ) {
+ if ( s->size() < width )
+ s->append( width - s->size(), c );
+ return *s;
+}
+
+/**
* Prints the given character in a printable way: if \c is_print(c) is \c true,
* prints \a c as-is; otherwise prints \c #x followed by the hexadecimal value
* of the character.
=== modified file 'src/util/stream_util.cpp'
--- src/util/stream_util.cpp 2013-02-12 03:55:18 +0000
+++ src/util/stream_util.cpp 2013-03-20 21:54:22 +0000
@@ -53,5 +53,38 @@
///////////////////////////////////////////////////////////////////////////////
+ostream& roman( ostream &o, unsigned n ) {
+ //
+ // Based on http://rosettacode.org/wiki/Roman_numerals/Encode#C.2B.2B
+ //
+ struct roman_data {
+ unsigned value;
+ char const *numeral[2];
+ };
+ static roman_data const data[] = {
+ 1000, { "m", "M" },
+ 900, { "cm", "CM" },
+ 500, { "d", "D" },
+ 400, { "cd", "CD" },
+ 100, { "c", "C" },
+ 90, { "xc", "XC" },
+ 50, { "l", "L" },
+ 40, { "xl", "XL" },
+ 10, { "x", "X" },
+ 9, { "ix", "IX" },
+ 5, { "v", "V" },
+ 4, { "iv", "IV" },
+ 1, { "i", "I" },
+ 0, { 0, 0 }
+ };
+ bool const uc = !!(o.flags() & ios::uppercase);
+ for ( roman_data const *r = data; r->value > 0; ++r )
+ for ( ; n >= r->value; n -= r->value )
+ o << r->numeral[ uc ];
+ return o;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
} // namespace zorba
/* vim:set et sw=2 ts=2: */
=== modified file 'src/util/stream_util.h'
--- src/util/stream_util.h 2013-02-12 03:55:18 +0000
+++ src/util/stream_util.h 2013-03-20 21:54:22 +0000
@@ -20,6 +20,7 @@
#include <iostream>
+#include "omanip.h"
#include "string_util.h"
namespace zorba {
@@ -61,6 +62,21 @@
///////////////////////////////////////////////////////////////////////////////
+/**
+ * Emits an integer as Roman numerals to the given ostream. By default,
+ * numerals are emitted in lower-case. To emit in upper-case, set the
+ * \c uppercase format flag on the stream.
+ *
+ * @param o The ostream to emit to.
+ * @param n The integer to emit.
+ * @return Returns \a o.
+ */
+std::ostream& roman( std::ostream &o, unsigned n );
+
+DEF_OMANIP1( roman, unsigned )
+
+///////////////////////////////////////////////////////////////////////////////
+
} // namespace zorba
#endif /* ZORBA_STREAM_UTIL_H */
=== modified file 'src/util/time_util.cpp'
--- src/util/time_util.cpp 2013-02-13 01:57:47 +0000
+++ src/util/time_util.cpp 2013-03-20 21:54:22 +0000
@@ -16,7 +16,9 @@
#include "stdafx.h"
+#include <algorithm>
#include <cassert>
+#include <cstring>
#ifdef WIN32
# include <windows.h>
# include <time.h> /* for gmtime_s() */
@@ -33,11 +35,135 @@
// local
#include "time_util.h"
+#define DEF_END(CHAR_ARRAY) \
+ static char const *const *const end = \
+ CHAR_ARRAY + sizeof( CHAR_ARRAY ) / sizeof( char* )
+
+#define FIND(WHAT) \
+ static_cast<type>( find_index( string_of, end, WHAT ) )
+
+using namespace std;
+
+/**
+ * A less-verbose way to use std::lower_bound.
+ */
+inline int find_index( char const *const *begin, char const *const *end,
+ char const *s ) {
+ char const *const *const entry =
+ ::lower_bound( begin, end, s, less<char const*>() );
+ return entry != end && ::strcmp( s, *entry ) == 0 ? entry - begin : 0;
+}
+
namespace zorba {
namespace time {
///////////////////////////////////////////////////////////////////////////////
+namespace iso8601 {
+ /**
+ * Weekday values as used by the ISO 8601 specification.
+ */
+ enum weekday {
+ mon = 1,
+ tue = 2,
+ wed = 3,
+ thu = 4,
+ fri = 5,
+ sat = 6,
+ sun = 7
+ };
+}
+
+namespace calendar {
+
+char const *const string_of[] = {
+ "#UNKNOWN",
+ "AD", // Anno Domini (Christian Era)
+ "AH", // Anno Hegirae (Muhammedan Era)
+ "AM", // Anno Mundi (Jewish)
+ "AME", // Mauludi Era (solar years since Mohammed's birth)
+ "AP", // Anno Persici
+ "AS", // Aji Saka Era (Java)
+ "BE", // Buddhist Era
+ "CB", // Cooch Behar Era
+ "CE", // Common Era
+ "CL", // Chinese Lunar Era
+ "CS", // Chula Sakarat Era
+ "EE", // Ethiopian Era
+ "FE", // Fasli Era
+ "ISO", // ISO 8601 calendar
+ "JE", // Japanese
+ "KE", // Khalsa Era (Sikh calendar)
+ "KY", // Kali Yuga
+ "ME", // Malabar Era
+ "MS", // Monarchic Solar Era
+ "OS", // Old Style (Julian)
+ "RS", // Rattanakosin (Bangkok) Era
+ "SE", // Saka Era
+ "SH", // Mohammedan Solar Era (Iran)
+ "SS", // Saka Samvat
+ "TE", // Tripurabda Era
+ "VE", // Vikrama Era
+ "VS" // Vikrama Samvat Era
+};
+
+int calc_week_in_year( unsigned mday, unsigned mon, unsigned year, type cal ) {
+ int yday = time::calc_yday( mday, mon, year );
+ int jan1_wday = time::calc_wday( 1, time::jan, year );
+
+ switch ( cal ) {
+ case AD:
+ return (jan1_wday + yday) / 7 + 1;
+ case ISO: {
+ // Based on http://www.personal.ecu.edu/mccartyr/ISOwdALG.txt
+ ++yday; // code assumes [1-366]
+ jan1_wday = convert_wday_to( jan1_wday, cal );
+
+ if ( jan1_wday > iso8601::thu && jan1_wday + yday <= 8 ) {
+ // date falls in week 52 or 53 of the previous year
+ return 52
+ + (jan1_wday == iso8601::fri ||
+ (jan1_wday == iso8601::sat && time::is_leap_year( year - 1 )));
+ }
+ int const wday =
+ convert_wday_to( time::calc_wday( mday, mon, year ), cal );
+ if ( time::days_in_year( year ) - yday < 4 - wday ) {
+ // date falls in week 1 of the next year
+ return 1;
+ }
+ return (yday + (7 - wday) + (jan1_wday - 1)) / 7
+ - (jan1_wday > iso8601::thu);
+ }
+ default:
+ return -1;
+ }
+}
+
+int convert_wday_from( unsigned wday, type from ) {
+ switch ( from ) {
+ case AD : return static_cast<int>( wday );
+ case ISO: return wday == iso8601::sun ? time::sun : wday;
+ default : return -1;
+ }
+}
+
+int convert_wday_to( unsigned wday, type to ) {
+ switch ( to ) {
+ case AD : return static_cast<int>( wday );
+ case ISO: return wday == time::sun ? iso8601::sun : wday;
+ default : return -1;
+ }
+}
+
+type find( char const *calendar ) {
+ DEF_END( string_of );
+ return FIND( calendar );
+}
+
+} // namespace calendar
+
+///////////////////////////////////////////////////////////////////////////////
+
static unsigned const yday_mon[][13] = {
// 0 1 2 3 4 5 6 7 8 9 10 11 12
{ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }, // non-leap
@@ -48,7 +174,7 @@
bool calc_mday_mon( unsigned yday, unsigned *mday, unsigned *mon,
unsigned year ) {
- assert( yday < 365 + is_leap_year( year ) );
+ assert( yday < days_in_year( year ) );
unsigned const *const ym = yday_mon[ is_leap_year( year ) ];
for ( unsigned m = 1; m <= 12; ++m )
@@ -107,26 +233,26 @@
* @param year Year.
* @return Returns the weekday where 0 = Sunday.
*/
-unsigned calc_wday( unsigned mday, unsigned mon, unsigned year ) {
+int calc_wday( unsigned mday, unsigned mon, unsigned year ) {
assert( mday >= 1 );
assert( mday <= days_in_month( mon, year ) );
assert( mon < 12 );
++mon; // Tondering's algorithm assumes month value in range 1-12.
- unsigned const a = (14 - mon) / 12;
- unsigned const y = year - a;
- unsigned const m = mon + 12 * a - 2;
+ int const a = (14 - mon) / 12;
+ int const y = year - a;
+ int const m = mon + 12 * a - 2;
return (mday + y + y/4 - y/100 + y/400 + (31 * m) / 12) % 7;
}
-unsigned calc_yday( unsigned mday, unsigned mon, unsigned year ) {
+int calc_yday( unsigned mday, unsigned mon, unsigned year ) {
assert( mday >= 1 );
assert( mday <= days_in_month( mon, year ) );
- return yday_mon[ is_leap_year( year ) ][ mon ] + mday - 1;
+ return (int)yday_mon[ is_leap_year( year ) ][ mon ] + mday - 1;
}
-unsigned days_in_month( unsigned mon, unsigned year ) {
- static unsigned const days[] = {
+int days_in_month( unsigned mon, unsigned year ) {
+ static int const days[] = {
31, // 0: Jan
28, // 1: Feb
31, // 2: Mar
@@ -141,7 +267,7 @@
31 // 11: Dec
};
assert( mon < 12 );
- return days[ mon ] + (mon == 1 /* Feb */ && is_leap_year( year ));
+ return days[ mon ] + (mon == feb && is_leap_year( year ));
}
void get_epoch( sec_type *sec, usec_type *usec ) {
@@ -202,6 +328,17 @@
#endif /* WIN32 */
}
+char get_military_tz( int hour ) {
+ hour %= 24;
+ if ( hour > 12 )
+ hour -= 24;
+ else if ( hour < -12 )
+ hour += 24;
+ if ( hour >= 0 && hour <= 12 )
+ return "ZABCDEFGHIKLM" [ hour ]; // no 'J' here (it means "no timezone")
+ return " NOPQRSTUVWXY" [ -hour ];
+}
+
///////////////////////////////////////////////////////////////////////////////
} // namespace time
=== modified file 'src/util/time_util.h'
--- src/util/time_util.h 2013-02-13 01:57:47 +0000
+++ src/util/time_util.h 2013-03-20 21:54:22 +0000
@@ -25,7 +25,9 @@
// Zorba
#include <zorba/config.h>
+#include <zorba/time.h>
#include "cxx_util.h"
+#include "string_util.h"
#ifndef TM_YEAR_BASE
# define TM_YEAR_BASE 1900
@@ -36,14 +38,22 @@
///////////////////////////////////////////////////////////////////////////////
+/**
+ * A type to hold a number of seconds (at least since epoch).
+ */
typedef time_t sec_type;
+/**
+ * A type to hold a number of microseconds.
+ */
#ifdef WIN32
typedef unsigned long usec_type;
#else
typedef suseconds_t usec_type;
#endif /* WIN32 */
+///////////////////////////////////////////////////////////////////////////////
+
//
// If the OS's tm struct has a GMT-timezone offset field, simply typedef tm as
// ztm; otherwise declare ztm as a struct derived from tm that adds a
@@ -71,12 +81,129 @@
///////////////////////////////////////////////////////////////////////////////
/**
+ * XQuery 3.0 F&O: 9.8.4.3: The calendars listed below were known to be in use
+ * during the last hundred years.
+ */
+namespace calendar {
+ extern char const* const string_of[];
+
+ /**
+ * Emits a calendar::type to an ostream.
+ *
+ * @param o The ostream to emit to.
+ * @param t The type to emit.
+ * @return Returns \a o.
+ */
+ inline std::ostream& operator<<( std::ostream &o, type t ) {
+ return o << string_of[ t ];
+ }
+
+ /**
+ * Calculates the week number for the given date and calendar.
+ *
+ * @param mday The month day [1-31].
+ * @param mon The month [0-11].
+ * @param year The year.
+ * @param cal The calendar.
+ * @return Returns the week [1-53] or -1 if it is unknown how to perform the
+ * calculation for \a cal.
+ */
+ int calc_week_in_year( unsigned mday, unsigned mon, unsigned year, type cal );
+
+ /**
+ * Converts a weekday number from a given calendar to the Unix interpretation
+ * [0-6] where 0 = Sunday.
+ *
+ * @param wday The weekday to convert where the meaning of the value is
+ * determined by \a from.
+ * @param from The calendar designator to convert \a wday from.
+ * @return Returns \a wday converted to \a to or -1 if it is unknown how to
+ * perform the conversion.
+ */
+ int convert_wday_from( unsigned wday, type from );
+
+ /**
+ * Converts a Unix weekday number to a specific calendar.
+ *
+ * @param wday The weekday to convert: [0-6] where 0 = Sunday.
+ * @param to The calendar designator to convert \a wday to.
+ * @return Returns \a wday converted to \a to or -1 if it is unknown how to
+ * perform the conversion.
+ */
+ int convert_wday_to( unsigned wday, type to );
+
+ /**
+ * Finds a calendar designator from the given string.
+ *
+ * @param calendar The calendar designator to find. It is presumed to be in
+ * upper-case.
+ * @return Returns said enumeration or \c unknown.
+ */
+ type find( char const *calendar );
+
+ //
+ // Template version of find().
+ //
+ template<class StringType> inline
+ typename std::enable_if<
+ ztd::has_c_str<StringType,char const* (StringType::*)() const>::value,
+ type
+ >::type
+ find( StringType const &country ) {
+ return find( country.c_str() );
+ }
+
+ /**
+ * Gets the default calendar to use.
+ *
+ * @return Returns said calendar.
+ */
+ inline type get_default() {
+ return AD; // i.e., the Gregorian calendar
+ }
+
+} // namespace calendar
+
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Month (<code>mod</code>) values as used by the \c tm structure.
+ */
+enum month {
+ jan = 0,
+ feb = 1,
+ mar = 2,
+ apr = 3,
+ may = 4,
+ jun = 5,
+ jul = 6,
+ aug = 7,
+ sep = 8,
+ oct = 9,
+ nov = 10,
+ dec = 11
+};
+
+/**
+ * Weekday (<code>wday</code>) values as used by the \c tm structure.
+ */
+enum weekday {
+ sun = 0,
+ mon = 1,
+ tue = 2,
+ wed = 3,
+ thu = 4,
+ fri = 5,
+ sat = 6
+};
+
+/**
* Calculates the day of the month and month from the given day of the year.
*
- * @param yday The year day (0-365) where 0 = January 1.
- * @param mday A pointer to the result for the month day (1-31) or \c null if
+ * @param yday The year day [0-365] where 0 = January 1.
+ * @param mday A pointer to the result for the month day [1-31] or \c null if
* this is not desired.
- * @param mon A pointer to the result for the month (0-11) or \c null if this
+ * @param mon A pointer to the result for the month [0-11] or \c null if this
* is not desired.
* @param year The year.
* @return Returns \c true if \a yday and \a year are a valid combination and
@@ -88,31 +215,31 @@
/**
* Calculates the weekday for the given date.
*
- * @param mday The month day (1-31).
- * @param mon The month (0-11).
+ * @param mday The month day [1-31].
+ * @param mon The month [0-11].
* @param year The year.
- * @return Returns the weekday (0-6) where 0 = Sunday.
+ * @return Returns the weekday [0-6] where 0 = Sunday.
*/
-unsigned calc_wday( unsigned mday, unsigned mon, unsigned year );
+int calc_wday( unsigned mday, unsigned mon, unsigned year );
/**
* Calculates the day of the year for the given date.
*
- * @param mday The month day (1-31).
- * @param mon The month (0-11).
+ * @param mday The month day [1-31].
+ * @param mon The month [0-11].
* @param year The year.
- * @return Returns the day of the year (0-365) where 0 = January 1.
+ * @return Returns the day of the year [0-365] where 0 = January 1.
*/
-unsigned calc_yday( unsigned mday, unsigned mon, unsigned year );
+int calc_yday( unsigned mday, unsigned mon, unsigned year );
/**
* Gets the number of days in the given month.
*
- * @param mon The month (0-11).
+ * @param mon The month [0-11].
* @param year The year.
- * @return Returns said number of days (1-31).
+ * @return Returns said number of days, one of: 28, 29, 30, or 31.
*/
-unsigned days_in_month( unsigned mon, unsigned year );
+int days_in_month( unsigned mon, unsigned year );
/**
* Gets the number of seconds and microseconds since epoch.
@@ -150,6 +277,14 @@
void get_localtime( ztm *tm, sec_type when = 0 );
/**
+ * Gets the military timezone letter code for the given GMT hour offset.
+ *
+ * @param hour The number of hours offset from GMT.
+ * @return Returns one of ABCDEFGHIKLMNOPQRSTUVWXYZ (no J).
+ */
+char get_military_tz( int hour );
+
+/**
* Checks whether the given year is a leap year.
*
* @param year The year to check.
@@ -160,10 +295,20 @@
}
/**
+ * Gets the number of days in the given year.
+ *
+ * @param year The year.
+ * @return Returns said number of days, either: 365 or 366.
+ */
+inline int days_in_year( unsigned year ) {
+ return 365 + is_leap_year( year );
+}
+
+/**
* Checks whether the given day of the month is valid.
*
- * @param mday The month day (1-31).
- * @param mon The month (0-11).
+ * @param mday The month day [1-31].
+ * @param mon The month [0-11].
* @param year The year.
* @return Returns \a true only if the given day of the month is valid.
*/
@@ -174,9 +319,9 @@
/**
* Checks whether the given weekday is valid.
*
- * @param wday The weekday (0-6) where 0 = Sunday.
- * @param mday The month day (1-31).
- * @param mon The month (0-11).
+ * @param wday The weekday [0-6] where 0 = Sunday.
+ * @param mday The month day [1-31].
+ * @param mon The month [0-11].
* @param year The year.
* @return Returns \a true only if the given weekday is valid.
*/
@@ -188,9 +333,9 @@
/**
* Checks whether the given day of the year is valid.
*
- * @param yday The day of the year (0-365).
- * @param mday The month day (1-31).
- * @param mon The month (0-11).
+ * @param yday The day of the year [0-365].
+ * @param mday The month day [1-31].
+ * @param mon The month [0-11].
* @param year The year.
* @return Returns \a true only if the given day of the year is valid.
*/
=== modified file 'src/util/unicode_util.cpp'
--- src/util/unicode_util.cpp 2013-02-07 17:24:36 +0000
+++ src/util/unicode_util.cpp 2013-03-20 21:54:22 +0000
@@ -28,6 +28,7 @@
# include <unicode/ustring.h>
#endif /* ZORBA_NO_ICU */
+#include "ascii_util.h"
#include "cxx_util.h"
#include "unicode_util.h"
#include "utf8_util.h"
@@ -2205,6 +2206,23 @@
return is_case<upper>( c );
}
+ostream& printable_cp( ostream &o, code_point cp ) {
+ if ( ascii::is_print( cp ) )
+ o << static_cast<char>( cp );
+ else
+ switch ( cp ) {
+ case '\n': o << "\\n"; break;
+ case '\r': o << "\\r"; break;
+ case '\t': o << "\\t"; break;
+ default: {
+ ios::fmtflags const old_flags = o.flags();
+ o << "#x" << uppercase << hex << static_cast<uint32_t>( cp );
+ o.flags( old_flags );
+ }
+ }
+ return o;
+}
+
code_point to_lower( code_point c ) {
return to_case<lower>( c );
}
=== modified file 'src/util/unicode_util.h'
--- src/util/unicode_util.h 2013-02-28 11:15:32 +0000
+++ src/util/unicode_util.h 2013-03-20 21:54:22 +0000
@@ -32,6 +32,7 @@
# include <unicode/unistr.h>
#endif /* ZORBA_NO_ICU */
+#include "omanip.h"
#include "stl_util.h"
namespace zorba {
@@ -426,6 +427,22 @@
return c >= 0x10000 && c <= 0x10FFFF;
}
+////////// Miscellaneous //////////////////////////////////////////////////////
+
+/**
+ * Prints the given code-point in a printable way: if \c ascii::is_print(c) is
+ * \c true, prints \a c as-is; otherwise prints \c #x followed by the
+ * hexadecimal value of the character.
+ *
+ * @param o The ostream to print to.
+ * @param cp The \c code-point to print.
+ * @return Returns \a o.
+ */
+std::ostream& printable_cp( std::ostream &o, code_point cp );
+
+// An ostream manipulator version of the above.
+DEF_OMANIP1( printable_cp, code_point )
+
///////////////////////////////////////////////////////////////////////////////
} // namespace unicode
=== modified file 'src/util/utf8_string.h'
--- src/util/utf8_string.h 2013-02-07 17:24:36 +0000
+++ src/util/utf8_string.h 2013-03-20 21:54:22 +0000
@@ -207,8 +207,12 @@
typedef typename StringType::const_pointer const_storage_pointer;
typedef typename StringType::reference storage_reference;
typedef typename StringType::const_reference const_storage_reference;
+
typedef typename StringType::iterator storage_iterator;
typedef typename StringType::const_iterator const_storage_iterator;
+ typedef typename StringType::reverse_iterator storage_reverse_iterator;
+ typedef typename StringType::const_reverse_iterator
+ const_storage_reverse_iterator;
typedef typename utf8::iterator<storage_iterator> iterator;
typedef typename utf8::iterator<const_storage_iterator> const_iterator;
@@ -1005,6 +1009,16 @@
}
/**
+ * Returns a read-only iterator positioned at the same byte as the given
+ * iterator of the string.
+ *
+ * @return Returns said iterator.
+ */
+ const_iterator current( const_storage_iterator const &i ) const {
+ return const_iterator( i );
+ }
+
+ /**
* Returns a read-only reverse iterator positioned at the first character
* (not byte) of the string.
*
@@ -1024,6 +1038,17 @@
return const_reverse_iterator( begin() );
}
+ /**
+ * Returns a read-only reverse iterator positioned at the same byte as the
+ * given reverse iterator of the string.
+ *
+ * @return Returns said iterator.
+ */
+ const_reverse_iterator
+ current( const_storage_reverse_iterator const &i ) const {
+ return const_reverse_iterator( i );
+ }
+
////////// miscellaneous ////////////////////////////////////////////////////
/**
=== modified file 'src/util/utf8_util.cpp'
--- src/util/utf8_util.cpp 2013-02-07 17:24:36 +0000
+++ src/util/utf8_util.cpp 2013-03-20 21:54:22 +0000
@@ -15,6 +15,9 @@
*/
#include "stdafx.h"
+#include <algorithm>
+#include <cstring>
+
#ifndef ZORBA_NO_ICU
#include <unicode/ustring.h>
#endif /* ZORBA_NO_ICU */
@@ -144,6 +147,35 @@
return len;
}
+storage_type* itou( unsigned long long n, storage_type *buf,
+ unicode::code_point zero ) {
+ storage_type *s = buf;
+ encoded_char_type utf8_digit[10]; // cache of UTF-8 bytes for each digit
+ size_type utf8_size[10]; // number of UTF-8 bytes for each digit
+
+ std::fill( utf8_size, utf8_size + 10, 0 );
+ do {
+ unsigned long long const n_prev = n;
+ n /= 10;
+ unsigned const digit = n_prev - n * 10;
+ if ( !utf8_size[ digit ] ) // didn't cache previously: cache now
+ utf8_size[ digit ] = encode( zero + digit, utf8_digit[ digit ] );
+ //
+ // Copy the UTF-8 bytes into buf backwards so when we reverse the entire
+ // buffer later (to reverse the digit order to put them the right way
+ // around), we can treat buf as a simple string and ignore multi-byte UTF-8
+ // character boundaries.
+ //
+ for ( size_type i = utf8_size[ digit ]; i; )
+ *s++ = utf8_digit[ digit ][ --i ];
+
+ } while ( n );
+
+ *s = '\0';
+ std::reverse( buf, s );
+ return buf;
+}
+
size_type length( storage_type const *begin, storage_type const *end ) {
size_type len = 0;
while ( begin < end && *begin ) {
=== modified file 'src/util/utf8_util.h'
--- src/util/utf8_util.h 2013-02-07 17:24:36 +0000
+++ src/util/utf8_util.h 2013-03-20 21:54:22 +0000
@@ -306,6 +306,31 @@
std::copy( u.begin(), u.end(), std::back_inserter( *c ) );
}
+////////// Integer-to-string conversion ///////////////////////////////////////
+
+/**
+ * A type that can hold the largest possible C string equivalent of the largest
+ * possible integral value using any Unicode numeric range within the Nd
+ * ("Number, Decimal Digit") category.
+ */
+typedef storage_type itou_buf_type[
+ (sizeof( encoded_char_type ) - 1 /* subtract null */) * 20 + 1 /* add null */
+];
+
+/**
+ * Converts an <code>unsigned long long</code> to a UTF-8 encoded string.
+ *
+ * @param n The <code>unsigned long long</code> to convert.
+ * @param buf The buffer for the result. The caller must ensure it's of
+ * sufficient size.
+ * @param zero The Unicode code-point of the zero at the start of a 10
+ * code-point range [zero,zero+9] for the digits to use in the Nd ("Number,
+ * Decimal Digit") category.
+ * @return Returns \a buf for convenience.
+ */
+storage_type* itou( unsigned long long n, storage_type *buf,
+ unicode::code_point zero );
+
////////// Encoding conversion ////////////////////////////////////////////////
#ifndef ZORBA_NO_ICU
@@ -737,6 +762,48 @@
////////// Miscellaneous //////////////////////////////////////////////////////
/**
+ * Pads a string to the left with a given code-point until the string is the
+ * given width.
+ *
+ * @param s The string to pad.
+ * @param width The width to pad to.
+ * @param cp The code-point to pad with.
+ * @return Returns \c *s.
+ */
+template<class StringType> inline
+StringType& left_pad( StringType *s, typename StringType::size_type width,
+ unicode::code_point cp ) {
+ typedef typename utf8_stringify<StringType>::type u_type;
+ typedef typename u_type::size_type u_size_type;
+ u_type u( *s );
+ u_size_type const u_size( u.size() );
+ if ( u_size < width )
+ u.insert( static_cast<size_type>( 0 ), width - u_size, cp );
+ return *s;
+}
+
+/**
+ * Pads a string to the right with a given code-point until the string is the
+ * given width.
+ *
+ * @param s The string to pad.
+ * @param width The width to pad to.
+ * @param cp The code-point to pad with.
+ * @return Returns \c *s.
+ */
+template<class StringType> inline
+StringType& right_pad( StringType *s, typename StringType::size_type width,
+ unicode::code_point cp ) {
+ typedef typename utf8_stringify<StringType>::type u_type;
+ typedef typename u_type::size_type u_size_type;
+ u_type u( *s );
+ u_size_type const u_size( u.size() );
+ if ( u_size < width )
+ u.append( width - u_size, cp );
+ return *s;
+}
+
+/**
* Reverses the characters in a string.
*
* @tparam InputStringType The input string type.
=== modified file 'src/zorbatypes/datetime.h'
--- src/zorbatypes/datetime.h 2013-03-12 17:03:31 +0000
+++ src/zorbatypes/datetime.h 2013-03-20 21:54:22 +0000
@@ -250,16 +250,10 @@
*/
static int parseGDay(const char* str, ascii::size_type strlen, DateTime& dt);
- static int getDayOfWeek(int year, int month, int day);
-
static int getDayOfYear(int year, int month, int day);
- static int getWeekInYear(int year, int month, int day);
-
static int getWeekInMonth(int year, int month, int day);
- static bool isLeapYear(int year);
-
protected:
static int parse_date(
const char* str,
@@ -361,11 +355,8 @@
* with the index being 0 based, with 0 being Sunday, 1 Monday, etc. If the give
* DateTime does not have a Date or DateTime facet, the function will return -1.
*/
- int getDayOfWeek() const;
int getDayOfYear() const;
- int getWeekInYear() const;
int getWeekInMonth() const;
- bool isLeapYear() const;
protected:
Duration* toDayTimeDuration() const;
=== modified file 'src/zorbatypes/datetime/datetimetype.cpp'
--- src/zorbatypes/datetime/datetimetype.cpp 2013-03-12 17:03:31 +0000
+++ src/zorbatypes/datetime/datetimetype.cpp 2013-03-20 21:54:22 +0000
@@ -39,6 +39,7 @@
#include "zorbatypes/datetime/parse.h"
#include "util/ascii_util.h"
+#include "util/time_util.h"
namespace zorba
@@ -47,7 +48,7 @@
static const char separators[] = { '-', '-', 'T', ':', ':', '.'};
static const char min_length[] = { 4, 2, 2, 2, 2, 2, 0};
-
+
const int DateTime::FACET_MEMBERS[][8] =
{
@@ -79,7 +80,7 @@
for (int i = YEAR_DATA; i <= DAY_DATA; i++)
data[i] = 1;
-
+
for (int i = HOUR_DATA; i <= FRACSECONDS_DATA; i++)
data[i] = 0;
@@ -158,10 +159,10 @@
dt.data[MINUTE_DATA] = std::abs(minutes);
dt.data[SECONDS_DATA] = std::floor(std::fabs(seconds));
dt.data[FRACSECONDS_DATA] = round(frac(std::fabs(seconds)) * FRAC_SECONDS_UPPER_LIMIT);
-
+
if (tz != NULL)
dt.the_time_zone = *tz;
-
+
return 0;
}
@@ -185,7 +186,7 @@
dt.data[MINUTE_DATA] = std::abs(minutes);
dt.data[SECONDS_DATA] = std::abs(seconds);
dt.data[FRACSECONDS_DATA] = std::abs(fractional_seconds);
-
+
if (tz != NULL)
dt.the_time_zone = *tz;
@@ -211,7 +212,7 @@
if (tz != NULL)
dt.the_time_zone = *tz;
-
+
return 0;
}
@@ -231,10 +232,10 @@
dt.data[MINUTE_DATA] = std::abs(minutes);
dt.data[SECONDS_DATA] = std::floor(std::fabs(seconds));
dt.data[FRACSECONDS_DATA] = round(frac(std::fabs(seconds)) * FRAC_SECONDS_UPPER_LIMIT);
-
+
if (tz != NULL)
dt.the_time_zone = *tz;
-
+
return 0;
}
@@ -352,7 +353,7 @@
ascii::skip_whitespace(str, len, &pos);
dt.facet = DATETIME_FACET;
-
+
if (parse_date(str,
len,
pos,
@@ -363,7 +364,7 @@
if (pos == len || str[pos++] != 'T')
return 1;
-
+
if (parse_time(str,
len,
pos,
@@ -372,7 +373,7 @@
dt.data[SECONDS_DATA],
dt.data[FRACSECONDS_DATA]))
return 1;
-
+
ascii::size_type savepos = pos;
ascii::skip_whitespace(str, len, &pos);
@@ -387,7 +388,7 @@
dt.the_time_zone))
return 1;
}
-
+
if (dt.data[HOUR_DATA] == 24)
{
dt.data[HOUR_DATA] = 0;
@@ -408,7 +409,7 @@
ascii::skip_whitespace(str, len, &pos);
dt.facet = DATE_FACET;
-
+
if (parse_date(str,
len,
pos,
@@ -429,7 +430,7 @@
if (0 != TimeZone::parseTimeZone(str + pos, len - pos, dt.the_time_zone))
return 1;
}
-
+
return 0;
}
@@ -441,14 +442,14 @@
ascii::skip_whitespace(str, len, &pos);
dt.facet = TIME_FACET;
-
+
if (parse_time(str, len, pos,
dt.data[HOUR_DATA],
dt.data[MINUTE_DATA],
dt.data[SECONDS_DATA],
dt.data[FRACSECONDS_DATA]))
return 1;
-
+
ascii::size_type savepos = pos;
ascii::skip_whitespace(str, len, &pos);
@@ -461,7 +462,7 @@
if (0 != TimeZone::parseTimeZone(str + pos, len - pos, dt.the_time_zone))
return 1;
}
-
+
if (dt.data[HOUR_DATA] == 24)
dt.data[HOUR_DATA] = 0;
@@ -476,11 +477,11 @@
zstring temp;
// GYearMonth of form: '-'? yyyy '-' mm zzzzzz?
-
+
ascii::skip_whitespace(str, len, &pos);
dt.facet = GYEARMONTH_FACET;
-
+
if (str[pos] == '-')
{
temp.append(str + pos, (8 < len - pos ? 8 : len - pos));
@@ -500,7 +501,7 @@
dt.data[MONTH_DATA],
dt.data[DAY_DATA]))
return 1;
-
+
pos += 7;
ascii::size_type savepos = pos;
@@ -527,11 +528,11 @@
zstring temp;
// GYear of form: '-'? yyyy zzzzzz?
-
+
ascii::skip_whitespace(str, len, &pos);
dt.facet = GYEAR_FACET;
-
+
temp.reserve(12);
if (str[pos] == '-')
@@ -553,7 +554,7 @@
dt.data[MONTH_DATA],
dt.data[DAY_DATA]))
return 1;
-
+
pos += 4;
ascii::size_type savepos = pos;
@@ -581,11 +582,11 @@
// GMonth of form: --MM zzzzzz?
// preceding - is not allowed.
-
+
ascii::skip_whitespace(str, len, &pos);
dt.facet = GMONTH_FACET;
-
+
if (str[pos++] != '-')
return 1;
@@ -601,7 +602,7 @@
dt.data[MONTH_DATA],
dt.data[DAY_DATA]))
return 1;
-
+
pos += 3;
ascii::size_type savepos = pos;
@@ -633,10 +634,10 @@
ascii::skip_whitespace(str, len, &pos);
dt.facet = GMONTHDAY_FACET;
-
+
if (str[pos++] != '-')
return 1;
-
+
temp.reserve(12);
temp = "0004";
temp.append(str + pos, 6); // Year 4 to make it a leap year, to allow the MonthDay of 29 February
@@ -650,7 +651,7 @@
return 1;
dt.data[YEAR_DATA] = 1;
-
+
pos += 6;
ascii::size_type savepos = pos;
@@ -678,17 +679,17 @@
// GDay of form: ---DD zzzzzz?
// preceding - is not allowed.
-
+
ascii::skip_whitespace(str, len, &pos);
dt.facet = GDAY_FACET;
-
- if (str[pos++] != '-')
- return 1;
-
- if (str[pos++] != '-')
- return 1;
-
+
+ if (str[pos++] != '-')
+ return 1;
+
+ if (str[pos++] != '-')
+ return 1;
+
temp = "0001-01";
temp.append(str + pos, 3);
@@ -699,7 +700,7 @@
dt.data[MONTH_DATA],
dt.data[DAY_DATA]))
return 1;
-
+
pos += 3;
ascii::size_type savepos = pos;
@@ -730,7 +731,7 @@
{
bool is_negative = false;
ascii::size_type temp_pos;
-
+
if (pos == len)
return 1;
@@ -765,18 +766,18 @@
// Parse day
if (pos == len || parse_long(str, len, pos, day, 2, 2))
return 1;
-
+
// Validate the date
// year may not be 0
if (year == 0)
return 1;
-
+
if (month < 1 || month > 12)
return 1;
if (day < 1 || day > get_last_day(year, month))
return 1;
-
+
return 0;
}
@@ -793,7 +794,7 @@
{
if (position == len)
return 1;
-
+
// Parse hour
if (position == len || parse_long(str, len, position, hour, 2, 2))
return 1;
@@ -811,7 +812,7 @@
// Parse seconds
if (position == len || parse_long(str, len, position, seconds, 2, 2))
return 1;
-
+
if (position < len && str[position] == '.')
{
double temp_frac_seconds;
@@ -830,19 +831,19 @@
// Validate the time
if (hour > 24)
return 1;
-
+
if (minute > 59)
return 1;
if (hour == 24 && minute != 0)
return 1;
-
+
if (seconds > 59)
return 1;
if (hour == 24 && (seconds != 0 || frac_seconds != 0))
return 1;
-
+
return 0;
}
@@ -871,18 +872,18 @@
zstring DateTime::toString() const
{
zstring result;
-
+
// output sign
if (FACET_MEMBERS[facet][0])
if (data[YEAR_DATA] < 0)
result.append("-", 1);
-
+
// output preceding '-' for Gregorian dates, when needed
if (facet == GMONTH_FACET || facet == GMONTHDAY_FACET)
result.append("--", 2);
if (facet == GDAY_FACET)
result.append("---", 3);
-
+
for (int i=0; i<=5; i++)
{
if (FACET_MEMBERS[facet][i])
@@ -892,12 +893,12 @@
result.push_back(separators[i]);
}
}
-
+
if (FACET_MEMBERS[facet][FRACSECONDS_DATA] && (data[FRACSECONDS_DATA] != 0))
{
int temp;
result.append(".", 1);
-
+
// print leading 0s, if any
temp = FRAC_SECONDS_UPPER_LIMIT / 10;
while (temp > data[FRACSECONDS_DATA] && temp > 0)
@@ -905,17 +906,17 @@
result.append("0", 1);
temp /= 10;
}
-
+
// strip trailing 0s, if any
temp = data[FRACSECONDS_DATA];
while (temp%10 == 0 && temp > 0)
temp = temp / 10;
-
+
result.append(ztd::to_string(temp));
}
-
+
result.append(the_time_zone.toString());
-
+
return result;
}
@@ -984,7 +985,7 @@
assert(data[SECONDS_DATA] >= 0);
return data[SECONDS_DATA];
}
-
+
int DateTime::getFractionalSeconds() const
{
@@ -1003,21 +1004,21 @@
{
return !the_time_zone.timeZoneNotSet();
}
-
-
+
+
int DateTime::compare(const DateTime* dt, long timezone_seconds) const
{
std::auto_ptr<DateTime> d1_t;
std::auto_ptr<DateTime> d2_t;
-
+
d1_t.reset(normalizeTimeZone(timezone_seconds));
d2_t.reset(dt->normalizeTimeZone(timezone_seconds));
-
+
if (d1_t->data[YEAR_DATA] < d2_t->data[YEAR_DATA])
return -1;
else if (d1_t->data[YEAR_DATA] > d2_t->data[YEAR_DATA])
return 1;
-
+
// compare the rest of the data
if (d1_t->data[YEAR_DATA] < 0 && d2_t->data[YEAR_DATA] < 0)
{
@@ -1039,7 +1040,7 @@
return 1;
}
}
-
+
return 0;
}
@@ -1048,7 +1049,7 @@
{
uint32_t hval = 0;
std::auto_ptr<DateTime> dt(normalizeTimeZone(implicit_timezone_seconds));
-
+
hval = hashfun::h32<int>((int)dt->facet, hval);
hval = hashfun::h32<int>(dt->data[YEAR_DATA], hval);
hval = hashfun::h32<int>(dt->data[MONTH_DATA], hval);
@@ -1057,9 +1058,9 @@
hval = hashfun::h32<int>(dt->data[MINUTE_DATA], hval);
hval = hashfun::h32<int>(dt->data[SECONDS_DATA], hval);
hval = hashfun::h32<int>(dt->data[FRACSECONDS_DATA], hval);
-
+
hval = dt->the_time_zone.hash(hval);
-
+
return hval;
}
@@ -1086,13 +1087,13 @@
data[MONTH_DATA],
data[DAY_DATA])-1,
0, 0, 0, 0);
-
+
Duration remainder(Duration::DAYTIMEDURATION_FACET, false, 0, 0, 0,
data[HOUR_DATA],
data[MINUTE_DATA],
data[SECONDS_DATA],
data[FRACSECONDS_DATA]);
-
+
return days + remainder;
}
}
@@ -1106,7 +1107,7 @@
// For the algorithm, see XML Schema 2 spec, Appendix E
// http://www.w3.org/TR/xmlschema-2/#adding-durations-to-dateTimes
-
+
months = modulo<int>(data[MONTH_DATA] + d.getMonths() - 1, 12) + 1;
years = data[YEAR_DATA] + d.getYears() +
@@ -1118,7 +1119,7 @@
int_seconds = modulo<int>(total_seconds, 60);
frac_seconds = modulo<int>(temp_frac_seconds, DateTime::FRAC_SECONDS_UPPER_LIMIT);
-
+
minutes = data[MINUTE_DATA] + d.getMinutes() + quotient<int>(total_seconds, 60);
hours = data[HOUR_DATA] + d.getHours() + quotient<int>(minutes, 60);
@@ -1155,7 +1156,7 @@
years += quotient<int>(months + carry-1, 12);
months = modulo<int>(months + carry -1, 12) + 1;
}
-
+
if (data[YEAR_DATA] > 0 && d.isNegative() && years <= 0)
years--;
if (data[YEAR_DATA] < 0 && !d.isNegative() && years >= 0)
@@ -1167,7 +1168,7 @@
int_seconds, frac_seconds, &the_time_zone,
*new_dt))
assert(0);
-
+
new_dt->facet = facet;
if (adjust_facet)
new_dt->adjustToFacet();
@@ -1199,13 +1200,13 @@
{
DateTime* dt;
Duration d;
-
+
if( the_time_zone.timeZoneNotSet() )
{
// validate timezone value (-14 .. +14 H)
if (tz_seconds > 14*3600 || tz_seconds < -14*3600)
throw InvalidTimezoneException( tz_seconds );
-
+
d = Duration(Duration::DAYTIMEDURATION_FACET,
(tz_seconds < 0), 0, 0, 0, 0, 0, tz_seconds, 0);
}
@@ -1214,10 +1215,10 @@
if (0 != Duration::fromTimezone(the_time_zone, d))
assert(0);
}
-
+
dt = subtractDuration(d, false); // do not adjust to facet
dt->the_time_zone = TimeZone(0);
-
+
return dt;
}
@@ -1227,7 +1228,7 @@
std::auto_ptr<Duration> dtduration;
std::auto_ptr<Duration> context_tz;
std::auto_ptr<DateTime> dt;
-
+
// validate timezone value (-14 .. +14 H)
if (tz_seconds > 14*3600 || tz_seconds < -14*3600)
throw InvalidTimezoneException( tz_seconds );
@@ -1236,7 +1237,7 @@
context_tz = std::auto_ptr<Duration>(new Duration(Duration::DAYTIMEDURATION_FACET, (tz_seconds<0), 0, 0, 0, 0, 0, tz_seconds, 0));
dt = std::auto_ptr<DateTime>(new DateTime(*this));
-
+
// If $arg does not have a timezone component and $timezone is not the empty sequence,
// then the result is $arg with $timezone as the timezone component.
if (the_time_zone.timeZoneNotSet())
@@ -1274,9 +1275,9 @@
// A dynamic error is raised [err:FODT0003] if $timezone is less than -PT14H
// or greater than PT14H or if does not contain an integral number of minutes.
-
+
dt = std::auto_ptr<DateTime>(new DateTime(*this));
-
+
if (d == NULL)
{
if (!the_time_zone.timeZoneNotSet())
@@ -1291,7 +1292,7 @@
d->getHours()*3600 + d->getMinutes()*60 > 14*3600 ||
d->getHours()*3600 + d->getMinutes()*60 < -14*3600)
throw InvalidTimezoneException( d->getHours()*3600 + d->getMinutes()*60 );
-
+
// If $arg does not have a timezone component and $timezone is not the
// empty sequence, then the result is $arg with $timezone as the timezone
// component.
@@ -1385,79 +1386,18 @@
}
-int DateTime::getDayOfWeek(int year, int month, int day)
-{
- if (month < 3)
- {
- month = month + 12;
- year = year - 1;
- }
-
- return (day
- + (2 * month)
- + int(6 * (month + 1) / 10)
- + year
- + int(year / 4)
- - int(year / 100)
- + int(year / 400)
- + 1 // CalendarSystem, 1 for Gregorian
- ) % 7;
-}
-
-
-int DateTime::getWeekInYear(int year, int month, int day)
-{
- int day_of_year = DateTime::getDayOfYear(year, month, day);
- int year_first_day_of_week = DateTime::getDayOfWeek(year, 1, 1);
-
- if (year_first_day_of_week > 4 && (year_first_day_of_week + day_of_year) <= 8)
- return getWeekInYear(year-1, 12, 31);
-
- return ((day_of_year + year_first_day_of_week - 2) / 7) + year_first_day_of_week < 5 ? 1 : 0;
-}
-
-
int DateTime::getDayOfYear(int year, int month, int day)
{
- static const int days[] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365};
-
if (month > 12)
return -1;
-
- if (isLeapYear(year) && month >= 3)
- day++;
-
- return days[month-1] + day;
-}
-
-
-bool DateTime::isLeapYear(int year)
-{
- if (((year%4 == 0) && (year%100 != 0))
- ||
- (year%400 == 0))
- return true;
- else
- return false;
+ return time::calc_yday( day, month, year );
}
int DateTime::getWeekInMonth(int year, int month, int day)
{
- int first_day_of_week = DateTime::getDayOfWeek(year, month, 1);
- return ((day + first_day_of_week - 2) / 7) + (first_day_of_week < 5 ? 1 : 0);
-}
-
-
-bool DateTime::isLeapYear() const
-{
- return isLeapYear(data[YEAR_DATA]);
-}
-
-
-int DateTime::getDayOfWeek() const
-{
- return getDayOfWeek(data[YEAR_DATA], data[MONTH_DATA], data[DAY_DATA]);
+ int const wday = time::calc_wday(1, month-1, year);
+ return ((day + wday - 2) / 7) + (wday < 5 ? 1 : 0);
}
@@ -1467,12 +1407,6 @@
}
-int DateTime::getWeekInYear() const
-{
- return getWeekInYear(data[YEAR_DATA], data[MONTH_DATA], data[DAY_DATA]);
-}
-
-
int DateTime::getWeekInMonth() const
{
return getWeekInMonth(data[YEAR_DATA], data[MONTH_DATA], data[DAY_DATA]);
=== modified file 'src/zorbautils/locale.cpp'
--- src/zorbautils/locale.cpp 2013-03-18 05:13:50 +0000
+++ src/zorbautils/locale.cpp 2013-03-20 21:54:22 +0000
@@ -169,6 +169,8 @@
LPCWSTR wlocale_name;
unique_ptr<WCHAR[]> wlocale_name_ptr;
+ if ( !country )
+ country = iso3166_1::get_default( lang );
if ( lang && country ) {
wlocale_name_ptr = get_wlocale_name( lang, country );
wlocale_name = wlocale_name_ptr.get();
@@ -278,6 +280,8 @@
static zstring get_locale_info( nl_item item, iso639_1::type lang,
iso3166_1::type country ) {
if ( lang ) {
+ if ( !country )
+ country = iso3166_1::get_default( lang );
if ( locale_t const loc = get_unix_locale_t( lang, country ) ) {
char const *const info = nl_langinfo_l( item, loc );
::freelocale( loc );
@@ -549,6 +553,205 @@
return FIND( country );
}
+type get_default( iso639_1::type lang ) {
+ //
+ // In cases where a language maps to multiple countries, if the language is
+ // the official language of a single country, that country is the one the
+ // language is mapped to.
+ //
+ static type const lang_to_country[] = {
+ unknown,
+ DJ , // aa: Afar => Djibouti
+ GE , // ab: Abkhazian => Georgia
+ IR , // ae: Avestan => Iran
+ ZA , // af: Afrikaans => South Africa
+ GH , // ak: Akan => Ghana
+ ET , // am: Amharic => Ethiopia
+ ES , // an: Aragonese => Spain
+ unknown, // ar: Arabic => (maps to multiple countries)
+ IN_ , // as: Assamese => India
+ AZ , // av: Avaric => Azerbaijan
+ BO , // ay: Aymara => Bolivia
+ AZ , // az: Azerbaijani => Azerbaijan
+ RU , // ba: Bashkir => Russian Federation
+ RU , // be: Byelorussian => Russian Federation
+ BG , // bg: Bulgarian => Bulgaria
+ IN_ , // bh: Bihari => India
+ VU , // bi: Bislama => Vanuatu
+ ML , // bm: Bambara => Mali
+ BD , // bn: Bengali; Bangla => Bangladesh
+ CN , // bo: Tibetan => China
+ FR , // br: Breton => France
+ BA , // bs: Bosnian => Bosnia
+ AD , // ca: Catalan => Andorra
+ RU , // ce: Chechen => Russian Federation
+ MP , // ch: Chamorro => Northern Mariana Islands
+ FR , // co: Corsican => France
+ US , // cr: Cree => United States
+ CZ , // cs: Czech => Czech Republic
+ RU , // cu: Church Slavic; Church Slavonic => Russian Federation
+ RU , // cv: Chuvash => Russian Federation
+ GB , // cy: Welsh => United Kingdom
+ DK , // da: Danish => Denmark
+ DE , // de: German => Germany
+ MV , // dv: Divehi => Maldives
+ PK , // dz: Bhutani => Pakistan
+ unknown, // ee: Ewe => (maps to multiple countries)
+ GR , // el: Greek => Greece
+ GB , // en: English => United Kingdom
+ unknown, // eo: Esperanto => (constructed language)
+ ES , // es: Spanish => Spain
+ EE , // et: Estonian => Estonia
+ ES , // eu: Basque => Spain
+ IR , // fa: Persian => Iran
+ unknown, // ff: Fulah => (maps to multiple countries)
+ FI , // fi: Finnish => Finland
+ FJ , // fj: Fiji => Fiji
+ FO , // fo: Faroese => Faroe Islands
+ FR , // fr: French => France
+ NL , // fy: Frisian => Netherlands
+ IE , // ga: Irish => Ireland
+ GB , // gd: Scots Gaelic => United Kingdom
+ ES , // gl: Galician => Spain
+ PY , // gn: Guarani => Paraguay
+ IN_ , // gu: Gujarati => India
+ IM , // gv: Manx => Isle of Man
+ unknown, // ha: Hausa => (maps to multiple languages)
+ IL , // he: Hebrew => Israel
+ IN_ , // hi: Hindi => India
+ PG , // ho: Hiri Motu => Papua New Guinea
+ HR , // hr: Croatian => Croatia
+ HT , // ht: Haitian Creole => Haiti
+ HU , // hu: Hungarian => Hungary
+ AM , // hy: Armenian => Armenia
+ unknown, // hz: Herero => (maps to multiple countries)
+ unknown, // ia: Interlingua => (constructed language)
+ ID , // id: Indonesian => Indonesia
+ unknown, // ie: Interlingue => (constructed language)
+ NG , // ig: Igbo => Nigeria
+ CN , // ii: Nuosu => China
+ US , // ik: Inupiak => United States
+ unknown, // io: Ido => (constructed language)
+ IS , // is: Icelandic => Island
+ IT , // it: Italian => Italy
+ CA , // iu: Inuktitut => Canada
+ JP , // ja: Japanese => Japan
+ ID , // jv: Javanese => Indonesia
+ GE , // ka: Georgian => Georgia
+ unknown, // kg: Kongo => (maps to multiple countries)
+ KE , // ki: Gikuyu => Kenya
+ unknown, // kj: Kuanyama => (maps to multiple countries)
+ KZ , // kk: Kazakh => Kazakhstan
+ GL , // kl: Greenlandic => Greenland
+ KH , // km: Cambodian => Cambodia
+ IN_ , // kn: Kannada => India
+ KR , // ko: Korean => Korea
+ unknown, // kr: Kanuri => (maps to multiple countries)
+ IN_ , // ks: Kashmiri => India
+ IQ , // ku: Kurdish => Iraq
+ RU , // kv: Komi => Russian Federation
+ GB , // kw: Cornish => United Kingdom
+ KG , // ky: Kirghiz => Kyrgyzstan
+ unknown, // la: Latin => (maps to multiple countries)
+ LU , // lb: Letzeburgesch => Luxembourg
+ UG , // lg: Ganda => Uganda
+ NL , // li: Limburgan; Limburger; Limburgish => Netherands
+ unknown, // ln: Lingala => (maps to multiple countries)
+ LA , // lo: Laotian => Lao
+ LT , // lt: Lithuanian => Lithuania
+ CD , // lu: Luba-Katanga => Democratic Republic of the Congo
+ LV , // lv: Latvian => Latvia
+ MG , // mg: Malagasy => Madagascar
+ MH , // mh: Marshallese => Marshall Islands
+ NZ , // mi: Maori => New Zealand
+ MK , // mk: Macedonian => Macedonia
+ IN_ , // ml: Malayalam => India
+ MN , // mn: Mongolian => Mongolia
+ MD , // mo: Moldavian => Moldova
+ IN_ , // mr: Marathi => India
+ MY , // ms: Malay => Malaysia
+ MT , // mt: Maltese => Malta
+ MM , // my: Burmese => Myanmar (Burma)
+ NR , // na: Nauru => Nauru
+ NO , // nb: Norwegian Bokmal => Norway
+ ZW , // nd: Ndebele, North => Zimbabwe
+ NP , // ne: Nepali => Nepal
+ NA , // ng: Ndonga => Namibia
+ NL , // nl: Dutch => Netherlands
+ NO , // nn: Norwegian Nynorsk => Norway
+ NO , // no: Norwegian => Norway
+ ZA , // nr: Ndebele, South => South Africa
+ US , // nv: Navajo; Navaho => United States
+ MW , // ny: Chichewa; Chewa; Nyanja => Malawi
+ unknown, // oc: Occitan => (maps to multiple countries)
+ CA , // oj: Ojibwa => Canada
+ unknown, // om: Oromo => (maps to multiple countries)
+ IN_ , // or: Oriya => India
+ unknown, // os: Ossetian; Ossetic => (maps to multiple countries)
+ PK , // pa: Panjabi; Punjabi => Pakistan
+ unknown, // pi: Pali => (maps to multiple countries)
+ PL , // pl: Polish => Poland
+ AF , // ps: Pashto, Pushto => Afghanistan
+ PT , // pt: Portuguese => Portugal
+ unknown, // qu: Quechua => (maps to multiple countries)
+ CH , // rm: Romansh => Switzerland
+ BI , // rn: Kirundi => Burundi
+ RO , // ro: Romanian => Romania
+ RU , // ru: Russian => Russian Federation
+ RW , // rw: Kinyarwanda => Rwanda
+ IN_ , // sa: Sanskrit => India
+ IT , // sc: Sardinian => Italy
+ PK , // sd: Sindhi => Pakistan
+ NO , // se: Northern Sami => Norway
+ CF , // sg: Sangho => Central African Republic
+ RS , // sh: Serbo-Croatian => Serbia
+ LK , // si: Sinhalese => Sri Lanka
+ SK , // sk: Slovak => Slovakia
+ SI , // sl: Slovenian => Slovenia
+ AS , // sm: Samoan => American Samoa
+ ZW , // sn: Shona => Zimbabwe
+ SO , // so: Somali => Somalia
+ AL , // sq: Albanian => Albania
+ RS , // sr: Serbian => Serbia
+ SZ , // ss: Siswati => Swaziland
+ LS , // st: Sesotho => Lesotho
+ SD , // su: Sundanese => Sudan
+ SE , // sv: Swedish => Sweden
+ KE , // sw: Swahili => Kenya
+ IN_ , // ta: Tamil => India
+ IN_ , // te: Telugu => India
+ TJ , // tg: Tajik => Tajikistan
+ TH , // th: Thai => Thailand
+ ER , // ti: Tigrinya => Eritrea
+ TM , // tk: Turkmen => Turkmenistan
+ PH , // tl: Tagalog => Philippines
+ ZA , // tn: Setswana => South Africa
+ TO , // to: Tonga => Tonga
+ TR , // tr: Turkish => Turkey
+ ZA , // ts: Tsonga => South Africa
+ RU , // tt: Tatar => Russian Federation
+ GH , // tw: Twi => Ghana
+ PF , // ty: Tahitian => French Polynesia
+ CN , // ug: Uighur => China
+ UA , // uk: Ukrainian => Ukrain
+ PK , // ur: Urdu => Pakistan
+ UZ , // uz: Uzbek => Uzbekistan
+ ZA , // ve: Venda => South Africa
+ VN , // vi: Vietnamese => Viet Nam
+ DE , // vo: Volapuk => Germany
+ BE , // wa: Walloon => Belgium
+ SN , // wo: Wolof => Senegal
+ ZA , // xh: Xhosa => South Africa
+ IL , // yi: Yiddish => Israel
+ NG , // yo: Yoruba => Nigeria
+ CN , // za: Zhuang => China
+ CN , // zh: Chinese => China
+ ZA , // zu: Zulu => South Africa
+ };
+ assert( lang < iso639_1::NUM_ENTRIES );
+ return lang_to_country[ lang ];
+}
+
} // namespace iso3166_1
///////////////////////////////////////////////////////////////////////////////
@@ -1302,6 +1505,8 @@
}
bool is_supported( iso639_1::type lang, iso3166_1::type country ) {
+ if ( !country )
+ country = iso3166_1::get_default( lang );
#ifdef WIN32
unique_ptr<WCHAR[]> const wlocale_name( get_wlocale_name( lang, country ) );
return Zorba_IsValidLocaleName( wlocale_name.get() );
=== modified file 'src/zorbautils/locale.h'
--- src/zorbautils/locale.h 2013-03-08 04:26:02 +0000
+++ src/zorbautils/locale.h 2013-03-20 21:54:22 +0000
@@ -62,6 +62,15 @@
find( StringType const &country ) {
return find( country.c_str() );
}
+
+ /**
+ * Gets the "default" country that speaks the given language.
+ *
+ * @param lang The language to get the default country for.
+ * @return Returns said country or \c unknown.
+ */
+ type get_default( iso639_1::type lang );
+
} // namespace iso3166_1
///////////////////////////////////////////////////////////////////////////
=== modified file 'test/fots/CMakeLists.txt'
--- test/fots/CMakeLists.txt 2013-03-20 06:58:59 +0000
+++ test/fots/CMakeLists.txt 2013-03-20 21:54:22 +0000
@@ -158,37 +158,8 @@
EXPECTED_FOTS_FAILURE (fn-environment-variable environment-variable-005 0)
EXPECTED_FOTS_FAILURE (fn-environment-variable environment-variable-006 0)
EXPECTED_FOTS_FAILURE (fn-environment-variable environment-variable-007 0)
-EXPECTED_FOTS_FAILURE (fn-format-date format-date-001d 0)
-EXPECTED_FOTS_FAILURE (fn-format-date format-date-001g 0)
EXPECTED_FOTS_FAILURE (fn-format-date format-date-005 0)
EXPECTED_FOTS_FAILURE (fn-format-date format-date-006 0)
-EXPECTED_FOTS_FAILURE (fn-format-date format-date-007a 0)
-EXPECTED_FOTS_FAILURE (fn-format-date format-date-007b 0)
-EXPECTED_FOTS_FAILURE (fn-format-date format-date-007c 0)
-EXPECTED_FOTS_FAILURE (fn-format-date format-date-008a 0)
-EXPECTED_FOTS_FAILURE (fn-format-date format-date-008b 0)
-EXPECTED_FOTS_FAILURE (fn-format-date format-date-008c 0)
-EXPECTED_FOTS_FAILURE (fn-format-date format-date-009 0)
-EXPECTED_FOTS_FAILURE (fn-format-date format-date-010 0)
-EXPECTED_FOTS_FAILURE (fn-format-date format-date-014 0)
-EXPECTED_FOTS_FAILURE (fn-format-date format-date-015 0)
-EXPECTED_FOTS_FAILURE (fn-format-date format-date-016 0)
-EXPECTED_FOTS_FAILURE (fn-format-date format-date-017 0)
-EXPECTED_FOTS_FAILURE (fn-format-date format-date-018 0)
-EXPECTED_FOTS_FAILURE (fn-format-date format-date-019 0)
-EXPECTED_FOTS_FAILURE (fn-format-date format-date-020 0)
-EXPECTED_FOTS_FAILURE (fn-format-date format-date-021 0)
-EXPECTED_FOTS_FAILURE (fn-format-date format-date-022 0)
-EXPECTED_FOTS_FAILURE (fn-format-date format-date-023 0)
-EXPECTED_FOTS_FAILURE (fn-format-date format-date-024 0)
-EXPECTED_FOTS_FAILURE (fn-format-date format-date-025 0)
-EXPECTED_FOTS_FAILURE (fn-format-date format-date-026 0)
-EXPECTED_FOTS_FAILURE (fn-format-date format-date-027 0)
-EXPECTED_FOTS_FAILURE (fn-format-date format-date-en117 0)
-EXPECTED_FOTS_FAILURE (fn-format-date format-date-en118 0)
-EXPECTED_FOTS_FAILURE (fn-format-date format-date-en123 0)
-EXPECTED_FOTS_FAILURE (fn-format-date format-date-en124 0)
-EXPECTED_FOTS_FAILURE (fn-format-date format-date-en125 0)
EXPECTED_FOTS_FAILURE (fn-format-date format-date-en126 0)
EXPECTED_FOTS_FAILURE (fn-format-date format-date-en127 0)
EXPECTED_FOTS_FAILURE (fn-format-date format-date-en128 0)
@@ -198,34 +169,9 @@
EXPECTED_FOTS_FAILURE (fn-format-date format-date-en132 0)
EXPECTED_FOTS_FAILURE (fn-format-date format-date-en133 0)
EXPECTED_FOTS_FAILURE (fn-format-date format-date-en134 0)
-EXPECTED_FOTS_FAILURE (fn-format-date format-date-en141 0)
-EXPECTED_FOTS_FAILURE (fn-format-date format-date-en151 0)
-EXPECTED_FOTS_FAILURE (fn-format-dateTime format-dateTime-001d 0)
-EXPECTED_FOTS_FAILURE (fn-format-dateTime format-dateTime-001g 0)
-EXPECTED_FOTS_FAILURE (fn-format-dateTime format-dateTime-002g 0)
-EXPECTED_FOTS_FAILURE (fn-format-dateTime format-dateTime-002h 0)
-EXPECTED_FOTS_FAILURE (fn-format-dateTime format-dateTime-002i 0)
-EXPECTED_FOTS_FAILURE (fn-format-dateTime format-dateTime-003d 0)
-EXPECTED_FOTS_FAILURE (fn-format-dateTime format-dateTime-003g 0)
-EXPECTED_FOTS_FAILURE (fn-format-dateTime format-dateTime-003m 0)
-EXPECTED_FOTS_FAILURE (fn-format-dateTime format-dateTime-003n 0)
-EXPECTED_FOTS_FAILURE (fn-format-dateTime format-dateTime-003p 0)
EXPECTED_FOTS_FAILURE (fn-format-dateTime format-dateTime-005 0)
EXPECTED_FOTS_FAILURE (fn-format-dateTime format-dateTime-006 0)
-EXPECTED_FOTS_FAILURE (fn-format-dateTime format-dateTime-009 0)
-EXPECTED_FOTS_FAILURE (fn-format-dateTime format-dateTime-010 0)
EXPECTED_FOTS_FAILURE (fn-format-dateTime format-dateTime-011 0)
-EXPECTED_FOTS_FAILURE (fn-format-dateTime format-dateTime-012 0)
-EXPECTED_FOTS_FAILURE (fn-format-dateTime format-dateTime-013p 0)
-EXPECTED_FOTS_FAILURE (fn-format-dateTime format-dateTime-013s 0)
-EXPECTED_FOTS_FAILURE (fn-format-dateTime format-dateTime-013u 0)
-EXPECTED_FOTS_FAILURE (fn-format-dateTime format-dateTime-014 0)
-EXPECTED_FOTS_FAILURE (fn-format-dateTime format-dateTime-015 0)
-EXPECTED_FOTS_FAILURE (fn-format-dateTime format-dateTime-016 0)
-EXPECTED_FOTS_FAILURE (fn-format-dateTime format-dateTime-017 0)
-EXPECTED_FOTS_FAILURE (fn-format-dateTime format-dateTime-018 0)
-EXPECTED_FOTS_FAILURE (fn-format-dateTime format-dateTime-en141 0)
-EXPECTED_FOTS_FAILURE (fn-format-dateTime format-dateTime-en151 0)
EXPECTED_FOTS_FAILURE (fn-format-integer format-integer-030 0)
EXPECTED_FOTS_FAILURE (fn-format-integer format-integer-031 0)
EXPECTED_FOTS_FAILURE (fn-format-integer format-integer-033 0)
@@ -265,18 +211,6 @@
EXPECTED_FOTS_FAILURE (fn-format-number numberformat86 0)
EXPECTED_FOTS_FAILURE (fn-format-number numberformat87 0)
EXPECTED_FOTS_FAILURE (fn-format-number numberformat88 0)
-EXPECTED_FOTS_FAILURE (fn-format-time format-time-002g 0)
-EXPECTED_FOTS_FAILURE (fn-format-time format-time-002h 0)
-EXPECTED_FOTS_FAILURE (fn-format-time format-time-002i 0)
-EXPECTED_FOTS_FAILURE (fn-format-time format-time-013p 0)
-EXPECTED_FOTS_FAILURE (fn-format-time format-time-013s 0)
-EXPECTED_FOTS_FAILURE (fn-format-time format-time-013u 0)
-EXPECTED_FOTS_FAILURE (fn-format-time format-time-014 0)
-EXPECTED_FOTS_FAILURE (fn-format-time format-time-015 0)
-EXPECTED_FOTS_FAILURE (fn-format-time format-time-016 0)
-EXPECTED_FOTS_FAILURE (fn-format-time format-time-017 0)
-EXPECTED_FOTS_FAILURE (fn-format-time format-time-018 0)
-EXPECTED_FOTS_FAILURE (fn-format-time format-time-816err 0)
EXPECTED_FOTS_FAILURE (fn-generate-id generate-id-001 0)
EXPECTED_FOTS_FAILURE (fn-generate-id generate-id-002 0)
EXPECTED_FOTS_FAILURE (fn-generate-id generate-id-003 0)
=== removed file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncYearMonth1.xml.res'
--- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncYearMonth1.xml.res 2013-02-07 17:24:36 +0000
+++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncYearMonth1.xml.res 1970-01-01 00:00:00 +0000
@@ -1,1 +0,0 @@
-true
\ No newline at end of file
=== removed file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncYearMonth2.xml.res'
--- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncYearMonth2.xml.res 2013-02-07 17:24:36 +0000
+++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncYearMonth2.xml.res 1970-01-01 00:00:00 +0000
@@ -1,1 +0,0 @@
-true
\ No newline at end of file
=== added file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-D.xml.res'
--- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-D.xml.res 1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-D.xml.res 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+true
=== added file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-D01.xml.res'
--- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-D01.xml.res 1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-D01.xml.res 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+true
=== added file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-D1o.xml.res'
--- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-D1o.xml.res 1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-D1o.xml.res 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+true
=== added file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-DW-1.xml.res'
--- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-DW-1.xml.res 1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-DW-1.xml.res 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+true
=== added file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-DWo-1.xml.res'
--- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-DWo-1.xml.res 1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-DWo-1.xml.res 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+true
=== added file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-DWw.xml.res'
--- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-DWw.xml.res 1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-DWw.xml.res 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+true
=== added file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-DWwo.xml.res'
--- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-DWwo.xml.res 1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-DWwo.xml.res 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+true
=== added file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-Dw-2.xml.res'
--- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-Dw-2.xml.res 1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-Dw-2.xml.res 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+true
=== added file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-Dwo-2.xml.res'
--- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-Dwo-2.xml.res 1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-Dwo-2.xml.res 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+true
=== added file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-FN-1.xml.res'
--- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-FN-1.xml.res 1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-FN-1.xml.res 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+true
=== added file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-FN-3.xml.res'
--- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-FN-3.xml.res 1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-FN-3.xml.res 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+true
=== added file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-FNn-1.xml.res'
--- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-FNn-1.xml.res 1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-FNn-1.xml.res 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+true
=== added file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-FNn-2.xml.res'
--- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-FNn-2.xml.res 1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-FNn-2.xml.res 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+true
=== added file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-Fn-2.xml.res'
--- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-Fn-2.xml.res 1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-Fn-2.xml.res 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+true
=== added file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-Fn-4.xml.res'
--- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-Fn-4.xml.res 1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-Fn-4.xml.res 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+true
=== renamed file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncMonthDefault.xml.res' => 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-M.xml.res'
--- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncMonthDefault.xml.res 2013-02-07 17:24:36 +0000
+++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-M.xml.res 2013-03-20 21:54:22 +0000
@@ -1,1 +1,1 @@
-true
\ No newline at end of file
+true
=== renamed file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncMonthNumber.xml.res' => 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-M01.xml.res'
--- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncMonthNumber.xml.res 2013-02-07 17:24:36 +0000
+++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-M01.xml.res 2013-03-20 21:54:22 +0000
@@ -1,1 +1,1 @@
-true
\ No newline at end of file
+true
=== renamed file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncMonthUpperCase.xml.res' => 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-MN-1.xml.res'
--- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncMonthUpperCase.xml.res 2013-02-07 17:24:36 +0000
+++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-MN-1.xml.res 2013-03-20 21:54:22 +0000
@@ -1,1 +1,1 @@
-true
\ No newline at end of file
+true
=== renamed file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncMonthTitleCase.xml.res' => 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-MNn.xml.res'
--- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncMonthTitleCase.xml.res 2013-02-07 17:24:36 +0000
+++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-MNn.xml.res 2013-03-20 21:54:22 +0000
@@ -1,1 +1,1 @@
-true
\ No newline at end of file
+true
=== renamed file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncMonthLowerCase.xml.res' => 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-Mn-2.xml.res'
--- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncMonthLowerCase.xml.res 2013-02-07 17:24:36 +0000
+++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-Mn-2.xml.res 2013-03-20 21:54:22 +0000
@@ -1,1 +1,1 @@
-true
\ No newline at end of file
+true
=== renamed file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncYearMaxWidth.xml.res' => 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-Y-2-2.xml.res'
--- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncYearMaxWidth.xml.res 2013-02-07 17:24:36 +0000
+++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-Y-2-2.xml.res 2013-03-20 21:54:22 +0000
@@ -1,1 +1,1 @@
-true
\ No newline at end of file
+true
=== renamed file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncReflexivity.xml.res' => 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-Y-M01-D01.xml.res'
--- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncReflexivity.xml.res 2013-02-07 17:24:36 +0000
+++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-Y-M01-D01.xml.res 2013-03-20 21:54:22 +0000
@@ -1,1 +1,1 @@
-true
\ No newline at end of file
+true
=== added file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-Y-Thai-1.xml.res'
--- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-Y-Thai-1.xml.res 1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-Y-Thai-1.xml.res 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+true
=== added file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-Y-Thai-2.xml.res'
--- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-Y-Thai-2.xml.res 1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-Y-Thai-2.xml.res 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+true
=== renamed file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncYearDefault.xml.res' => 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-Y.xml.res'
--- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncYearDefault.xml.res 2013-02-07 17:24:36 +0000
+++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-Y.xml.res 2013-03-20 21:54:22 +0000
@@ -1,1 +1,1 @@
-true
\ No newline at end of file
+true
=== added file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-YI-1.xml.res'
--- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-YI-1.xml.res 1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-YI-1.xml.res 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+true
=== added file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-Yi-2.xml.res'
--- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-Yi-2.xml.res 1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-Yi-2.xml.res 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+true
=== renamed file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncYearDefaultExtraChars.xml.res' => 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-chars.xml.res'
--- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncYearDefaultExtraChars.xml.res 2013-02-07 17:24:36 +0000
+++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-chars.xml.res 2013-03-20 21:54:22 +0000
@@ -1,1 +1,1 @@
-true
\ No newline at end of file
+true
=== renamed file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncMonthNumberSpaces.xml.res' => 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-whitespace.xml.res'
--- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncMonthNumberSpaces.xml.res 2013-02-07 17:24:36 +0000
+++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-date-whitespace.xml.res 2013-03-20 21:54:22 +0000
@@ -1,1 +1,1 @@
-true
\ No newline at end of file
+true
=== renamed file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/FormatDateTimeFuncReflexivity.xml.res' => 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-dateTime-01.xml.res'
--- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/FormatDateTimeFuncReflexivity.xml.res 2013-02-07 17:24:36 +0000
+++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-dateTime-01.xml.res 2013-03-20 21:54:22 +0000
@@ -1,1 +1,1 @@
-true
\ No newline at end of file
+true
=== added file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-H-1.xml.res'
--- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-H-1.xml.res 1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-H-1.xml.res 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+true
=== added file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-P-1.xml.res'
--- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-P-1.xml.res 1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-P-1.xml.res 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+true
=== added file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-P-2.xml.res'
--- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-P-2.xml.res 1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-P-2.xml.res 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+true
=== added file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-P-3.xml.res'
--- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-P-3.xml.res 1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-P-3.xml.res 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+true
=== added file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-Z0-1.xml.res'
--- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-Z0-1.xml.res 1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-Z0-1.xml.res 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+true
=== added file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-Z0-2.xml.res'
--- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-Z0-2.xml.res 1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-Z0-2.xml.res 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+true
=== added file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-Z0000.xml.res'
--- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-Z0000.xml.res 1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-Z0000.xml.res 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+true
=== added file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-Z00_00.xml.res'
--- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-Z00_00.xml.res 1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-Z00_00.xml.res 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+true
=== added file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-Z00_00t-1.xml.res'
--- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-Z00_00t-1.xml.res 1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-Z00_00t-1.xml.res 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+true
=== added file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-Z00_00t-2.xml.res'
--- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-Z00_00t-2.xml.res 1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-Z00_00t-2.xml.res 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+true
=== added file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-Z0_00.xml.res'
--- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-Z0_00.xml.res 1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-Z0_00.xml.res 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+true
=== added file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-ZN-CST.xml.res'
--- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-ZN-CST.xml.res 1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-ZN-CST.xml.res 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+true
=== added file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-ZN-EST.xml.res'
--- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-ZN-EST.xml.res 1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-ZN-EST.xml.res 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+true
=== added file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-ZN-GMT.xml.res'
--- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-ZN-GMT.xml.res 1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-ZN-GMT.xml.res 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+true
=== added file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-ZN-MST.xml.res'
--- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-ZN-MST.xml.res 1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-ZN-MST.xml.res 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+true
=== added file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-ZN-PST.xml.res'
--- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-ZN-PST.xml.res 1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-ZN-PST.xml.res 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+true
=== added file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-ZZ-1.xml.res'
--- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-ZZ-1.xml.res 1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-ZZ-1.xml.res 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+true
=== added file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-ZZ-2.xml.res'
--- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-ZZ-2.xml.res 1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-ZZ-2.xml.res 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+true
=== added file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-h-2.xml.res'
--- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-h-2.xml.res 1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-h-2.xml.res 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+true
=== added file 'test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-z.xml.res'
--- test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-z.xml.res 1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/durationdatetime/FormatDateTimeFunc/format-time-z.xml.res 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+true
=== removed file 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncYearMonth1.xq'
--- test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncYearMonth1.xq 2013-02-07 17:24:36 +0000
+++ test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncYearMonth1.xq 1970-01-01 00:00:00 +0000
@@ -1,1 +0,0 @@
-fn:format-date(xs:date("2010-12-31"), "[Y][M]") eq "201012"
=== removed file 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncYearMonth2.xq'
--- test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncYearMonth2.xq 2013-02-07 17:24:36 +0000
+++ test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncYearMonth2.xq 1970-01-01 00:00:00 +0000
@@ -1,1 +0,0 @@
-fn:format-date(xs:date("2010-12-31"), "[Y].[M]") eq "2010.12"
\ No newline at end of file
=== added file 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-BadComponent.spec'
--- test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-BadComponent.spec 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-BadComponent.spec 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+Error: http://www.w3.org/2005/xqt-errors:FOFD1340
=== added file 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-BadComponent.xq'
--- test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-BadComponent.xq 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-BadComponent.xq 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+fn:format-date( xs:date("2012-01-02"), "[A]" )
=== added file 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-CharExpected-1.spec'
--- test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-CharExpected-1.spec 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-CharExpected-1.spec 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+Error: http://www.w3.org/2005/xqt-errors:FOFD1340
=== added file 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-CharExpected-1.xq'
--- test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-CharExpected-1.xq 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-CharExpected-1.xq 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+fn:format-date( xs:date("2012-01-02"), "[Y" )
=== added file 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-D.xq'
--- test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-D.xq 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-D.xq 2013-03-20 21:54:22 +0000
@@ -0,0 +1,2 @@
+(: Default presentation modifier for D is 1, so a number should be the result :)
+fn:format-date( xs:date("2010-12-03"), "[D]" ) eq "3"
=== added file 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-D01.xq'
--- test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-D01.xq 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-D01.xq 2013-03-20 21:54:22 +0000
@@ -0,0 +1,2 @@
+(: D as a 2-digit number :)
+fn:format-date( xs:date("2010-12-03"), "[D01]" ) eq "03"
=== added file 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-DW-1.xq'
--- test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-DW-1.xq 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-DW-1.xq 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+fn:format-date( xs:date("2010-12-31"), "[DW]", "en-US", (), () ) eq "THIRTY ONE"
=== added file 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-DWw.xq'
--- test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-DWw.xq 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-DWw.xq 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+fn:format-date( xs:date("2010-12-31"), "[DWw]", "en-US", (), () ) eq "Thirty One"
=== added file 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-Dw-2.xq'
--- test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-Dw-2.xq 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-Dw-2.xq 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+fn:format-date( xs:date("2010-12-31"), "[Dw]", "en-US", (), () ) eq "thirty one"
=== added file 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-FN-1.xq'
--- test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-FN-1.xq 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-FN-1.xq 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+fn:format-date( xs:date("1967-11-18"), "[FN]", "en-US", (), () ) eq "SATURDAY"
=== added file 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-FN-3.xq'
--- test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-FN-3.xq 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-FN-3.xq 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+fn:format-date( xs:date("1967-11-18"), "[FN]", "de-DE", (), () ) eq "SAMSTAG"
=== added file 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-FNn-1.xq'
--- test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-FNn-1.xq 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-FNn-1.xq 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+fn:format-date( xs:date("1967-11-18"), "[FNn]", "en-US", (), () ) eq "Saturday"
=== added file 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-FNn-2.xq'
--- test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-FNn-2.xq 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-FNn-2.xq 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+fn:format-date( xs:date("1967-11-18"), "[FNn]", "de-DE", (), () ) eq "Samstag"
=== added file 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-Fn-2.xq'
--- test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-Fn-2.xq 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-Fn-2.xq 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+fn:format-date( xs:date("1967-11-18"), "[Fn]", "en-US", (), () ) eq "saturday"
=== added file 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-Fn-4.xq'
--- test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-Fn-4.xq 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-Fn-4.xq 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+fn:format-date( xs:date("1967-11-18"), "[Fn]", "de-DE", (), () ) eq "samstag"
=== renamed file 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncMonthDefault.xq' => 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-M.xq'
--- test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncMonthDefault.xq 2013-02-07 17:24:36 +0000
+++ test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-M.xq 2013-03-20 21:54:22 +0000
@@ -1,2 +1,2 @@
-(: Default Presentation Modifier for M is 1, so a number should be the result :)
-fn:format-date(xs:date("2010-12-31"), "[M]") eq "12"
+(: Default presentation modifier for M is 1, so a number should be the result :)
+fn:format-date( xs:date("2010-12-31"), "[M]" ) eq "12"
=== renamed file 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncMonthNumber.xq' => 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-M01.xq'
--- test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncMonthNumber.xq 2013-02-07 17:24:36 +0000
+++ test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-M01.xq 2013-03-20 21:54:22 +0000
@@ -1,2 +1,2 @@
-(: M as number on 2 digits :)
-fn:format-date(xs:date("2010-12-31"), "[M01]") eq "12"
+(: M as a 2-digit number :)
+fn:format-date(xs:date("2010-01-31"), "[M01]") eq "01"
=== renamed file 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncMonthUpperCase.xq' => 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-MN-1.xq'
--- test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncMonthUpperCase.xq 2013-02-07 17:24:36 +0000
+++ test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-MN-1.xq 2013-03-20 21:54:22 +0000
@@ -1,2 +1,2 @@
(: M as word in upper case :)
-fn:format-date(xs:date("2010-12-31"), "[MN]") eq "DECEMBER"
+fn:format-date( xs:date("2010-12-31"), "[MN]", "en-US", (), () ) eq "DECEMBER"
=== renamed file 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncMonthTitleCase.xq' => 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-MNn.xq'
--- test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncMonthTitleCase.xq 2013-02-07 17:24:36 +0000
+++ test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-MNn.xq 2013-03-20 21:54:22 +0000
@@ -1,2 +1,2 @@
(: M as word in title case :)
-fn:format-date(xs:date("2010-12-31"), "[MNn]") eq "December"
+fn:format-date( xs:date("2010-12-31"), "[MNn]", "en-US", (), () ) eq "December"
=== renamed file 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncMonthLowerCase.xq' => 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-Mn-2.xq'
--- test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncMonthLowerCase.xq 2013-02-07 17:24:36 +0000
+++ test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-Mn-2.xq 2013-03-20 21:54:22 +0000
@@ -1,2 +1,2 @@
(: M as word in lower case :)
-fn:format-date(xs:date("2010-12-31"), "[Mn]") eq "december"
+fn:format-date( xs:date("2010-12-31"), "[Mn]", "en-US", (), () ) eq "december"
=== added file 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-NoAdjacentGroupSep.spec'
--- test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-NoAdjacentGroupSep.spec 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-NoAdjacentGroupSep.spec 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+Error: http://www.w3.org/2005/xqt-errors:FOFD1340
=== added file 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-NoAdjacentGroupSep.xq'
--- test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-NoAdjacentGroupSep.xq 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-NoAdjacentGroupSep.xq 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+fn:format-date( xs:date("2012-01-02"), "[Y00''00]" )
=== added file 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-NoComponent.spec'
--- test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-NoComponent.spec 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-NoComponent.spec 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+Error: http://www.w3.org/2005/xqt-errors:FOFD1340
=== added file 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-NoComponent.xq'
--- test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-NoComponent.xq 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-NoComponent.xq 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+fn:format-date( xs:date("2012-01-02"), "[]" )
=== added file 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-NoGroupSepAtEnd.spec'
--- test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-NoGroupSepAtEnd.spec 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-NoGroupSepAtEnd.spec 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+Error: http://www.w3.org/2005/xqt-errors:FOFD1340
=== added file 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-NoGroupSepAtEnd.xq'
--- test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-NoGroupSepAtEnd.xq 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-NoGroupSepAtEnd.xq 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+fn:format-date( xs:date("2012-01-02"), "[Y00']" )
=== added file 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-NoGroupSepAtStart.spec'
--- test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-NoGroupSepAtStart.spec 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-NoGroupSepAtStart.spec 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+Error: http://www.w3.org/2005/xqt-errors:FOFD1340
=== added file 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-NoGroupSepAtStart.xq'
--- test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-NoGroupSepAtStart.xq 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-NoGroupSepAtStart.xq 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+fn:format-date( xs:date("2012-01-02"), "[Y']" )
=== added file 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-NoOptDigitAfterMandatory.spec'
--- test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-NoOptDigitAfterMandatory.spec 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-NoOptDigitAfterMandatory.spec 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+Error: http://www.w3.org/2005/xqt-errors:FOFD1340
=== added file 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-NoOptDigitAfterMandatory.xq'
--- test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-NoOptDigitAfterMandatory.xq 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-NoOptDigitAfterMandatory.xq 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+fn:format-date( xs:date("2012-01-02"), "[Y0#]" )
=== renamed file 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncYearMaxWidth.xq' => 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-Y-2-2.xq'
--- test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncYearMaxWidth.xq 2013-02-07 17:24:36 +0000
+++ test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-Y-2-2.xq 2013-03-20 21:54:22 +0000
@@ -1,2 +1,2 @@
-(: if max-width is set to 2 then the year 2003 will be output as 03 :)
-fn:format-date(xs:date("2010-12-31"), "[Y,2-2]") eq "10"
+(: If max-width is set to 2, then the year 2003 will be output as 03 :)
+fn:format-date( xs:date("2003-12-31"), "[Y,2-2]" ) eq "03"
=== renamed file 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncReflexivity.xq' => 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-Y-M01-D01.xq'
--- test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncReflexivity.xq 2013-02-07 17:24:36 +0000
+++ test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-Y-M01-D01.xq 2013-03-20 21:54:22 +0000
@@ -1,3 +1,3 @@
-let $date := xs:date("2010-12-31")
-let $newDate := xs:date(fn:format-date($date, "[Y]-[M01]-[D01]"))
-return $date eq $newDate
+let $old := xs:date( "2010-12-31" )
+let $new := xs:date( fn:format-date( $old, "[Y]-[M01]-[D01]" ) )
+return $new eq $old
=== added file 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-Y-Thai-1.xq'
--- test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-Y-Thai-1.xq 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-Y-Thai-1.xq 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+fn:format-date( xs:date("2003-09-07"), "[Y๐๐๐๑]" ) eq "๒๐๐๓"
=== added file 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-Y-Thai-2.xq'
--- test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-Y-Thai-2.xq 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-Y-Thai-2.xq 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+fn:format-date( xs:date("2003-09-07"), "[Y๐๑]" ) eq "๐๓"
=== renamed file 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncYearDefault.xq' => 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-Y.xq'
--- test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncYearDefault.xq 2013-02-07 17:24:36 +0000
+++ test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-Y.xq 2013-03-20 21:54:22 +0000
@@ -1,2 +1,1 @@
-(: Default Presentation Modifier for Y is 1, so a number should be the result :)
-fn:format-date(xs:date("2010-12-31"), "[Y]") eq "2010"
+fn:format-date( xs:date("2010-12-31"), "[Y]" ) eq "2010"
=== added file 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-YI-1.xq'
--- test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-YI-1.xq 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-YI-1.xq 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+fn:format-date( xs:date("1967-11-18"), "[YI]" ) eq "MCMLXVII"
=== added file 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-Yi-2.xq'
--- test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-Yi-2.xq 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-Yi-2.xq 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+fn:format-date( xs:date("1967-11-18"), "[Yi]" ) eq "mcmlxvii"
=== renamed file 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncYearDefaultExtraChars.xq' => 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-chars.xq'
--- test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncYearDefaultExtraChars.xq 2013-02-07 17:24:36 +0000
+++ test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-chars.xq 2013-03-20 21:54:22 +0000
@@ -1,2 +1,2 @@
-(: Default Presentation Modifier for M is 1, so a number should be the result :)
-fn:format-date(xs:date("2010-12-31"), "[Y]. this should also come in the output") eq "2010. this should also come in the output"
+(: extra chars passed through as-as :)
+fn:format-date( xs:date("2010-12-31"), "extra [Y] chars" ) eq "extra 2010 chars"
=== renamed file 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncMonthNumberSpaces.xq' => 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-whitespace.xq'
--- test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/FormatDateFuncMonthNumberSpaces.xq 2013-02-07 17:24:36 +0000
+++ test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-date-whitespace.xq 2013-03-20 21:54:22 +0000
@@ -1,6 +1,6 @@
-(: whitespaces in variable markers are ignored :)
-fn:format-date(xs:date("2010-12-31"), "[
+(: Whitespace in variable markers should be ignored :)
+fn:format-date( xs:date("2010-12-31"), "[
M
01
- ]")
-eq "12"
\ No newline at end of file
+ ]" )
+eq "12"
=== renamed file 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/FormatDateTimeFuncReflexivity.xq' => 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-dateTime-01.xq'
--- test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/FormatDateTimeFuncReflexivity.xq 2013-02-07 17:24:36 +0000
+++ test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-dateTime-01.xq 2013-03-20 21:54:22 +0000
@@ -1,3 +1,3 @@
-let $dateTime := xs:dateTime("2010-11-12T13:14:15.167")
-let $newDateTime := xs:dateTime(fn:format-dateTime($dateTime, "[Y]-[M01]-[D01]T[H01]:[m01]:[s01].[f001]"))
-return $dateTime eq $newDateTime
+let $old := xs:dateTime( "2010-11-12T13:14:15.167" )
+let $new := xs:dateTime( fn:format-dateTime( $old, "[Y]-[M01]-[D01]T[H01]:[m01]:[s01].[f001]" ) )
+return $new eq $old
=== added file 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-H-1.xq'
--- test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-H-1.xq 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-H-1.xq 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+fn:format-time( xs:time("21:14:00"), "[H]" ) eq "21"
=== added file 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-P-1.xq'
--- test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-P-1.xq 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-P-1.xq 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+fn:format-time( xs:time("09:14:00"), "[P]", "en-US", (), () ) eq "am"
=== added file 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-P-2.xq'
--- test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-P-2.xq 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-P-2.xq 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+fn:format-time( xs:time("21:14:00"), "[P]", "en-US", (), () ) eq "pm"
=== added file 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-P-3.xq'
--- test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-P-3.xq 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-P-3.xq 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+fn:format-time( xs:time("21:14:00"), "[PN]", "en-US", (), () ) eq "PM"
=== added file 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-Z0-1.xq'
--- test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-Z0-1.xq 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-Z0-1.xq 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+fn:format-time( xs:time("09:14:00-08:00"), "[Z0]" ) eq "-8"
=== added file 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-Z0-2.xq'
--- test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-Z0-2.xq 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-Z0-2.xq 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+fn:format-time( xs:time("09:14:00-08:30"), "[Z0]" ) eq "-8:30"
=== added file 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-Z0000.xq'
--- test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-Z0000.xq 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-Z0000.xq 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+fn:format-time( xs:time("09:14:00-08:30"), "[Z0000]" ) eq "-0830"
=== added file 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-Z00_00.xq'
--- test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-Z00_00.xq 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-Z00_00.xq 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+fn:format-time( xs:time("09:14:00-08:30"), "[Z00:00]" ) eq "-08:30"
=== added file 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-Z00_00t-1.xq'
--- test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-Z00_00t-1.xq 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-Z00_00t-1.xq 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+fn:format-time( xs:time("09:14:00-08:30"), "[Z00:00t]" ) eq "-08:30"
=== added file 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-Z00_00t-2.xq'
--- test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-Z00_00t-2.xq 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-Z00_00t-2.xq 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+fn:format-time( xs:time("09:14:00+00:00"), "[Z00:00t]" ) eq "Z"
=== added file 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-Z0_00.xq'
--- test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-Z0_00.xq 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-Z0_00.xq 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+fn:format-time( xs:time("09:14:00-08:30"), "[Z0:00]" ) eq "-8:30"
=== added file 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-ZN-CST.xq'
--- test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-ZN-CST.xq 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-ZN-CST.xq 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+fn:format-time( xs:time("09:14:00-06:00"), "[ZN]" ) eq "CST"
=== added file 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-ZN-EST.xq'
--- test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-ZN-EST.xq 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-ZN-EST.xq 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+fn:format-time( xs:time("09:14:00-05:00"), "[ZN]" ) eq "EST"
=== added file 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-ZN-GMT.xq'
--- test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-ZN-GMT.xq 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-ZN-GMT.xq 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+fn:format-time( xs:time("09:14:00+00:00"), "[ZN]" ) eq "GMT"
=== added file 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-ZN-MST.xq'
--- test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-ZN-MST.xq 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-ZN-MST.xq 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+fn:format-time( xs:time("09:14:00-07:00"), "[ZN]" ) eq "MST"
=== added file 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-ZN-PST.xq'
--- test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-ZN-PST.xq 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-ZN-PST.xq 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+fn:format-time( xs:time("09:14:00-08:00"), "[ZN]" ) eq "PST"
=== added file 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-ZZ-1.xq'
--- test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-ZZ-1.xq 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-ZZ-1.xq 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+fn:format-time( xs:time("09:14:00-08:00"), "[ZZ]" ) eq "U"
=== added file 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-ZZ-2.xq'
--- test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-ZZ-2.xq 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-ZZ-2.xq 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+fn:format-time( xs:time("09:14:00-08:30"), "[ZZ]" ) eq "-08:30"
=== added file 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-h-2.xq'
--- test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-h-2.xq 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-h-2.xq 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+fn:format-time( xs:time("21:14:00"), "[h]" ) eq "9"
=== added file 'test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-z.xq'
--- test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-z.xq 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/durationdatetime/FormatDateTimeFunc/format-time-z.xq 2013-03-20 21:54:22 +0000
@@ -0,0 +1,1 @@
+fn:format-time( xs:time("09:14:00-08:00"), "[z]" ) eq "GMT-08:00"
Follow ups
-
[Merge] lp:~zorba-coders/zorba/bug-1123162 into lp:zorba
From: noreply, 2013-03-21
-
[Merge] lp:~zorba-coders/zorba/bug-1123162 into lp:zorba
From: Zorba Build Bot, 2013-03-21
-
[Merge] lp:~zorba-coders/zorba/bug-1123162 into lp:zorba
From: Zorba Build Bot, 2013-03-21
-
[Merge] lp:~zorba-coders/zorba/bug-1123162 into lp:zorba
From: Matthias Brantner, 2013-03-21
-
Re: [Merge] lp:~zorba-coders/zorba/bug-1123162 into lp:zorba
From: Matthias Brantner, 2013-03-21
-
Re: [Merge] lp:~zorba-coders/zorba/bug-1123162 into lp:zorba
From: Sorin Marian Nasoi, 2013-03-21
-
Re: [Merge] lp:~zorba-coders/zorba/bug-1123162 into lp:zorba
From: Nicolae Brinza, 2013-03-21
-
[Merge] lp:~zorba-coders/zorba/bug-1123162 into lp:zorba
From: Zorba Build Bot, 2013-03-21
-
Re: [Merge] lp:~zorba-coders/zorba/bug-1123162 into lp:zorba
From: Zorba Build Bot, 2013-03-21
-
[Merge] lp:~zorba-coders/zorba/bug-1123162 into lp:zorba
From: Zorba Build Bot, 2013-03-21
-
[Merge] lp:~zorba-coders/zorba/bug-1123162 into lp:zorba
From: Zorba Build Bot, 2013-03-21
-
[Merge] lp:~zorba-coders/zorba/bug-1123162 into lp:zorba
From: Paul J. Lucas, 2013-03-21
-
[Merge] lp:~zorba-coders/zorba/bug-1123162 into lp:zorba
From: Zorba Build Bot, 2013-03-21
-
Re: [Merge] lp:~zorba-coders/zorba/bug-1123162 into lp:zorba
From: Zorba Build Bot, 2013-03-21
-
[Merge] lp:~zorba-coders/zorba/bug-1123162 into lp:zorba
From: Zorba Build Bot, 2013-03-21
-
[Merge] lp:~zorba-coders/zorba/bug-1123162 into lp:zorba
From: Paul J. Lucas, 2013-03-21
-
[Merge] lp:~zorba-coders/zorba/bug-1123162 into lp:zorba
From: Zorba Build Bot, 2013-03-20
-
Re: [Merge] lp:~zorba-coders/zorba/bug-1123162 into lp:zorba
From: Chris Hillery, 2013-03-20
-
Re: [Merge] lp:~zorba-coders/zorba/bug-1123162 into lp:zorba
From: Zorba Build Bot, 2013-03-20
-
[Merge] lp:~zorba-coders/zorba/bug-1123162 into lp:zorba
From: Zorba Build Bot, 2013-03-20
-
[Merge] lp:~zorba-coders/zorba/bug-1123162 into lp:zorba
From: Paul J. Lucas, 2013-03-20
-
Re: [Merge] lp:~zorba-coders/zorba/bug-1123162 into lp:zorba
From: Paul J. Lucas, 2013-03-20