Skip to content

Commit c9b5882

Browse files
authored
Merge pull request #84 from Dual-Life/feature/1_39
Release 1.39
2 parents b7e8df6 + 0781d54 commit c9b5882

10 files changed

Lines changed: 295 additions & 252 deletions

File tree

Changes

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
Revision history for Time-Piece
22

3+
1.39 2025-10-24
4+
- strptime: allow year < 1900 (GH56)
5+
- add add_days() (GH65)
6+
- strptime(): More %z formats (GH74)
7+
- Test failures in 11strptime_defaults.t (GH81)
8+
- XS cleanup (GH80)
9+
- Remove parse()
10+
311
1.38 2025-10-18
412
- Doc updates
513
- Fix Windows-2025 crash with %P

MANIFEST

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,4 @@ t/10overload.t
2121
t/11strptime_defaults.t
2222
t/12strptime_timezones.t
2323
t/13date_arithmetic_edge_cases.t
24-
t/99legacy.t
2524
t/lib/Time/Piece/Twin.pm

Piece.pm

Lines changed: 87 additions & 88 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.38';
22+
our $VERSION = '1.39';
2323

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

@@ -102,24 +102,6 @@ sub new {
102102
return bless $self, ref($class) || $class;
103103
}
104104

105-
sub parse {
106-
my $proto = shift;
107-
my $class = ref($proto) || $proto;
108-
my @components;
109-
110-
warnings::warnif("deprecated",
111-
"parse() is deprecated, use strptime() instead.");
112-
113-
if (@_ > 1) {
114-
@components = @_;
115-
}
116-
else {
117-
@components = shift =~ /(\d+)$DATE_SEP(\d+)$DATE_SEP(\d+)(?:(?:T|\s+)(\d+)$TIME_SEP(\d+)(?:$TIME_SEP(\d+)))/;
118-
@components = reverse(@components[0..5]);
119-
}
120-
return $class->new( timelocal(@components ));
121-
}
122-
123105
sub _mktime {
124106
my ($class, $time, $islocal) = @_;
125107

@@ -791,6 +773,14 @@ sub compare {
791773
return $lhs <=> $rhs;
792774
}
793775

776+
sub add_days {
777+
my ( $time, $num_days ) = @_;
778+
779+
croak("add_days requires a number of days") unless defined($num_days);
780+
781+
return add( $time, $num_days * ONE_DAY );
782+
}
783+
794784
sub add_months {
795785
my ($time, $num_months) = @_;
796786

@@ -1089,6 +1079,9 @@ the actual offset including any DST adjustment.
10891079
10901080
$t->is_leap_year # true if it's a leap year
10911081
$t->month_last_day # 28-31
1082+
$t->add_days # Add days
1083+
$t->add_months # Add months
1084+
$t->add_years # Add years
10921085
10931086
=head2 Global Configuration
10941087
@@ -1122,6 +1115,7 @@ The following are valid ($t1 and $t2 are Time::Piece objects):
11221115
$t1 - $t2; # returns Time::Seconds object
11231116
$t1 - 42; # returns Time::Piece object
11241117
$t1 + 533; # returns Time::Piece object
1118+
$t1->add_days(2); # returns Time::Piece object
11251119
11261120
B<Note:> All arithmetic uses epoch seconds (UTC). When daylight saving time
11271121
(DST) changes occur:
@@ -1213,40 +1207,6 @@ The default format string is C<"%a, %d %b %Y %H:%M:%S %Z">, so these are equival
12131207
my $t1 = Time::Piece->strptime($string);
12141208
my $t2 = Time::Piece->strptime($string, "%a, %d %b %Y %H:%M:%S %Z");
12151209
1216-
=head2 Handling Partial Dates
1217-
1218-
When parsing incomplete date strings, you can provide defaults for missing
1219-
components in several ways:
1220-
1221-
B<Array Reference> - Standard time components (as returned by localtime):
1222-
1223-
my @defaults = localtime();
1224-
my $t = Time::Piece->strptime("15 Mar", "%d %b",
1225-
{ defaults => \@defaults });
1226-
1227-
B<Hash Reference> - Specify only needed components:
1228-
1229-
my $t = Time::Piece->strptime("15 Mar", "%d %b",
1230-
{ defaults => {
1231-
year => 2023,
1232-
hour => 14,
1233-
min => 30
1234-
} });
1235-
1236-
Valid keys: C<sec>, C<min>, C<hour>, C<mday>, C<mon>, C<year>, C<wday>, C<yday>, C<isdst>
1237-
1238-
B<Note>: For the C<year> parameter numbers less than 1000 are treated as an
1239-
offset from 1900. Whereas numbers larger than 1000 are treated as the actual year.
1240-
1241-
B<Time::Piece Object> - Uses all components from the object:
1242-
1243-
my $base = localtime();
1244-
my $t = Time::Piece->strptime("15 Mar", "%d %b",
1245-
{ defaults => $base });
1246-
1247-
B<Note:> In all cases, parsed values always override defaults. Only missing
1248-
components use default values.
1249-
12501210
=head2 GMT vs Local Time
12511211
12521212
By default, C<strptime> returns GMT objects when called as a class method:
@@ -1266,40 +1226,6 @@ To get local time objects, you can:
12661226
my $local = localtime();
12671227
Time::Piece->strptime($string, $format, { defaults => $local })
12681228
1269-
The islocal and defaults options were added in version 1.37; the instance
1270-
method can be used for compatibility with previous versions.
1271-
1272-
=head3 Locale Considerations
1273-
1274-
By default, C<strptime> only parses English day and month names, while
1275-
C<strftime> uses your system locale. This can cause parsing failures for
1276-
non-English dates.
1277-
1278-
To parse localized dates, call C<Time::Piece-E<gt>use_locale()> to build
1279-
a list of your locale's day and month names:
1280-
1281-
# Enable locale-aware parsing (global setting)
1282-
Time::Piece->use_locale();
1283-
1284-
# Now strptime can parse names in your system locale
1285-
my $t = Time::Piece->strptime("15 Marzo 2024", "%d %B %Y");
1286-
1287-
B<Note:> This is a global change affecting all Time::Piece instances.
1288-
1289-
You can also override the day/month names manually:
1290-
1291-
my @days = qw( Domingo Lunes Martes Miercoles Jueves Viernes Sabado );
1292-
my $spanish_day = localtime->day(@days);
1293-
1294-
my @months = qw( Enero Febrero Marzo Abril Mayo Junio
1295-
Julio Agosto Septiembre Octubre Noviembre Diciembre );
1296-
print localtime->month(@months);
1297-
1298-
Set globally with:
1299-
1300-
Time::Piece::day_list(@days);
1301-
Time::Piece::mon_list(@months);
1302-
13031229
=head2 Timezone Parsing with %z and %Z
13041230
13051231
Time::Piece's C<strptime()> function has some limited support for parsing timezone
@@ -1310,7 +1236,8 @@ Consider the current implementation somewhat "alpha" and in need of feedback.
13101236
13111237
=head3 Numeric Offsets (%z)
13121238
1313-
The C<%z> specifier parses numeric timezone offsets (format: C<+HHMM> or C<-HHMM>):
1239+
The C<%z> specifier parses numeric timezone offsets
1240+
(format: C<[+-]HHMM>, C<[+-]HH:MM>, or C<[+-]HH>):
13141241
13151242
my $t = Time::Piece->strptime("2024-01-15 15:30:00 +0500",
13161243
"%Y-%m-%d %H:%M:%S %z");
@@ -1351,9 +1278,81 @@ Other timezone names are parsed B<but ignored>:
13511278
"%Y-%m-%d %H:%M:%S %Z");
13521279
print $t2->hour; # prints 10 (PST ignored - no adjustment)
13531280
1281+
# Parse and convert to local timezone
1282+
my $t3 = Time::Piece->strptime("2024-01-15 15:30:00 UTC",
1283+
"%Y-%m-%d %H:%M:%S %Z",
1284+
{ islocal => 1 });
1285+
print $t3->hour; # prints 10:30 UTC converted to your local timezone
1286+
1287+
13541288
B<Note:> Full timezone name support is not currently implemented. For reliable
13551289
timezone handling beyond GMT/UTC, consider using the L<DateTime> module.
13561290
1291+
=head2 Handling Partial Dates
1292+
1293+
When parsing incomplete date strings, you can provide defaults for missing
1294+
components in several ways:
1295+
1296+
B<Array Reference> - Standard time components (as returned by localtime):
1297+
1298+
my @defaults = localtime();
1299+
my $t = Time::Piece->strptime("15 Mar", "%d %b",
1300+
{ defaults => \@defaults });
1301+
1302+
B<Hash Reference> - Specify only needed components:
1303+
1304+
my $t = Time::Piece->strptime("15 Mar", "%d %b",
1305+
{ defaults => {
1306+
year => 2023,
1307+
hour => 14,
1308+
min => 30
1309+
} });
1310+
1311+
Valid keys: C<sec>, C<min>, C<hour>, C<mday>, C<mon>, C<year>, C<wday>, C<yday>, C<isdst>
1312+
1313+
B<Note>: For the C<year> parameter numbers less than 1000 are treated as an
1314+
offset from 1900. Whereas numbers larger than 1000 are treated as the actual year.
1315+
1316+
B<Time::Piece Object> - Uses all components from the object:
1317+
1318+
my $base = localtime();
1319+
my $t = Time::Piece->strptime("15 Mar", "%d %b",
1320+
{ defaults => $base });
1321+
1322+
B<Note:> In all cases, parsed values always override defaults. Only missing
1323+
components use default values.
1324+
1325+
=head2 Locale Considerations
1326+
1327+
By default, C<strptime> only parses English day and month names, while
1328+
C<strftime> uses your system locale. This can cause parsing failures for
1329+
non-English dates.
1330+
1331+
To parse localized dates, call C<Time::Piece-E<gt>use_locale()> to build
1332+
a list of your locale's day and month names:
1333+
1334+
# Enable locale-aware parsing (global setting)
1335+
Time::Piece->use_locale();
1336+
1337+
# Now strptime can parse names in your system locale
1338+
my $t = Time::Piece->strptime("15 Marzo 2024", "%d %B %Y");
1339+
1340+
B<Note:> This is a global change affecting all Time::Piece instances.
1341+
1342+
You can also override the day/month names manually:
1343+
1344+
my @days = qw( Domingo Lunes Martes Miercoles Jueves Viernes Sabado );
1345+
my $spanish_day = localtime->day(@days);
1346+
1347+
my @months = qw( Enero Febrero Marzo Abril Mayo Junio
1348+
Julio Agosto Septiembre Octubre Noviembre Diciembre );
1349+
print localtime->month(@months);
1350+
1351+
Set globally with:
1352+
1353+
Time::Piece::day_list(@days);
1354+
Time::Piece::mon_list(@months);
1355+
13571356
=head1 Global Overriding
13581357
13591358
To override localtime and gmtime everywhere:

0 commit comments

Comments
 (0)