PerlのDateTime.pmのstrftimeの%Uと%Wについて

ちょっとstrftimeを再発明していて、%Uと%Wの実装でDataTimeをパk…ゲフンゲフン…参考にさせてもらおうとしたところ、挙動がおかしかったのでした。最初は、何かやっちゃったかと思ったのですが、ソースも怪しかったので、どうやらビンゴっぽいです。
テストコードは以下の通り。

use strict;
use warnings;
use POSIX qw(strftime);
use DateTime;

foreach my $year (2005..2008){
	my $t = DateTime->new(
		year  => $year,
		month => 1,
		day   => 1,
		time_zone => 'Asia/Tokyo'
	);

	printf("\n%-15s %8s %8s %8s\n",
		$t->year, "POSIX", "DateTime", "Calc");
	print('-' x 50, "\n");

	foreach my $day (1..8){
		$t->set_day($day);
		my $strftime = strftime('%U:%W', localtime($t->epoch));
		my $datetime = $t->strftime('%U:%W');

		my $u = sprintf("%02d", int(($t->day_of_year - $t->day_of_week % 7 + 6) / 7));
		my $w = sprintf("%02d", int(($t->day_of_year - $t->day_of_week + 7) / 7));
		my $calc = "$u:$w";

		printf("%s(%s) %8s %8s %8s\n",
			$t->ymd('/'), $t->day_abbr, $strftime, $datetime, $calc);
	}
}

実行結果は以下の通り。

2005               POSIX DateTime     Calc
                                                                                                  • -
2005/01/01(Sat) 00:00 00:00 00:00 2005/01/02(Sun) 01:00 01:00 01:00 2005/01/03(Mon) 01:01 01:01 01:01 2005/01/04(Tue) 01:01 01:01 01:01 2005/01/05(Wed) 01:01 01:01 01:01 2005/01/06(Thu) 01:01 01:01 01:01 2005/01/07(Fri) 01:01 01:01 01:01 2005/01/08(Sat) 01:01 01:01 01:01 2006 POSIX DateTime Calc
                                                                                                  • -
2006/01/01(Sun) 01:00 00:00 01:00 2006/01/02(Mon) 01:01 00:00 01:01 2006/01/03(Tue) 01:01 00:00 01:01 2006/01/04(Wed) 01:01 00:00 01:01 2006/01/05(Thu) 01:01 00:00 01:01 2006/01/06(Fri) 01:01 00:00 01:01 2006/01/07(Sat) 01:01 00:00 01:01 2006/01/08(Sun) 02:01 01:00 02:01 2007 POSIX DateTime Calc
                                                                                                  • -
2007/01/01(Mon) 00:01 00:00 00:01 2007/01/02(Tue) 00:01 00:00 00:01 2007/01/03(Wed) 00:01 00:00 00:01 2007/01/04(Thu) 00:01 00:00 00:01 2007/01/05(Fri) 00:01 00:00 00:01 2007/01/06(Sat) 00:01 00:00 00:01 2007/01/07(Sun) 01:01 01:00 01:01 2007/01/08(Mon) 01:02 01:01 01:02 2008 POSIX DateTime Calc
                                                                                                  • -
2008/01/01(Tue) 00:00 00:00 00:00 2008/01/02(Wed) 00:00 00:00 00:00 2008/01/03(Thu) 00:00 00:00 00:00 2008/01/04(Fri) 00:00 00:00 00:00 2008/01/05(Sat) 00:00 00:00 00:00 2008/01/06(Sun) 01:00 01:00 01:00 2008/01/07(Mon) 01:01 01:01 01:01 2008/01/08(Tue) 01:01 01:01 01:01

POSIX」がPOSIXモジュールのstrftimeで、「DateTime」がDateTimeのstrftimeで、Calcは自前で求めたものです。どうやら、日曜日か月曜日で始まる年がアウトの模様です。自前で求めたもの($uと$w)で、とりあえず回避ができます…というか、POSIX使いましょうって事でしょうか。