Skip to content

Commit 1bafab3

Browse files
cpan/Time-Piece - Update to version 1.40
1.40 2025-11-08 - strptime: locale parse fixes (GH86) - Add fullmon_list() and fullday_list() (GH85) - Fix null deref (GH47) - Remove locale-dependent flags (GH71) - Document flags for strftime/strptime (GH83)
1 parent b586026 commit 1bafab3

File tree

5 files changed

+253
-103
lines changed

5 files changed

+253
-103
lines changed

Porting/Maintainers.pl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1256,8 +1256,8 @@ package Maintainers;
12561256
},
12571257

12581258
'Time::Piece' => {
1259-
'DISTRIBUTION' => 'ESAYM/Time-Piece-1.39.tar.gz',
1260-
'SYNCINFO' => 'jkeenan on Sat Oct 25 12:20:55 2025',
1259+
'DISTRIBUTION' => 'ESAYM/Time-Piece-1.40.tar.gz',
1260+
'SYNCINFO' => 'tib on Wed Nov 12 10:06:05 2025',
12611261
'FILES' => q[cpan/Time-Piece],
12621262
'EXCLUDED' => [ qw[reverse_deps.txt] ],
12631263
},

cpan/Time-Piece/Piece.pm

Lines changed: 118 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ our %EXPORT_TAGS = (
1919
':override' => 'internal',
2020
);
2121

22-
our $VERSION = '1.39';
22+
our $VERSION = '1.40';
2323

2424
XSLoader::load( 'Time::Piece', $VERSION );
2525

@@ -462,16 +462,6 @@ sub month_last_day {
462462
}
463463

