File Coverage

blib/lib/DateTimeX/strftimeq.pm
Criterion Covered Total %
statement 40 40 100.0
branch 5 8 62.5
condition 7 11 63.6
subroutine 8 8 100.0
pod 1 1 100.0
total 61 68 89.7


line stmt bran cond sub pod time code
1             ## no critic: Modules::ProhibitAutomaticExportation
2              
3             package DateTimeX::strftimeq;
4              
5             our $DATE = '2019-11-20'; # DATE
6             our $DIST = 'DateTimeX-strftimeq'; # DIST
7             our $VERSION = '0.003'; # VERSION
8              
9 1     1   485217 use 5.010001;
  1         10  
10 1     1   4 use strict;
  1         2  
  1         17  
11 1     1   4 use warnings;
  1         1  
  1         21  
12              
13 1     1   4 use POSIX ();
  1         2  
  1         14  
14 1     1   4 use Scalar::Util 'blessed';
  1         2  
  1         39  
15              
16 1     1   5 use Exporter 'import';
  1         1  
  1         234  
17             our @EXPORT = qw(strftimeq);
18              
19             our $regex = qr{
20             (?(DEFINE)
21             (?<def_not_close_paren> [^)]+)
22             (?<def_code> ((?&def_not_close_paren) | \((?&def_code)\))*)
23             )
24             (?<all>
25              
26             (?<convspec>
27             %
28             (?<flags> [_0^#-]+)?
29             (?<width> [0-9]+)?
30             (?<alt>[EO])?
31             (?<convletter> [%aAbBcCdDeEFgGhHIjklmMnOpPrRsStTuUVwWxXyYZz+])
32             )|
33             (?<qconvspec>
34             %\(
35             (?<code> (?&def_code))
36             \)q)
37             )
38             }x;
39              
40             # faster version, without using named capture
41             if (0) {
42             }
43              
44             sub strftimeq {
45 12     12 1 2849 my ($format, @time) = @_;
46              
47 12         41 my ($dt, %compiled_code);
48              
49 12 50 66     72 if (@time == 1 && blessed $time[0] && $time[0]->isa('DateTime')) {
      66        
50 6         15 $dt = $time[0];
51 6         17 @time = (
52             $dt->second,
53             $dt->minute,
54             $dt->hour,
55             $dt->day,
56             $dt->month-1,
57             $dt->year-1900,
58             );
59             }
60              
61 12         202 $format =~ s{$regex}{
62             # for faster acccess
63 1     1   397 my %m = %+;
  1         301  
  1         204  
  38         335  
64              
65             # DEBUG
66             #use DD; dd \%m;
67              
68 38 100       109 if (exists $m{code}) {
69 6         29 require DateTime;
70 6   66     27 $dt //= DateTime->new(
71             second => $time[0],
72             minute => $time[1],
73             hour => $time[2],
74             day => $time[3],
75             month => $time[4]+1,
76             year => $time[5]+1900,
77             );
78 6 50       725 unless (defined $compiled_code{$m{code}}) {
79 6         363 $compiled_code{$m{code}} = eval "sub { $m{code} }";
80 6 50       18 die "Can't compile code in $m{all}: $@" if $@;
81             }
82 6         8 local $_ = $dt;
83 6         106 my $code_res = $compiled_code{$m{code}}->(
84             time => \@time,
85             dt => $dt,
86             );
87 6   50     83 $code_res //= "";
88 6         11 $code_res =~ s/%/%%/g;
89 6         21 $code_res;
90             } else {
91 32         151 $m{all};
92             }
93             }xego;
94              
95 12         456 POSIX::strftime($format, @time);
96             }
97              
98             1;
99             # ABSTRACT: POSIX::strftime() with support for embedded perl code in %(...)q
100              
101             __END__
102              
103             =pod
104              
105             =encoding UTF-8
106              
107             =head1 NAME
108              
109             DateTimeX::strftimeq - POSIX::strftime() with support for embedded perl code in %(...)q
110              
111             =head1 VERSION
112              
113             This document describes version 0.003 of DateTimeX::strftimeq (from Perl distribution DateTimeX-strftimeq), released on 2019-11-20.
114              
115             =head1 SYNOPSIS
116              
117             use DateTimeX::strftimeq; # by default exports strftimeq()
118              
119             my @time = localtime();
120             print strftimeq '<%6Y-%m-%d>', @time; # <002019-11-19>
121             print strftimeq '<%6Y-%m-%d%( $_->day_of_week eq 7 ? "sun" : "" )q>', @time; # <002019-11-19>
122             print strftimeq '<%6Y-%m-%d%( $_->day_of_week eq 2 ? "tue" : "" )q>', @time; # <002019-11-19tue>
123              
124             You can also pass DateTime object instead of ($second, $minute, $hour, $day,
125             $month, $year):
126              
127             print strftimeq '<%6Y-%m-%d>', $dt; # <002019-11-19>
128              
129             =head1 DESCRIPTION
130              
131             This module provides C<strftimeq()> which extends L<POSIX>'s C<strftime()> with
132             a conversion: C<%(...)q>. Inside the parenthesis, you can specify Perl code. The
133             Perl code will receive a hash argument (C<%args>) with the following keys:
134             C<time> (arrayref, the arguments passed to strftimeq() except for the first),
135             C<dt> (L<DateTime> object). For convenience, C<$_> will also be locally set to
136             the DateTime object.
137              
138             =head1 FUNCTIONS
139              
140             =head2 strftimeq
141              
142             Usage:
143              
144             $str = strftimeq $fmt, $sec, $min, $hour, $mday, $mon, $year;
145             $str = strftimeq $fmt, $dt;
146              
147             =head1 HOMEPAGE
148              
149             Please visit the project's homepage at L<https://metacpan.org/release/DateTimeX-strftimeq>.
150              
151             =head1 SOURCE
152              
153             Source repository is at L<https://github.com/perlancar/perl-DateTimeX-strftimeq>.
154              
155             =head1 BUGS
156              
157             Please report any bugs or feature requests on the bugtracker website L<https://rt.cpan.org/Public/Dist/Display.html?Name=DateTimeX-strftimeq>
158              
159             When submitting a bug or request, please include a test-file or a
160             patch to an existing test-file that illustrates the bug or desired
161             feature.
162              
163             =head1 SEE ALSO
164              
165             L<POSIX>'s C<strftime()>
166              
167             L<DateTime>
168              
169             =head1 AUTHOR
170              
171             perlancar <perlancar@cpan.org>
172              
173             =head1 COPYRIGHT AND LICENSE
174              
175             This software is copyright (c) 2019 by perlancar@cpan.org.
176              
177             This is free software; you can redistribute it and/or modify it under
178             the same terms as the Perl 5 programming language system itself.
179              
180             =cut