On Wed Jan 25 16:53:00 2012, DOUGW wrote:
Show quoted text> On Wed Jan 25 15:45:23 2012, DOUGW wrote:
>
> I'll keep trying.
This works. The tests even test a list of formats to strftime.
diff -r -u DateTime-0.72/lib/DateTime.pm Tst-DateTime-0.72/lib/DateTime.pm
--- DateTime-0.72/lib/DateTime.pm Thu Jan 5 12:42:04 2012
+++ Tst-DateTime-0.72/lib/DateTime.pm Wed Jan 25 15:17:30 2012
@@ -999,7 +999,6 @@
'm' => sub { sprintf( '%02d', $_[0]->month ) },
'M' => sub { sprintf( '%02d', $_[0]->minute ) },
'n' => sub {"\n"}, # should this be OS-sensitive?
- 'N' => \&_format_nanosecs,
'p' => sub { $_[0]->am_or_pm() },
'P' => sub { lc $_[0]->am_or_pm() },
'r' => sub { $_[0]->strftime('%I:%M:%S %p') },
@@ -1045,6 +1044,15 @@
my @r;
foreach my $p (@patterns) {
+
+ my $tmp_self = $self;
+ if ( $p =~ /(?<!%)((?:%%)*)%(\d*)N/ ) {
+ my ( $pct, $precision ) = ($1, $2);
+ my ($n, $carry) = _format_nanosecs($self, $precision);
+ $p =~ s/(?<!%)$pct%${precision}N/$n/;
+ $tmp_self = $tmp_self->clone->add(seconds => 1) if $carry;
+ }
+
$p =~ s/
(?:
%{(\w+)} # method name like %{day_name}
@@ -1055,11 +1063,11 @@
)
/
( $1
- ? ( $self->can($1) ? $self->$1() : "\%{$1}" )
+ ? ( $tmp_self->can($1) ? $tmp_self->$1() : "\%{$1}" )
: $2
- ? ( $strftime_patterns{$2} ? $strftime_patterns{$2}->($self) : "\%$2" )
+ ? ( $strftime_patterns{$2} ? $strftime_patterns{$2}->($tmp_self) : "\%$2" )
: $3
- ? $strftime_patterns{N}->($self, $3)
+ ? $strftime_patterns{N}->($tmp_self, $3)
: '' # this won't happen
)
/sgex;
@@ -1299,14 +1307,14 @@
sub _format_nanosecs {
my $self = shift;
- my $precision = @_ ? shift : 9;
+ my $precision = @_ ? shift || 9 : 9;
my $divide_by = 10**( 9 - $precision );
- return sprintf(
+ my $t = sprintf(
'%0' . $precision . 'u',
- round( $self->{rd_nanosecs} / $divide_by )
- );
+ round( $self->{rd_nanosecs} / $divide_by ) );
+ return ( length($t) > $precision ) ? ("0" x $precision,1) : $t;
}
sub epoch {
diff -r -u DateTime-0.72/t/13strftime.t Tst-DateTime-0.72/t/13strftime.t
--- DateTime-0.72/t/13strftime.t Thu Jan 5 12:42:04 2012
+++ Tst-DateTime-0.72/t/13strftime.t Wed Jan 25 14:35:07 2012
@@ -170,6 +170,22 @@
}
}
+{
+ for my $i (2..9) {
+ my $dt = DateTime->new( year => 2012, nanosecond => "9" x $i . "0" x (9 - $i) );
+ my $precision = $i - 1;
+ my $spec1 = '%S.%' . $precision . 'N';
+ my $spec2 = '%S.%' . ($precision + 1) . 'N';
+ my $expect1 = '01.' . "0" x $precision;
+ my $expect2 = '00.' . "9" x ( $precision + 1 );
+ my @dt_str = $dt->strftime($spec1, $spec1, $spec2);
+ is( scalar(@dt_str), 3, "strftime correct number of results");
+ is( $dt_str[0], $expect1, "strftime $spec1 nanoseconds rounding up to a second" );
+ is( $dt_str[1], $expect1, "strftime $spec1 nanoseconds rounding up to a second - repeat" );
+ is( $dt_str[2], $expect2, "strftime $spec2 nanoseconds no round" );
+ }
+}
+
done_testing();
# add these if we do roman-numeral stuff