464464
my $strftime_trans_map = {
465-
'c' => sub {
466-
my ( $format ) = @_;
467-
if($LOCALE->{PM} && $LOCALE->{AM}){
468-
$format =~ s/%c/%a %d %b %Y %I:%M:%S %p/;
469-
}
470-
else{
471-
$format =~ s/%c/%a %d %b %Y %H:%M:%S/;
472-
}
473-
return $format;
474-
},
475465
'e' => sub {
476466
my ( $format, $time ) = @_;
477467
my $day = sprintf( "%2d", $time->[c_mday] );
@@ -543,22 +533,9 @@ my $strftime_trans_map = {
543533
},
544534
'V' => sub {
545535
my ( $format, $time ) = @_;
546-
my $week = sprintf( "%02d", $time->week() );
547-
$format =~ s/%V/$week/ if $IS_WIN32;
548-
return $format;
549-
},
550-
'x' => sub {
551-
my ( $format ) = @_;
552-
$format =~ s/%x/%a %d %b %Y/;
553-
return $format;
554-
},
555-
'X' => sub {
556-
my ( $format ) = @_;
557-
if($LOCALE->{PM} && $LOCALE->{AM}){
558-
$format =~ s/%X/%I:%M:%S %p/;
559-
}
560-
else{
561-
$format =~ s/%X/%H:%M:%S/;
536+
if ($IS_WIN32) {
537+
my $week = sprintf( "%02d", $time->week() );
538+
$format =~ s/%V/$week/;
562539
}
563540
return $format;
564541
},
@@ -675,6 +652,26 @@ sub mon_list {
675652
return @old;
676653
}
677654

655+
sub fullday_list {
656+
shift if ref($_[0]) && $_[0]->isa(__PACKAGE__); # strip first if called as a method
657+
my @old = @FULLDAY_LIST;
658+
if (@_) {
659+
@FULLDAY_LIST = @_;
660+
&Time::Piece::_default_locale();
661+
}
662+
return @old;
663+
}
664+
665+
sub fullmon_list {
666+
shift if ref($_[0]) && $_[0]->isa(__PACKAGE__); # strip first if called as a method
667+
my @old = @FULLMON_LIST;
668+
if (@_) {
669+
@FULLMON_LIST = @_;
670+
&Time::Piece::_default_locale();
671+
}
672+
return @old;
673+
}
674+
678675
sub time_separator {
679676
shift if ref($_[0]) && $_[0]->isa(__PACKAGE__);
680677
my $old = $TIME_SEP;
@@ -1046,6 +1043,24 @@ The following methods are available on the object:
10461043
# of the full POSIX extension)
10471044
$t->strftime() # "Tue, 29 Feb 2000 12:34:56 GMT"
10481045
1046+
=head3 strftime Format Flags
1047+
1048+
The C<strftime> method calls your system's native C<strftime()> implementation,
1049+
so the supported format flags and their behavior will depend on your platform.
1050+
1051+
B<Platform Variability:> Some format flags behave differently or may be missing
1052+
entirely on certain platforms. The following flags are known to have
1053+
platform-specific issues: C<%e>, C<%D>, C<%F>, C<%k>, C<%l>, C<%P>, C<%r>, C<%R>,
1054+
C<%s>, C<%T>, C<%u>, C<%V>, C<%z>, and C<%Z>.
1055+
1056+
To mitigate these differences, C<Time::Piece> includes a special translation layer
1057+
that attempts to unify behavior across platforms. For example, C<%F> is not
1058+
available on some Microsoft platforms, so it is automatically converted to
1059+
C<"%Y-%m-%d"> internally before calling the system's C<strftime()>.
1060+
1061+
For a complete list of format flags supported by your system, consult your
1062+
platform's C<strftime(3)> manual page (C<man strftime> on Unix-like systems).
1063+
10491064
=head2 Epoch and Calendar Calculations
10501065
10511066
$t->epoch # seconds since the epoch
@@ -1085,10 +1100,12 @@ the actual offset including any DST adjustment.
10851100
10861101
=head2 Global Configuration
10871102
1088-
$t->time_separator($s) # set the default separator (default ":")
1089-
$t->date_separator($s) # set the default separator (default "-")
1090-
$t->day_list(@days) # set the default weekdays
1091-
$t->mon_list(@days) # set the default months
1103+
$t->time_separator($s) # set the default separator (default ":")
1104+
$t->date_separator($s) # set the default separator (default "-")
1105+
$t->day_list(@days) # set the names used by wdayname()
1106+
$t->mon_list(@months) # set the names used by month()
1107+
$t->fullday_list(@days) # set the names used by fullday()
1108+
$t->fullmon_list(@months) # set the names used by fullmonth()
10921109
10931110
=head2 Parsing
10941111
@@ -1207,6 +1224,58 @@ The default format string is C<"%a, %d %b %Y %H:%M:%S %Z">, so these are equival
12071224
my $t1 = Time::Piece->strptime($string);
12081225
my $t2 = Time::Piece->strptime($string, "%a, %d %b %Y %H:%M:%S %Z");
12091226
1227+
=head2 Supported Format Flags
1228+
1229+
C<Time::Piece> uses a custom C<strptime()> implementation that supports the
1230+
following format flags:
1231+
1232+
Flag Description
1233+
---- -----------
1234+
%% Literal '%' character
1235+
%a Abbreviated weekday name (Mon, Tue, etc.)
1236+
%A Full weekday name (Monday, Tuesday, etc.)
1237+
%b Abbreviated month name (Jan, Feb, etc.)
1238+
%B Full month name (January, February, etc.)
1239+
%C Century number (00-99)
1240+
%d Day of month (01-31)
1241+
%D Equivalent to %m/%d/%y
1242+
%e Day of month ( 1-31, space-padded)
1243+
%F Equivalent to %Y-%m-%d (ISO 8601 date format)
1244+
%h Abbreviated month name (same as %b)
1245+
%H Hour in 24-hour format (00-23)
1246+
%I Hour in 12-hour format (01-12)
1247+
%j Day of year (001-366)
1248+
%k Hour in 24-hour format ( 0-23, space-padded)
1249+
%l Hour in 12-hour format ( 1-12, space-padded)
1250+
%m Month number (01-12)
1251+
%M Minute (00-59)
1252+
%n Any whitespace
1253+
%p AM/PM indicator
1254+
%P Alt AM/PM indicator
1255+
%r Time in AM/PM format (%I:%M:%S %p, or %H:%M:%S if locale has no AM/PM)
1256+
%R Equivalent to %H:%M
1257+
%s Seconds since Unix epoch (1970-01-01 00:00:00 UTC)
1258+
%S Second (00-60, allowing for leap seconds)
1259+
%t Any whitespace (same as %n)
1260+
%T Equivalent to %H:%M:%S
1261+
%u Weekday as number (1-7, Monday = 1)
1262+
%w Weekday as number (0-6, Sunday = 0)
1263+
%y Year within century (00-99). Values 00-68 are 2000-2068, 69-99 are 1969-1999
1264+
%Y Year with century (e.g., 2024)
1265+
%z Timezone offset (+HHMM, -HHMM, +HH:MM, or -HH:MM)
1266+
%Z Timezone name (only GMT and UTC recognized; others parsed but ignored)
1267+
1268+
B<Unsupported Locale Flags:> The format flags C<%c>, C<%x>, and C<%X> are B<not>
1269+
supported as they are highly locale-dependent and have inconsistent formats
1270+
across systems. However, you can construct equivalent formats using the individual
1271+
flags listed above. For example, C<%c> is typically equivalent to something like:
1272+
1273+
"%a %b %e %H:%M:%S %Y" # e.g., "Tue Feb 29 12:34:56 2000"
1274+
1275+
B<Note:> C<%U>, C<%V>, and C<%W> (week number formats) are parsed but not fully
1276+
implemented in the strptime logic, as they require additional date components
1277+
to calculate the actual date.
1278+
12101279
=head2 GMT vs Local Time
12111280
12121281
By default, C<strptime> returns GMT objects when called as a class method:
@@ -1226,6 +1295,9 @@ To get local time objects, you can:
12261295
my $local = localtime();
12271296
Time::Piece->strptime($string, $format, { defaults => $local })
12281297
1298+
The islocal and defaults options were added in version 1.37; the instance
1299+
method can be used for compatibility with previous versions.
1300+
12291301
=head2 Timezone Parsing with %z and %Z
12301302
12311303
Time::Piece's C<strptime()> function has some limited support for parsing timezone
@@ -1341,17 +1413,29 @@ B<Note:> This is a global change affecting all Time::Piece instances.
13411413
13421414
You can also override the day/month names manually:
13431415
1344-
my @days = qw( Domingo Lunes Martes Miercoles Jueves Viernes Sabado );
1416+
# Abbreviated day names
1417+
my @days = qw( Dom Lun Mar Mie Jue Vie Sab );
13451418
my $spanish_day = localtime->day(@days);
13461419
1347-
my @months = qw( Enero Febrero Marzo Abril Mayo Junio
1348-
Julio Agosto Septiembre Octubre Noviembre Diciembre );
1420+
# Full day names
1421+
my @fulldays = qw( Domingo Lunes Martes Miercoles Jueves Viernes Sabado );
1422+
my $spanish_fullday = localtime->fullday(@fulldays);
1423+
1424+
# Abbreviated month names
1425+
my @months = qw( Ene Feb Mar Abr May Jun Jul Ago Sep Oct Nov Dic );
13491426
print localtime->month(@months);
13501427
1428+
# Full month names
1429+
my @fullmonths = qw( Enero Febrero Marzo Abril Mayo Junio
1430+
Julio Agosto Septiembre Octubre Noviembre Diciembre );
1431+
print localtime->fullmonth(@fullmonths);
1432+
13511433
Set globally with:
13521434
13531435
Time::Piece::day_list(@days);
13541436
Time::Piece::mon_list(@months);
1437+
Time::Piece::fullday_list(@fulldays);
1438+
Time::Piece::fullmon_list(@fullmonths);
13551439
13561440
=head1 Global Overriding
13571441

0 commit comments

Comments
 (0)