anewt-developers team mailing list archive
-
anewt-developers team
-
Mailing list archive
-
Message #00259
[Branch ~uws/anewt/anewt.uws] Rev 1781: [core] Add support for year-week dates to AnewtDateTime
------------------------------------------------------------
revno: 1781
committer: Wouter Bolsterlee <uws@xxxxxxxxx>
branch nick: anewt.uws
timestamp: Sat 2010-03-27 21:50:26 +0100
message:
[core] Add support for year-week dates to AnewtDateTime
AnewtDateTime can now parse ISO8601 year-week dates like
2010-W12. The result will be a datetime pointing to the
first day of the week.
modified:
core/datetime.lib.php
core/datetime.test.php
--
lp:anewt
https://code.launchpad.net/~uws/anewt/anewt.uws
Your team Anewt developers is subscribed to branch lp:anewt.
To unsubscribe from this branch go to https://code.launchpad.net/~uws/anewt/anewt.uws/+edit-subscription.
=== modified file 'core/datetime.lib.php'
--- core/datetime.lib.php 2010-02-16 00:06:07 +0000
+++ core/datetime.lib.php 2010-03-27 20:50:26 +0000
@@ -37,7 +37,7 @@
/** Regular expression for day of year */
define('DATETIME_RE_DAY_OF_YEAR', '([0-3]\d{2})');
/** Regular expression for week of year */
-define('DATETIME_RE_WEEK_OF_YEAR', '([0-4]\d|5[0-3])');
+define('DATETIME_RE_WEEK_OF_YEAR', '(0[1-9]|[1-4]\d|5[0-3])');
/** Regular expression for abbreviated day names */
define('DATETIME_RE_DAY_NAMES_ABBR', '(Sun|Mon|Tue|Wed|Thu|Fri|Sat)');
/** Regular expression for abbreviated month names */
@@ -345,6 +345,43 @@
// ISO 8601: 2005-W02
/* TODO: Dates specified by year, week and day. */
+ $pattern = sprintf('/^(%s)-?W(%s)$/', DATETIME_RE_YEAR, DATETIME_RE_WEEK_OF_YEAR);
+ if (preg_match($pattern, $date, $matches) === 1)
+ {
+ $y_not_final = (int) $matches[1];
+ $w = (int) $matches[3];
+
+ /* Too bad, it seems strptime() cannot parse %V correctly, so we
+ * implement our own logic:
+ *
+ * - start with the beginning of the year
+ * - add a very conservative guess of the number of days in the
+ * year based on the number of weeks. We need to make sure the
+ * date is always too early (hence the $w - 2 below)
+ * - repeatedly increment the timestamp with one day until we find
+ * the first matching date
+ */
+
+ /* Find the highest possible week number for the year... */
+ $last_day_of_the_last_week_of_the_year = 31;
+ do {
+ $w_max = (int) strftime('%V', mktime(0, 0, 0, 12, $last_day_of_the_last_week_of_the_year, $y_not_final));
+ $last_day_of_the_last_week_of_the_year--;
+ } while ($w_max == 1);
+
+ /* ... and only proceed if the week number is actually valid for the
+ * specified year. */
+ if ($w <= $w_max)
+ {
+ $ts = mktime(0, 0, 0, 1, 1, $matches[1]);
+ $ts += ($w - 2) * 7 * 24 * 60 * 60;
+
+ while ((int) strftime('%V', $ts) != $w)
+ $ts += 24 * 60 * 60;
+
+ list ($y, $m, $d) = explode('-', strftime('%Y-%m-%d', $ts));
+ }
+ }
// MS SQL default format: Mon Jan 23 00:00:00 2006
=== modified file 'core/datetime.test.php'
--- core/datetime.test.php 2009-07-20 20:39:48 +0000
+++ core/datetime.test.php 2010-03-27 20:50:26 +0000
@@ -53,7 +53,14 @@
f('Fri, 21 Nov 1997 09:55:06 -0600');
f('Fri, 21 Nov 1997 09:55:06 +0630');
-echo '(There should only be empty lines below)', NL;
+f('2010-W01');
+f('2010-W02');
+f('2009W53');
+echo 'This one should be empty:', NL;
+f('2010-W53');
+f('2013-W01');
+
+echo 'There should only be empty lines below:', NL;
f(null);