File Coverage

blib/lib/Time/Piece/Guess.pm
Criterion Covered Total %
statement 38 163 23.3
branch 53 214 24.7
condition 4 15 26.6
subroutine 6 6 100.0
pod 2 2 100.0
total 103 400 25.7


line stmt bran cond sub pod time code
1             package Time::Piece::Guess;
2              
3 2     2   154232 use 5.006;
  2         10  
4 2     2   15 use strict;
  2         2  
  2         67  
5 2     2   11 use warnings;
  2         4  
  2         77  
6 2     2   572 use Time::Piece;
  2         12647  
  2         10  
7              
8             =head1 NAME
9              
10             Time::Piece::Guess - Compares the passed string against common patterns and returns a format to use with Time::Piece or object
11              
12             =head1 VERSION
13              
14             Version 0.1.1
15              
16             =cut
17              
18             our $VERSION = '0.1.1';
19              
20             =head1 SYNOPSIS
21              
22             use Time::Piece::Guess;
23             use Time::Piece;
24              
25             my $string='2023-02-27T11:00:18.33';
26             my ($format, $ms_clean_regex) = Time::Piece::Guess->guess('2023-02-27T11:00:18');
27             # apply the regex if needed
28             if (defined( $ms_clean_regex )){
29             $string=~s/$ms_clean_regex//;
30             }
31             my $tp_object;
32             if (!defined( $format )){
33             print "No matching format found\n";
34             }else{
35             $tp_object = Time::Piece->strptime( '2023-02-27T11:00:18' , $format );
36             }
37              
38             $tp_object = Time::Piece::Guess->guess_to_object('2023-02-27T11:00:18');
39             if (!defined( $tp_object )){
40             print "No matching format found\n";
41             }
42              
43             =head1 METHODS
44              
45             =head2 guess
46              
47             Compares it against various patterns and returns the matching string for use with
48             parsing that format.
49              
50             If one can't be matched, undef is returned. Two values are returned. The first is the format
51             of it and the second is a regexp to remove microseconds if needed.
52              
53             This will attempt to remove microseconds as below.
54              
55             my $string='2023-02-27T11:00:18.33';
56             my ($format, $ms_clean_regex) = Time::Piece::Guess->guess('2023-02-27T11:00:18');
57             # apply the regex if needed
58             if (defined( $ms_clean_regex )){
59             $string=~s/$ms_clean_regex//;
60             }
61             my $tp_object;
62             if (!defined( $format )){
63             print "No matching format found\n";
64             }else{
65             $tp_object = Time::Piece->strptime( '2023-02-27T11:00:18' , $format );
66             }
67              
68              
69             Worth noting that Time::Piece as of the writing of this has a bug in which if just hours
70             are present for %z and minutes are not it will error.
71              
72             if ($format =~ /\%z/ && $string =~ /[-+]\d\d$/) {
73             sstring=$string.'00';
74             }
75              
76              
77             =cut
78              
79             sub guess {
80 3     3 1 118 my $string = $_[1];
81              
82 3 50       10 if ( !defined($string) ) {
83 0         0 return undef;
84             }
85              
86             # remove micro seconds if they are present
87 3         5 my $regex;
88 3 100       11 if ( $string =~ /\.\d+/ ) {
89 1         4 $regex = qr/\.\d+/;
90 1         7 $string =~ s/$regex//;
91             }
92              
93 3         4 my $format;
94 3 50       88 if ( $string =~ /^\d+$/ ) {
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
95 0         0 $format = '%s';
96             } elsif ( $string =~ /^\d\d\d\d\-\d\d-\d\d\ [0-2][0-9]\:[0-5][0-9][-+]\d+$/ ) {
97 0         0 $format = '%Y-%m-%d %H:%M%z';
98             } elsif ( $string =~ /^\d\d\d\d\-\d\d-\d\d\ [0-2][0-9]\:[0-5][0-9]Z$/ ) {
99 0         0 $format = '%Y-%m-%d %H:%MZ';
100             } elsif ( $string =~ /^\d\d\d\d\-\d\d-\d\d\ [0-2][0-9]\:[0-5][0-9]\ .+$/ ) {
101 0         0 $format = '%Y-%m-%d %H:%M %Z';
102             } elsif ( $string =~ /^\d\d\d\d\-\d\d-\d\d\ [0-2][0-9]\:[0-5][0-9]\:[0-5][0-9][-+]\d+$/ ) {
103 0         0 $format = '%Y-%m-%d %H:%M:%S%z';
104             } elsif ( $string =~ /^\d\d\d\d\-\d\d-\d\d\ [0-2][0-9]\:[0-5][0-9]\:[0-5][0-9]Z$/ ) {
105 0         0 $format = '%Y-%m-%d %H:%M:%SZ';
106             } elsif ( $string =~ /^\d\d\d\d\-\d\d-\d\d\ [0-2][0-9]\:[0-5][0-9]\:[0-5][0-9]\ .+$/ ) {
107 0         0 $format = '%Y-%m-%d %H:%M:%S %Z';
108             } elsif ( $string =~ /^\d\d\d\d\-\d\d-\d\dT[0-2][0-9]\:[0-5][0-9][-+]\d+$/ ) {
109 0         0 $format = '%Y-%m-%dT%H:%M%z';
110             } elsif ( $string =~ /^\d\d\d\d\-\d\d-\d\dT[0-2][0-9]\:[0-5][0-9]Z$/ ) {
111 0         0 $format = '%Y-%m-%dT%H:%MZ';
112             } elsif ( $string =~ /^\d\d\d\d\-\d\d-\d\dT[0-2][0-9]\:[0-5][0-9]\ .+$/ ) {
113 0         0 $format = '%Y-%m-%dT%H:%M %Z';
114             } elsif ( $string =~ /^\d\d\d\d\-\d\d-\d\dT[0-2][0-9]\:[0-5][0-9]\:[0-5][0-9][-+]\d+$/ ) {
115 2         4 $format = '%Y-%m-%dT%H:%M:%S%z';
116             } elsif ( $string =~ /^\d\d\d\d\-\d\d-\d\dT[0-2][0-9]\:[0-5][0-9]\:[0-5][0-9]Z$/ ) {
117 0         0 $format = '%Y-%m-%dT%H:%M:%SZ';
118             } elsif ( $string =~ /^\d\d\d\d\-\d\d-\d\dT[0-2][0-9]\:[0-5][0-9]\:[0-5][0-9]\ .+$/ ) {
119 0         0 $format = '%Y-%m-%dT%H:%M:%S %Z';
120             } elsif ( $string =~ /^\d\d\d\d\-\d\d-\d\d\/[0-2][0-9]\:[0-5][0-9][-+]\d+$/ ) {
121 0         0 $format = '%Y-%m-%dT%H:%M%z';
122             } elsif ( $string =~ /^\d\d\d\d\-\d\d-\d\d\/[0-2][0-9]\:[0-5][0-9]Z$/ ) {
123 0         0 $format = '%Y-%m-%dT%H:%MZ';
124             } elsif ( $string =~ /^\d\d\d\d\-\d\d-\d\d\/[0-2][0-9]\:[0-5][0-9]\ .+$/ ) {
125 0         0 $format = '%Y-%m-%dT%H:%M %Z';
126             } elsif ( $string =~ /^\d\d\d\d\-\d\d-\d\d\/[0-2][0-9]\:[0-5][0-9]\:[0-5][0-9][-+]\d+$/ ) {
127 0         0 $format = '%Y-%m-%d/%H:%M:%S%z';
128             } elsif ( $string =~ /^\d\d\d\d\-\d\d-\d\d\/[0-2][0-9]\:[0-5][0-9]\:[0-5][0-9]Z$/ ) {
129 0         0 $format = '%Y-%m-%d/%H:%M:%SZ';
130             } elsif ( $string =~ /^\d\d\d\d\-\d\d-\d\d\/[0-2][0-9]\:[0-5][0-9]\:[0-5][0-9]\ .+$/ ) {
131 0         0 $format = '%Y-%m-%d/%H:%M:%S %Z';
132             } elsif ( $string =~ /^\d\d\d\d\d\d\d\d\ [0-2][0-9]\:[0-5][0-9][-+]\d+$/ ) {
133 0         0 $format = '%Y%m%d %H:%M%z';
134             } elsif ( $string =~ /^\d\d\d\d\d\d\d\d\ [0-2][0-9]\:[0-5][0-9]Z$/ ) {
135 0         0 $format = '%Y%m%d %H:%M%Z';
136             } elsif ( $string =~ /^\d\d\d\d\d\d\d\d\ [0-2][0-9]\:[0-5][0-9]\ .+$/ ) {
137 0         0 $format = '%Y%m%d %H:%M %Z';
138             } elsif ( $string =~ /^\d\d\d\d\d\d\d\d\ [0-2][0-9]\:[0-5][0-9]\:[0-5][0-9][-+]\d+$/ ) {
139 0         0 $format = '%Y%m%d %H:%M:%S%z';
140             } elsif ( $string =~ /^\d\d\d\d\d\d\d\d\ [0-2][0-9]\:[0-5][0-9]\:[0-5][0-9]Z$/ ) {
141 0         0 $format = '%Y%m%d %H:%M:%SZ';
142             } elsif ( $string =~ /^\d\d\d\d\d\d\d\d\ [0-2][0-9]\:[0-5][0-9]\:[0-5][0-9]\ .+$/ ) {
143 0         0 $format = '%Y%m%d %H:%M:%S %Z';
144             } elsif ( $string =~ /\^d\d\d\d\d\d\d\dT[0-2][0-9]\:[0-5][0-9][-+]\d+$/ ) {
145 0         0 $format = '%Y%m%dT%H:%M%z';
146             } elsif ( $string =~ /\^d\d\d\d\d\d\d\dT[0-2][0-9]\:[0-5][0-9]Z$/ ) {
147 0         0 $format = '%Y%m%dT%H:%MZ';
148             } elsif ( $string =~ /\^d\d\d\d\d\d\d\dT[0-2][0-9]\:[0-5][0-9]\ .+$/ ) {
149 0         0 $format = '%Y%m%dT%H:%M %Z';
150             } elsif ( $string =~ /^\d\d\d\d\d\d\d\dT[0-2][0-9]\:[0-5][0-9]\:[0-5][0-9][-+]\d+$/ ) {
151 0         0 $format = '%Y%m%dT%H:%M:%S%z';
152             } elsif ( $string =~ /^\d\d\d\d\d\d\d\dT[0-2][0-9]\:[0-5][0-9]\:[0-5][0-9]Z$/ ) {
153 0         0 $format = '%Y%m%dT%H:%M:%SZ';
154             } elsif ( $string =~ /^\d\d\d\d\d\d\d\dT[0-2][0-9]\:[0-5][0-9]\:[0-5][0-9]\ .+$/ ) {
155 0         0 $format = '%Y%m%dT%H:%M:%S %Z';
156             } elsif ( $string =~ /^\d\d\d\d\d\d\d\d\/[0-2][0-9]\:[0-5][0-9][-+]\d+$/ ) {
157 0         0 $format = '%Y%m%dT%H:%M%z';
158             } elsif ( $string =~ /^\d\d\d\d\d\d\d\d\/[0-2][0-9]\:[0-5][0-9]Z$/ ) {
159 0         0 $format = '%Y%m%dT%H:%MZ';
160             } elsif ( $string =~ /^\d\d\d\d\d\d\d\d\/[0-2][0-9]\:[0-5][0-9]\ .+$/ ) {
161 0         0 $format = '%Y%m%dT%H:%M %Z';
162             } elsif ( $string =~ /^\d\d\d\d\d\d\d\d\/[0-2][0-9]\:[0-5][0-9]\:[0-5][0-9][-+]\d+$/ ) {
163 0         0 $format = '%Y%m%d/%H:%M:%S%z';
164             } elsif ( $string =~ /^\d\d\d\d\d\d\d\d\/[0-2][0-9]\:[0-5][0-9]\:[0-5][0-9]Z$/ ) {
165 0         0 $format = '%Y%m%d/%H:%M:%SZ';
166             } elsif ( $string =~ /^\d\d\d\d\d\d\d\d\/[0-2][0-9]\:[0-5][0-9]\:[0-5][0-9]\ .+$/ ) {
167 0         0 $format = '%Y%m%d/%H:%M:%S %Z';
168             } elsif ( $string =~ /^\d\d\d\d\-\d\d-\d\d\ [0-2][0-9]\:[0-5][0-9]$/ ) {
169 0         0 $format = '%Y-%m-%d %H:%M';
170             } elsif ( $string =~ /^\d\d\d\d\-\d\d-\d\d\ [0-2][0-9]\:[0-5][0-9]\:[0-5][0-9]$/ ) {
171 0         0 $format = '%Y-%m-%d %H:%M:%S';
172             } elsif ( $string =~ /^\d\d\d\d\-\d\d-\d\dT[0-2][0-9]\:[0-5][0-9]$/ ) {
173 0         0 $format = '%Y-%m-%dT%H:%M';
174             } elsif ( $string =~ /^\d\d\d\d\-\d\d-\d\dT[0-2][0-9]\:[0-5][0-9]\:[0-5][0-9]$/ ) {
175 1         6 $format = '%Y-%m-%dT%H:%M:%S';
176             } elsif ( $string =~ /^\d\d\d\d\-\d\d-\d\d\/[0-2][0-9]\:[0-5][0-9]$/ ) {
177 0         0 $format = '%Y-%m-%dT%H:%M';
178             } elsif ( $string =~ /^\d\d\d\d\-\d\d-\d\d\/[0-2][0-9]\:[0-5][0-9]\:[0-5][0-9]$/ ) {
179 0         0 $format = '%Y-%m-%d/%H:%M:%S';
180             } elsif ( $string =~ /^\d\d\d\d\d\d\d\d\ [0-2][0-9]\:[0-5][0-9]$/ ) {
181 0         0 $format = '%Y%m%d %H:%M';
182             } elsif ( $string =~ /^\d\d\d\d\d\d\d\d\ [0-2][0-9]\:[0-5][0-9]\:[0-5][0-9]$/ ) {
183 0         0 $format = '%Y%m%d %H:%M:%S';
184             } elsif ( $string =~ /^\d\d\d\d\d\d\d\dT[0-2][0-9]\:[0-5][0-9]$/ ) {
185 0         0 $format = '%Y%m%dT%H:%M';
186             } elsif ( $string =~ /^\d\d\d\d\d\d\d\dT[0-2][0-9]\:[0-5][0-9]\:[0-5][0-9]$/ ) {
187 0         0 $format = '%Y%m%dT%H:%M:%S';
188             } elsif ( $string =~ /^\d\d\d\d\d\d\d\d\/[0-2][0-9]\:[0-5][0-9]$/ ) {
189 0         0 $format = '%Y%m%dT%H:%M';
190             } elsif ( $string =~ /^\d\d\d\d\d\d\d\d\/[0-2][0-9]\:[0-5][0-9]\:[0-5][0-9]$/ ) {
191 0         0 $format = '%Y%m%d/%H:%M:%S';
192             } elsif ( $string =~ /^\d\d\d\d\-\d\d-\d\d\ [0-2][0-9][0-5][0-9][-+]\d+$/ ) {
193 0         0 $format = '%Y-%m-%d %H%M%z';
194             } elsif ( $string =~ /^\d\d\d\d\-\d\d-\d\d\ [0-2][0-9][0-5][0-9]Z$/ ) {
195 0         0 $format = '%Y-%m-%d %H%MZ';
196             } elsif ( $string =~ /^\d\d\d\d\-\d\d-\d\d\ [0-2][0-9][0-5][0-9]\ .+$/ ) {
197 0         0 $format = '%Y-%m-%d %H%M %Z';
198             } elsif ( $string =~ /^\d\d\d\d\-\d\d-\d\d\ [0-2][0-9][0-5][0-9][0-5][0-9][-+]\d+$/ ) {
199 0         0 $format = '%Y-%m-%d %H%M%S%z';
200             } elsif ( $string =~ /^\d\d\d\d\-\d\d-\d\d\ [0-2][0-9][0-5][0-9][0-5][0-9]Z$/ ) {
201 0         0 $format = '%Y-%m-%d %H%M%SZ';
202             } elsif ( $string =~ /^\d\d\d\d\-\d\d-\d\d\ [0-2][0-9][0-5][0-9][0-5][0-9]\ .+$/ ) {
203 0         0 $format = '%Y-%m-%d %H%M%S %Z';
204             } elsif ( $string =~ /^\d\d\d\d\-\d\d-\d\dT[0-2][0-9][0-5][0-9][-+]\d+$/ ) {
205 0         0 $format = '%Y-%m-%dT%H%M%z';
206             } elsif ( $string =~ /^\d\d\d\d\-\d\d-\d\dT[0-2][0-9][0-5][0-9]Z$/ ) {
207 0         0 $format = '%Y-%m-%dT%H%MZ';
208             } elsif ( $string =~ /^\d\d\d\d\-\d\d-\d\dT[0-2][0-9][0-5][0-9]\ .+$/ ) {
209 0         0 $format = '%Y-%m-%dT%H%M %Z';
210             } elsif ( $string =~ /^\d\d\d\d\-\d\d-\d\dT[0-2][0-9][0-5][0-9][0-5][0-9][-+]\d+$/ ) {
211 0         0 $format = '%Y-%m-%dT%H%M%S%z';
212             } elsif ( $string =~ /^\d\d\d\d\-\d\d-\d\dT[0-2][0-9][0-5][0-9][0-5][0-9]Z$/ ) {
213 0         0 $format = '%Y-%m-%dT%H%M%SZ';
214             } elsif ( $string =~ /^\d\d\d\d\-\d\d-\d\dT[0-2][0-9][0-5][0-9][0-5][0-9]\ .+$/ ) {
215 0         0 $format = '%Y-%m-%dT%H%M%S %Z';
216             } elsif ( $string =~ /^\d\d\d\d\-\d\d-\d\d\/[0-2][0-9][0-5][0-9][-+]\d+$/ ) {
217 0         0 $format = '%Y-%m-%dT%H%M%z';
218             } elsif ( $string =~ /^\d\d\d\d\-\d\d-\d\d\/[0-2][0-9][0-5][0-9]Z$/ ) {
219 0         0 $format = '%Y-%m-%dT%H%MZ';
220             } elsif ( $string =~ /^\d\d\d\d\-\d\d-\d\d\/[0-2][0-9][0-5][0-9]\ .+$/ ) {
221 0         0 $format = '%Y-%m-%dT%H%M %Z';
222             } elsif ( $string =~ /^\d\d\d\d\-\d\d-\d\d\/[0-2][0-9][0-5][0-9][0-5][0-9][-+]\d+$/ ) {
223 0         0 $format = '%Y-%m-%d/%H%M%S%z';
224             } elsif ( $string =~ /^\d\d\d\d\-\d\d-\d\d\/[0-2][0-9][0-5][0-9][0-5][0-9]Z$/ ) {
225 0         0 $format = '%Y-%m-%d/%H%M%SZ';
226             } elsif ( $string =~ /^\d\d\d\d\d\d\d\d\ [0-2][0-9][0-5][0-9][-+]\d+$/ ) {
227 0         0 $format = '%Y%m%d %H%M%z';
228             } elsif ( $string =~ /^\d\d\d\d\d\d\d\d\ [0-2][0-9][0-5][0-9]Z$/ ) {
229 0         0 $format = '%Y%m%d %H%M%Z';
230             } elsif ( $string =~ /^\d\d\d\d\d\d\d\d\ [0-2][0-9][0-5][0-9][0-5][0-9][-+]\d+$/ ) {
231 0         0 $format = '%Y%m%d %H%M%S%z';
232             } elsif ( $string =~ /^\d\d\d\d\d\d\d\d\ [0-2][0-9][0-5][0-9][0-5][0-9]Z$/ ) {
233 0         0 $format = '%Y%m%d %H%M%SZ';
234             } elsif ( $string =~ /\^d\d\d\d\d\d\d\dT[0-2][0-9][0-5][0-9][-+]\d+$/ ) {
235 0         0 $format = '%Y%m%dT%H%M%z';
236             } elsif ( $string =~ /\^d\d\d\d\d\d\d\dT[0-2][0-9][0-5][0-9]Z$/ ) {
237 0         0 $format = '%Y%m%dT%H%MZ';
238             } elsif ( $string =~ /^\d\d\d\d\d\d\d\dT[0-2][0-9][0-5][0-9][0-5][0-9][-+]\d+$/ ) {
239 0         0 $format = '%Y%m%dT%H%M%S%z';
240             } elsif ( $string =~ /^\d\d\d\d\d\d\d\dT[0-2][0-9][0-5][0-9][0-5][0-9]Z$/ ) {
241 0         0 $format = '%Y%m%dT%H%M%SZ';
242             } elsif ( $string =~ /^\d\d\d\d\d\d\d\d\/[0-2][0-9][0-5][0-9][-+]\d+$/ ) {
243 0         0 $format = '%Y%m%dT%H%M%z';
244             } elsif ( $string =~ /^\d\d\d\d\d\d\d\d\/[0-2][0-9][0-5][0-9]Z$/ ) {
245 0         0 $format = '%Y%m%dT%H%MZ';
246             } elsif ( $string =~ /^\d\d\d\d\d\d\d\d\/[0-2][0-9][0-5][0-9][0-5][0-9][-+]\d+$/ ) {
247 0         0 $format = '%Y%m%d/%H%M%S%z';
248             } elsif ( $string =~ /^\d\d\d\d\d\d\d\d\/[0-2][0-9][0-5][0-9][0-5][0-9]Z$/ ) {
249 0         0 $format = '%Y%m%d/%H%M%SZ';
250             } elsif ( $string =~ /^\d\d\d\d\-\d\d-\d\d\ [0-2][0-9][0-5][0-9]$/ ) {
251 0         0 $format = '%Y-%m-%d %H%M';
252             } elsif ( $string =~ /^\d\d\d\d\-\d\d-\d\d\ [0-2][0-9][0-5][0-9][0-5][0-9]$/ ) {
253 0         0 $format = '%Y-%m-%d %H%M%S';
254             } elsif ( $string =~ /^\d\d\d\d\-\d\d-\d\dT[0-2][0-9][0-5][0-9]$/ ) {
255 0         0 $format = '%Y-%m-%dT%H%M';
256             } elsif ( $string =~ /^\d\d\d\d\-\d\d-\d\dT[0-2][0-9][0-5][0-9][0-5][0-9]$/ ) {
257 0         0 $format = '%Y-%m-%dT%H%M%S';
258             } elsif ( $string =~ /^\d\d\d\d\-\d\d-\d\d\/[0-2][0-9][0-5][0-9]$/ ) {
259 0         0 $format = '%Y-%m-%dT%H%M';
260             } elsif ( $string =~ /^\d\d\d\d\-\d\d-\d\d\/[0-2][0-9][0-5][0-9][0-5][0-9]$/ ) {
261 0         0 $format = '%Y-%m-%d/%H%M%S';
262             } elsif ( $string =~ /^\d\d\d\d\d\d\d\d\ [0-2][0-9][0-5][0-9]$/ ) {
263 0         0 $format = '%Y%m%d %H%M';
264             } elsif ( $string =~ /^\d\d\d\d\d\d\d\d\ [0-2][0-9][0-5][0-9][0-5][0-9]$/ ) {
265 0         0 $format = '%Y%m%d %H%M%S';
266             } elsif ( $string =~ /^\d\d\d\d\d\d\d\dT[0-2][0-9][0-5][0-9]$/ ) {
267 0         0 $format = '%Y%m%dT%H%M';
268             } elsif ( $string =~ /^\d\d\d\d\d\d\d\dT[0-2][0-9][0-5][0-9][0-5][0-9]$/ ) {
269 0         0 $format = '%Y%m%dT%H%M%S';
270             } elsif ( $string =~ /^\d\d\d\d\d\d\d\d\/[0-2][0-9][0-5][0-9]$/ ) {
271 0         0 $format = '%Y%m%dT%H%M';
272             } elsif ( $string =~ /^\d\d\d\d\d\d\d\d\/[0-2][0-9][0-5][0-9][0-5][0-9]$/ ) {
273 0         0 $format = '%Y%m%d/%H%M%S';
274              
275             }
276              
277 3         35 return $format, $regex;
278             } ## end sub guess
279              
280             =head2 guess_to_object
281              
282             Takes the string, calles guess on it. If it gets a hit, it then returns
283             the Time::Piece object.
284              
285             Optionally there is the option to enable specials as well. See the section
286             on specials further down.
287              
288             If it fails, undef is returned.
289              
290             $tp_object = Time::Piece::Guess->guess_to_object('2023-02-27T11:00:18');
291             if (!defined( $tp_object )){
292             print "No matching format found\n";
293             }
294              
295             The same thing, but enabling specials and, resulting in it appending the local timezone
296             offset data that would correspond to %z.
297              
298             $tp_object = Time::Piece::Guess->guess_to_object('2023-02-27T11:00:18zz', 1);
299              
300             =cut
301              
302             sub guess_to_object {
303 1     1 1 171 my $string = $_[1];
304 1         3 my $special = $_[2];
305              
306 1 50       3 if ( !defined($string) ) {
307 0         0 return undef;
308             }
309              
310             # if special is enabled and it looks like a now special
311             # return the current time with the diffence applied
312 1 0 0     4 if (
      33        
313             $special
314             && ( $string =~ /^now$/
315             || $string =~ /^now[\-\+]\d+[mhdw]?$/
316             || $string =~ /^[\-\+]\d+[mhdw]?$/ )
317             )
318             {
319 0         0 my $t = localtime;
320              
321             # if just now, it is asking for the current time, so just return that
322 0 0       0 if ( $string eq 'now' ) {
323 0         0 return $t;
324             }
325              
326             # since this is more than just now, remove the now part and proceed to
327             # figure out what the off set is
328 0         0 $string =~ s/^now//;
329              
330             # figure out what to multiply the offset by
331             # nothing, seconds
332 0         0 my $multiplier = 1;
333 0 0       0 if ( $string =~ /m$/ ) {
    0          
    0          
    0          
334             # minutes
335 0         0 $multiplier = 60;
336 0         0 $string =~ s/m$//;
337             } elsif ( $string =~ /h$/ ) {
338             # hours
339 0         0 $multiplier = 60 * 60;
340 0         0 $string =~ s/h$//;
341             } elsif ( $string =~ /d$/ ) {
342             # days
343 0         0 $multiplier = 60 * 60 * 24;
344 0         0 $string =~ s/d$//;
345             } elsif ( $string =~ /w$/ ) {
346             # weeks
347 0         0 $multiplier = 60 * 60 * 24 * 7;
348 0         0 $string =~ s/w$//;
349             }
350              
351             # figure out the direction we are going
352             # multiply it
353             # apply the offset
354 0 0       0 if ( $string =~ /^\-/ ) {
355 0         0 $string =~ s/^\-//;
356 0         0 $string = $string * $multiplier;
357 0         0 $t = $t - $string;
358             } else {
359 0         0 $string =~ s/^\+//;
360 0         0 $string = $string * $multiplier;
361 0         0 $t = $t + $string;
362             }
363              
364 0         0 return $t;
365             } ## end if ( $special && ( $string =~ /^now$/ || $string...))
366              
367             # if special is enabled and ZZ or zz is used at the end
368             # append the timezone abbreviation
369 1         2 my $make_local = 0;
370 1 50 33     22 if ( $special
    50 33        
371             && $string =~ /zz$/ )
372             {
373 0         0 my $t = localtime;
374 0         0 my $zone = $t->strftime("%z");
375 0         0 $string =~ s/zz$/$zone/;
376 0         0 $make_local = 1;
377             } elsif ( $special
378             && $string =~ /ZZ$/ )
379             {
380 0         0 my $t = localtime;
381 0         0 my $zone = $t->strftime("%Z");
382 0         0 $string =~ s/\ ?ZZ$/\ $zone/;
383 0         0 $make_local = 1;
384             }
385              
386 1         12 my ( $format, $ms_clean_regex ) = Time::Piece::Guess->guess($string);
387              
388 1 50       4 if ( !defined($format) ) {
389 0         0 return undef;
390             }
391              
392 1 50       4 if ( defined($ms_clean_regex) ) {
393 0         0 $string =~ s/$ms_clean_regex//;
394             }
395              
396             # append 00 for minutes if %z is on the end
397             # as Time::Piece does not handle it properly if it
398             # is just hours
399 1 50 33     10 if ($format =~ /\%z/ && $string =~ /[-+]\d\d$/) {
400 0         0 $string=$string.'00';
401             }
402              
403 1         3 my $t;
404 1         10 eval { $t = Time::Piece->strptime( $string, $format ); };
  1         16  
405 1 50       62 if ($@) {
406 0         0 return undef;
407             }
408              
409             # unfortunately Time::Piece lakes the ability to set this currently
410 1 50       4 if ($make_local) {
411 0         0 $t->[10] = 1;
412             }
413              
414 1         4 return $t;
415             } ## end sub guess_to_object
416              
417             =head1 SPECIAL FORMATS
418              
419             =head2 now
420              
421             Now is returns current time.
422              
423             =head2 now[-+]\d+[mhdw]?
424              
425             Returns the current time after adding or subtracting the specified number of seconds.
426              
427             The following may be applied to the end to act as a multipler.
428              
429             - m :: The specified number is minutes.
430              
431             - h :: The specified number is hours.
432              
433             - d :: The specified number is hours.
434              
435             - w :: The specified number is weeks.
436              
437             So 'now-5' would be now minus five seconds and 'now-5m' would be now minus five minutes.
438              
439             =head2 zz
440              
441             Apply the current time zone to the end prior to parsing. Offset is determined by %z.
442              
443             '2023-07-23T17:34:00zz' if in -0500 would become '2023-07-23T17:34:00-0500'.
444              
445             =head2 ZZ
446              
447             Apply the current time zone name to the end prior to parsing. The name is determined
448             by %Z.
449              
450             =head1 AUTHOR
451              
452             Zane C. Bowers-Hadley, C<< >>
453              
454             =head1 BUGS
455              
456             Please report any bugs or feature requests to C, or through
457             the web interface at L. I will be notified, and then you'll
458             automatically be notified of progress on your bug as I make changes.
459              
460              
461              
462              
463             =head1 SUPPORT
464              
465             You can find documentation for this module with the perldoc command.
466              
467             perldoc Time::Piece::Guess
468              
469              
470             You can also look for information at:
471              
472             =over 4
473              
474             =item * RT: CPAN's request tracker (report bugs here)
475              
476             L
477              
478             =item * CPAN Ratings
479              
480             L
481              
482             =item * Search CPAN
483              
484             L
485              
486             =back
487              
488              
489             =head1 ACKNOWLEDGEMENTS
490              
491              
492             =head1 LICENSE AND COPYRIGHT
493              
494             This software is Copyright (c) 2023 by Zane C. Bowers-Hadley.
495              
496             This is free software, licensed under:
497              
498             The Artistic License 2.0 (GPL Compatible)
499              
500              
501             =cut
502              
503             1; # End of Time::Piece::Guess