zorba-coders team mailing list archive
-
zorba-coders team
-
Mailing list archive
-
Message #21040
[Merge] lp:~paul-lucas/zorba/bug-1167704 into lp:zorba
Paul J. Lucas has proposed merging lp:~paul-lucas/zorba/bug-1167704 into lp:zorba.
Commit message:
Added correct support for 'w' in format-date(), etc., functions now that the W3C has resolved the issue.
Requested reviews:
Paul J. Lucas (paul-lucas)
Related bugs:
Bug #1167704 in Zorba: "Implement [w] for ISO calendars for format-date/time functions"
https://bugs.launchpad.net/zorba/+bug/1167704
For more details, see:
https://code.launchpad.net/~paul-lucas/zorba/bug-1167704/+merge/160437
Added correct support for 'w' in format-date(), etc., functions now that the W3C has resolved the issue.
--
https://code.launchpad.net/~paul-lucas/zorba/bug-1167704/+merge/160437
Your team Zorba Coders is subscribed to branch lp:zorba.
=== modified file 'ChangeLog'
--- ChangeLog 2013-04-19 23:41:38 +0000
+++ ChangeLog 2013-04-23 17:00:37 +0000
@@ -43,6 +43,7 @@
* Fixed bug #1123836 (overflows in date/time casts now return FODT0001 and
in durations return FODT0002)
* Fixed bug #1147518 (fn:round-half-to-even (at least 11 failures))
+ * Fixed bug #1167704 (Implement [w] for ISO calendars for format-date/time functions)
* Fixed bug #1114228 (unrecognized options in the XQuery namespace now raise an error)
* Fixed bug #1124273 (xqdoc crash because of annotation literals)
* Fixed bug #1085408 (xs:date(): casting large year values)
=== modified file 'src/runtime/durations_dates_times/format_dateTime.cpp'
--- src/runtime/durations_dates_times/format_dateTime.cpp 2013-03-29 15:31:51 +0000
+++ src/runtime/durations_dates_times/format_dateTime.cpp 2013-04-23 17:00:37 +0000
@@ -561,6 +561,19 @@
}
}
+static void append_week_in_month( unsigned mday, unsigned mon, unsigned year,
+ modifier const &mod, zstring *dest ) {
+ int week = time::calendar::calc_week_in_month( mday, mon, year, mod.cal );
+ if ( week == -1 ) {
+ week = time::calendar::calc_week_in_month( 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_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 );
@@ -1265,7 +1278,10 @@
);
break;
case 'w':
- append_number( dateTime.getWeekInMonth(), mod, &result_str );
+ append_week_in_month(
+ dateTime.getDay(), dateTime.getMonth() - 1, dateTime.getYear(),
+ mod, &result_str
+ );
break;
case 'Y':
append_year( std::abs( dateTime.getYear() ), mod, &result_str );
=== modified file 'src/unit_tests/test_time.cpp'
--- src/unit_tests/test_time.cpp 2013-03-22 19:04:51 +0000
+++ src/unit_tests/test_time.cpp 2013-04-23 17:00:37 +0000
@@ -48,6 +48,62 @@
///////////////////////////////////////////////////////////////////////////////
+static void test_calc_week_in_month() {
+ 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 */ { 1, time::feb, 2013, calendar::AD, 1 },
+ /* 8 */ { 1, time::jun, 2013, calendar::AD, 1 },
+ /* 9 */ { 2, time::jun, 2013, calendar::AD, 2 },
+ /* 10 */ { 28, time::dec, 2013, calendar::AD, 4 },
+ /* 11 */ { 31, time::dec, 2013, calendar::AD, 5 },
+
+ /* 12 */ { 1, time::jan, 2013, calendar::ISO, 1 },
+ /* 13 */ { 2, time::jan, 2013, calendar::ISO, 1 },
+ /* 14 */ { 3, time::jan, 2013, calendar::ISO, 1 },
+ /* 15 */ { 4, time::jan, 2013, calendar::ISO, 1 },
+ /* 16 */ { 5, time::jan, 2013, calendar::ISO, 1 },
+ /* 17 */ { 6, time::jan, 2013, calendar::ISO, 1 },
+ /* 18 */ { 7, time::jan, 2013, calendar::ISO, 2 },
+ /* 19 */ { 1, time::feb, 2013, calendar::ISO, 5 },
+ /* 20 */ { 1, time::jan, 2005, calendar::ISO, 5 },
+ /* 21 */ { 2, time::jan, 2005, calendar::ISO, 5 },
+ /* 22 */ { 3, time::jan, 2005, calendar::ISO, 1 },
+ /* 23 */ { 31, time::dec, 2005, calendar::ISO, 5 },
+ /* 24 */ { 1, time::jan, 2007, calendar::ISO, 1 },
+ /* 25 */ { 30, time::dec, 2007, calendar::ISO, 4 },
+ /* 26 */ { 31, time::dec, 2007, calendar::ISO, 1 },
+ /* 27 */ { 1, time::jan, 2008, calendar::ISO, 1 },
+ /* 28 */ { 28, time::dec, 2008, calendar::ISO, 4 },
+ /* 29 */ { 29, time::dec, 2008, calendar::ISO, 5 },
+ /* 30 */ { 30, time::dec, 2008, calendar::ISO, 5 },
+ /* 31 */ { 31, time::dec, 2008, calendar::ISO, 5 },
+ /* 32 */ { 31, time::dec, 2009, calendar::ISO, 5 },
+ /* 33 */ { 1, time::jan, 2010, calendar::ISO, 5 },
+ /* 34 */ { 2, time::jan, 2010, calendar::ISO, 5 },
+ /* 35 */ { 3, time::jan, 2010, calendar::ISO, 5 },
+ /* 36 */ { 4, time::jan, 2010, calendar::ISO, 1 },
+
+ { 0, 0, 0, calendar::unknown, 0 }
+ };
+
+ test_no = 0;
+ for ( test_type const *t = test; t->mday; ++t ) {
+ int w = calendar::calc_week_in_month( t->mday, t->mon, t->year, t->cal );
+ ++test_no;
+ ASSERT_TRUE( test_no, w == t->expected );
+ }
+}
+
static void test_calc_week_in_year() {
struct test_type {
unsigned mday, mon, year;
@@ -93,10 +149,11 @@
{ 0, 0, 0, calendar::unknown, 0 }
};
+ test_no = 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 );
+ ASSERT_TRUE( test_no, w == t->expected );
}
}
@@ -107,6 +164,7 @@
int test_time( int, char*[] ) {
+ test_calc_week_in_month();
test_calc_week_in_year();
cout << failures << " test(s) failed\n";
=== modified file 'src/util/time_util.cpp'
--- src/util/time_util.cpp 2013-03-25 14:48:29 +0000
+++ src/util/time_util.cpp 2013-04-23 17:00:37 +0000
@@ -108,6 +108,43 @@
"VS" // Vikrama Samvat Era
};
+int calc_week_in_month( unsigned mday, unsigned mon, unsigned year, type cal ) {
+ int mon1_wday = time::calc_wday( 1, mon, year );
+
+ switch ( cal ) {
+ case AD:
+ return (mon1_wday + mday - 1) / 7 + 1;
+ case ISO: {
+ //
+ // From https://www.w3.org/Bugs/Public/show_bug.cgi?id=21370#c6
+ //
+ // When the 'w' component is used, the convention to be adopted is
+ // that each Monday-to-Sunday week is considered to fall within a
+ // particular month if its Thursday occurs in that month; the weeks
+ // that fall in a particular month under this definition are numbered
+ // starting from 1. Thus, for example, 29 January 2013 falls in week 5
+ // because the Thursday of the relevant week (31 January 2013) is the
+ // fifth Thursday in January, and 1 February 2013 is also in week 5
+ // for the same reason.
+ //
+ mon1_wday = convert_wday_to( mon1_wday, cal );
+ int week = (mday + mon1_wday - 2) / 7 + 1;
+ if ( mon1_wday > iso8601::thu && !--week )
+ return 5; // week is part of previous month
+
+ int const wday =
+ convert_wday_to( time::calc_wday( mday, mon, year ), cal );
+ int const yday = time::calc_yday( mday, mon, year );
+ if ( time::days_in_year( year ) - yday + 1 < iso8601::thu - wday )
+ return 1; // date falls in week 1 of next year
+
+ return week;
+ }
+ default:
+ return -1;
+ }
+}
+
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 );
@@ -121,15 +158,15 @@
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
+ // date falls in week 52 or 53 of 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
+ if ( time::days_in_year( year ) - yday < iso8601::thu - wday ) {
+ // date falls in week 1 of next year
return 1;
}
return (yday + (7 - wday) + (jan1_wday - 1)) / 7
=== modified file 'src/util/time_util.h'
--- src/util/time_util.h 2013-04-10 22:41:09 +0000
+++ src/util/time_util.h 2013-04-23 17:00:37 +0000
@@ -80,10 +80,6 @@
///////////////////////////////////////////////////////////////////////////////
-/**
- * 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[];
@@ -99,7 +95,20 @@
}
/**
- * Calculates the week number for the given date and calendar.
+ * Calculates the week number of the month 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-5] or -1 if it is unknown how to perform the
+ * calculation for \a cal.
+ */
+ int calc_week_in_month( unsigned mday, unsigned mon, unsigned year,
+ type cal );
+
+ /**
+ * Calculates the week number of the year for the given date and calendar.
*
* @param mday The month day [1-31].
* @param mon The month [0-11].
=== modified file 'src/zorbatypes/datetime.h'
--- src/zorbatypes/datetime.h 2013-03-20 15:08:29 +0000
+++ src/zorbatypes/datetime.h 2013-04-23 17:00:37 +0000
@@ -252,8 +252,6 @@
static int getDayOfYear(int year, int month, int day);
- static int getWeekInMonth(int year, int month, int day);
-
protected:
static int parse_date(
const char* str,
@@ -356,8 +354,7 @@
* DateTime does not have a Date or DateTime facet, the function will return -1.
*/
int getDayOfYear() const;
- int getWeekInMonth() const;
-
+
protected:
Duration* toDayTimeDuration() const;
=== modified file 'src/zorbatypes/datetime/datetimetype.cpp'
--- src/zorbatypes/datetime/datetimetype.cpp 2013-04-03 09:33:11 +0000
+++ src/zorbatypes/datetime/datetimetype.cpp 2013-04-23 17:00:37 +0000
@@ -1431,23 +1431,10 @@
}
-int DateTime::getWeekInMonth(int year, int month, int day)
-{
- int const wday = time::calc_wday( 1, month - 1, year );
- return ((day + wday - 2) / 7) + (wday < 5 ? 1 : 0);
-}
-
-
int DateTime::getDayOfYear() const
{
return getDayOfYear(data[YEAR_DATA], data[MONTH_DATA], data[DAY_DATA]);
}
-
-int DateTime::getWeekInMonth() const
-{
- return getWeekInMonth(data[YEAR_DATA], data[MONTH_DATA], data[DAY_DATA]);
-}
-
-} // namespace xqp
+} // namespace zorba
/* vim:set et sw=2 ts=2: */
=== modified file 'test/fots/CMakeLists.txt'
--- test/fots/CMakeLists.txt 2013-04-23 13:55:03 +0000
+++ test/fots/CMakeLists.txt 2013-04-23 17:00:37 +0000
@@ -125,6 +125,7 @@
EXPECTED_FOTS_FAILURE (DISPUTED fn-format-date format-date-en132 21423)
EXPECTED_FOTS_FAILURE (DISPUTED fn-format-date format-date-en133 21423)
EXPECTED_FOTS_FAILURE (DISPUTED fn-format-date format-date-en134 21423)
+EXPECTED_FOTS_FAILURE (DISPUTED fn-format-dateTime format-dateTime-011 21794)
EXPECTED_FOTS_FAILURE (DISPUTED fn-format-integer format-integer-044 21448)
EXPECTED_FOTS_FAILURE (DISPUTED fn-format-date format-date-en152 21558)
EXPECTED_FOTS_FAILURE (DISPUTED fn-format-dateTime format-dateTime-en152 21558)
@@ -164,7 +165,6 @@
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-dateTime format-dateTime-006 0)
-EXPECTED_FOTS_FAILURE (fn-format-dateTime format-dateTime-011 0)
EXPECTED_FOTS_FAILURE (fn-format-number numberformat41 1167427)
EXPECTED_FOTS_FAILURE (fn-format-number numberformat42 1167427)
EXPECTED_FOTS_FAILURE (fn-format-number numberformat60a 1167609)
Follow ups
-
[Merge] lp:~paul-lucas/zorba/bug-1167704 into lp:zorba
From: noreply, 2013-04-23
-
[Merge] lp:~paul-lucas/zorba/bug-1167704 into lp:zorba
From: Zorba Build Bot, 2013-04-23
-
[Merge] lp:~paul-lucas/zorba/bug-1167704 into lp:zorba
From: Zorba Build Bot, 2013-04-23
-
[Merge] lp:~paul-lucas/zorba/bug-1167704 into lp:zorba
From: Paul J. Lucas, 2013-04-23
-
[Merge] lp:~paul-lucas/zorba/bug-1167704 into lp:zorba
From: Zorba Build Bot, 2013-04-23
-
Re: [Merge] lp:~paul-lucas/zorba/bug-1167704 into lp:zorba
From: Zorba Build Bot, 2013-04-23
-
[Merge] lp:~paul-lucas/zorba/bug-1167704 into lp:zorba
From: Zorba Build Bot, 2013-04-23
-
[Merge] lp:~paul-lucas/zorba/bug-1167704 into lp:zorba
From: Nicolae Brinza, 2013-04-23
-
Re: [Merge] lp:~paul-lucas/zorba/bug-1167704 into lp:zorba
From: Nicolae Brinza, 2013-04-23
-
Re: [Merge] lp:~paul-lucas/zorba/bug-1167704 into lp:zorba
From: Nicolae Brinza, 2013-04-23
-
[Merge] lp:~paul-lucas/zorba/bug-1167704 into lp:zorba
From: Zorba Build Bot, 2013-04-23
-
Re: [Merge] lp:~paul-lucas/zorba/bug-1167704 into lp:zorba
From: Zorba Build Bot, 2013-04-23
-
[Merge] lp:~paul-lucas/zorba/bug-1167704 into lp:zorba
From: Zorba Build Bot, 2013-04-23
-
[Merge] lp:~paul-lucas/zorba/bug-1167704 into lp:zorba
From: Zorba Build Bot, 2013-04-23
-
[Merge] lp:~paul-lucas/zorba/bug-1167704 into lp:zorba
From: Paul J. Lucas, 2013-04-23
-
[Merge] lp:~paul-lucas/zorba/bug-1167704 into lp:zorba
From: Zorba Build Bot, 2013-04-23
-
Re: [Merge] lp:~paul-lucas/zorba/bug-1167704 into lp:zorba
From: Zorba Build Bot, 2013-04-23
-
[Merge] lp:~paul-lucas/zorba/bug-1167704 into lp:zorba
From: Zorba Build Bot, 2013-04-23
-
[Merge] lp:~paul-lucas/zorba/bug-1167704 into lp:zorba
From: Paul J. Lucas, 2013-04-23
-
Re: [Merge] lp:~paul-lucas/zorba/bug-1167704 into lp:zorba
From: Paul J. Lucas, 2013-04-23