Skip Menu |

Preferred bug tracker

Please visit the preferred bug tracker to report your issue.

This queue is for tickets about the DateTime CPAN distribution.

Report information
The Basics
Id: 83558
Status: resolved
Priority: 0/
Queue: DateTime

People
Owner: Nobody in particular
Requestors: PJNEWMAN [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Wishlist
Broken in: 0.78
Fixed in: (no value)



Subject: Wishlist, patched: add ability to fetch week_number and week_year for locales with specified first_day_of_week
Our weeks start on a Saturday (don't ask), I've created a locale class overriding first_day_of_week, like so: sub first_day_of_week {6} I assumed this would then change the numbers generated by week/week_number/week_year, but that didn't seem to be the case. The code below can just be added to DateTime somewhere to provide local_ equivalents of the week number methods, returning the local numbers. As commented, it might be able to be optimised a little bit, I'm not quite clear on exactly what some of the maths is doing, to substitute the local first day of week. I guess it may also be worth adding some additional options in some of the formatting stuff, although you don't seem to have many letters left. sub local_week { my $self = shift; unless ( defined $self->{local_c}{local_week_year} ) { my $jan_one_dow_m1 # This algorithm was taken from Date::Calc's DateCalc.c file #= ( ( $self->_ymd2rd( $self->year, 1, 1 ) + 6 ) % 7 ); #Work out how the above needs translating to use the local day, reinterpreted based on Date::Calc::PP's DateCalc_Week_Number = ( ( DateTime->new(year => $self->year, month => 1, day => 1, locale => $self->locale())->local_day_of_week() ) - 1); $self->{local_c}{local_week_number} = int( ( ( $self->{local_c}{day_of_year} - 1 ) + $jan_one_dow_m1 ) / 7 ); $self->{local_c}{local_week_number}++ if $jan_one_dow_m1 < 4; if ( $self->{local_c}{local_week_number} == 0 ) { $self->{local_c}{local_week_year} = $self->year - 1; $self->{local_c}{local_week_number} = $self->_local_weeks_in_year( $self->{local_c}{local_week_year} ); } elsif ($self->{local_c}{local_week_number} == 53 && $self->_local_weeks_in_year( $self->year ) == 52 ) { $self->{local_c}{local_week_number} = 1; $self->{local_c}{local_week_year} = $self->year + 1; } else { $self->{local_c}{local_week_year} = $self->year; } } return @{ $self->{local_c} }{ 'local_week_year', 'local_week_number' }; } sub _local_weeks_in_year { my $self = shift; my $year = shift; #TODO: Later versions of DateTime optimise _weeks_in_year this is copied from to something involving leap years and start days #Possibly adapt that to include this optimisation my $jan_one_dow = #TODO: Older DateTime's have this as the presumably optimised ( ( $self->_ymd2rd( $year, 1, 1 ) + 6 ) % 7 ) + 1; #Work out how that needs translating to use the local day ( DateTime->new(year => $year, month => 1, day => 1, locale => $self->locale())->local_day_of_week() ); my $dec_31_dow = #TODO: Older DateTime's have this as the presumably optimised ( ( $self->_ymd2rd( $year, 12, 31 ) + 6 ) % 7 ) + 1; #Work out how that needs translating to use the local day ( DateTime->new(year => $year, month => 12, day => 31, locale => $self->locale())->local_day_of_week() ); return $jan_one_dow == 4 || $dec_31_dow == 4 ? 53 : 52; } sub local_week_year { ( $_[0]->local_week )[0] } sub local_week_number { ( $_[0]->local_week )[1] }