• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..03-May-2022-

examples/H09-Aug-2020-671388

lib/DateTime/Format/H09-Aug-2020-2,815951

t/H09-Aug-2020-1,7131,397

xt/H09-Aug-2020-249204

CODE_OF_CONDUCT.mdH A D09-Aug-20203.2 KiB7656

CONTRIBUTING.mdH A D09-Aug-20203.7 KiB10570

ChangesH A D09-Aug-20204.9 KiB259123

INSTALLH A D09-Aug-20202.3 KiB7346

LICENSEH A D09-Aug-20208.8 KiB208154

MANIFESTH A D09-Aug-20201.3 KiB7069

META.jsonH A D09-Aug-202035.7 KiB1,0541,052

META.ymlH A D09-Aug-202023 KiB782781

Makefile.PLH A D09-Aug-20201.7 KiB6755

README.mdH A D09-Aug-202021.3 KiB598396

azure-pipelines.ymlH A D09-Aug-2020668 2924

cpanfileH A D09-Aug-20201.5 KiB4943

dist.iniH A D09-Aug-2020848 3735

perlcriticrcH A D09-Aug-20201.9 KiB7149

perltidyrcH A D09-Aug-2020603 2827

tidyall.iniH A D09-Aug-2020447 2321

README.md

1# NAME
2
3DateTime::Format::Builder - Create DateTime parser classes and objects.
4
5# VERSION
6
7version 0.83
8
9# SYNOPSIS
10
11    package DateTime::Format::Brief;
12
13    use DateTime::Format::Builder (
14        parsers => {
15            parse_datetime => [
16                {
17                    regex  => qr/^(\d{4})(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)$/,
18                    params => [qw( year month day hour minute second )],
19                },
20                {
21                    regex  => qr/^(\d{4})(\d\d)(\d\d)$/,
22                    params => [qw( year month day )],
23                },
24            ],
25        }
26    );
27
28# DESCRIPTION
29
30DateTime::Format::Builder creates DateTime parsers. Many string formats of
31dates and times are simple and just require a basic regular expression to
32extract the relevant information. Builder provides a simple way to do this
33without writing reams of structural code.
34
35Builder provides a number of methods, most of which you'll never need, or at
36least rarely need. They're provided more for exposing of the module's innards
37to any subclasses, or for when you need to do something slightly beyond what I
38expected.
39
40# TUTORIAL
41
42See [DateTime::Format::Builder::Tutorial](https://metacpan.org/pod/DateTime%3A%3AFormat%3A%3ABuilder%3A%3ATutorial).
43
44# ERROR HANDLING AND BAD PARSES
45
46Often, I will speak of `undef` being returned, however that's not strictly
47true.
48
49When a simple single specification is given for a method, the method isn't
50given a single parser directly. It's given a wrapper that will call `on_fail`
51if the single parser returns `undef`. The single parser must return `undef`
52so that a multiple parser can work nicely and actual errors can be thrown from
53any of the callbacks.
54
55Similarly, any multiple parsers will only call `on_fail` right at the end
56when it's tried all it could.
57
58`on_fail` (see [later](#on_fail)) is defined, by default, to throw an error.
59
60Multiple parser specifications can also specify `on_fail` with a coderef as
61an argument in the options block. This will take precedence over the
62inheritable and overrideable method.
63
64That said, don't throw real errors from callbacks in multiple parser
65specifications unless you really want parsing to stop right there and not try
66any other parsers.
67
68In summary: calling a **method** will result in either a `DateTime` object
69being returned or an error being thrown (unless you've overridden `on_fail`
70or `create_method`, or you've specified a `on_fail` key to a multiple
71parser specification).
72
73Individual **parsers** (be they multiple parsers or single parsers) will return
74either the `DateTime` object or `undef`.
75
76# SINGLE SPECIFICATIONS
77
78A single specification is a hash ref of instructions on how to create a
79parser.
80
81The precise set of keys and values varies according to parser type. There are
82some common ones though:
83
84- length
85
86    **length** is an optional parameter that can be used to specify that this
87    particular _regex_ is only applicable to strings of a certain fixed
88    length. This can be used to make parsers more efficient. It's strongly
89    recommended that any parser that can use this parameter does.
90
91    You may happily specify the same length twice. The parsers will be tried in
92    order of specification.
93
94    You can also specify multiple lengths by giving it an arrayref of numbers
95    rather than just a single scalar. If doing so, please keep the number of
96    lengths to a minimum.
97
98    If any specifications without _length_s are given and the particular
99    _length_ parser fails, then the non-_length_ parsers are tried.
100
101    This parameter is ignored unless the specification is part of a multiple
102    parser specification.
103
104- label
105
106    **label** provides a name for the specification and is passed to some of the
107    callbacks about to mentioned.
108
109- on\_match and on\_fail
110
111    **on\_match** and **on\_fail** are callbacks. Both routines will be called with
112    parameters of:
113
114    - input
115
116        **input** is the input to the parser (after any preprocessing callbacks).
117
118    - label
119
120        **label** is the label of the parser if there is one.
121
122    - self
123
124        **self** is the object on which the method has been invoked (which may just be
125        a class name). Naturally, you can then invoke your own methods on it do get
126        information you want.
127
128    - **args** is an arrayref of any passed arguments, if any. If there were no
129    arguments, then this parameter is not given.
130
131    These routines will be called depending on whether the **regex** match
132    succeeded or failed.
133
134- preprocess
135
136    **preprocess** is a callback provided for cleaning up input prior to
137    parsing. It's given a hash as arguments with the following keys:
138
139    - input
140
141        **input** is the datetime string the parser was given (if using multiple
142        specifications and an overall _preprocess_ then this is the date after it's
143        been through that preprocessor).
144
145    - parsed
146
147        **parsed** is the state of parsing so far. Usually empty at this point unless
148        an overall _preprocess_ was given.  Items may be placed in it and will be
149        given to any **postprocess**or and `DateTime->new` (unless the
150        postprocessor deletes it).
151
152    - self, args, label
153
154        **self**, **args**, **label** as per _on\_match_ and _on\_fail_.
155
156    The return value from the routine is what is given to the _regex_. Note that
157    this is last code stop before the match.
158
159    **Note**: mixing _length_ and a _preprocess_ that modifies the length of the
160    input string is probably not what you meant to do. You probably meant to use
161    the _multiple parser_ variant of _preprocess_ which is done **before** any
162    length calculations. This `single parser` variant of _preprocess_ is
163    performed **after** any length calculations.
164
165- postprocess
166
167    **postprocess** is the last code stop before `DateTime->new` is
168    called. It's given the same arguments as _preprocess_. This allows it to
169    modify the parsed parameters after the parse and before the creation of the
170    object. For example, you might use:
171
172        {
173            regex       => qr/^(\d\d) (\d\d) (\d\d)$/,
174            params      => [qw( year  month  day   )],
175            postprocess => \&_fix_year,
176        }
177
178    where `_fix_year` is defined as:
179
180        sub _fix_year {
181            my %args = @_;
182            my ( $date, $p ) = @args{qw( input parsed )};
183            $p->{year} += $p->{year} > 69 ? 1900 : 2000;
184            return 1;
185        }
186
187    This will cause the two digit years to be corrected according to the cut
188    off. If the year was '69' or lower, then it is made into 2069 (or 2045, or
189    whatever the year was parsed as). Otherwise it is assumed to be 19xx. The
190    [DateTime::Format::Mail](https://metacpan.org/pod/DateTime%3A%3AFormat%3A%3AMail) module uses code similar to this (only it allows the
191    cut off to be configured and it doesn't use Builder).
192
193    **Note**: It is **very important** to return an explicit value from the
194    _postprocess_ callback. If the return value is false then the parse is taken
195    to have failed. If the return value is true, then the parse is taken to have
196    succeeded and `DateTime->new` is called.
197
198See the documentation for the individual parsers for their valid keys.
199
200Parsers at the time of writing are:
201
202- [DateTime::Format::Builder::Parser::Regex](https://metacpan.org/pod/DateTime%3A%3AFormat%3A%3ABuilder%3A%3AParser%3A%3ARegex) - provides regular expression
203based parsing.
204- [DateTime::Format::Builder::Parser::Strptime](https://metacpan.org/pod/DateTime%3A%3AFormat%3A%3ABuilder%3A%3AParser%3A%3AStrptime) - provides strptime based
205parsing.
206
207## Subroutines / coderefs as specifications.
208
209A single parser specification can be a coderef. This was added mostly because
210it could be and because I knew someone, somewhere, would want to use it.
211
212If the specification is a reference to a piece of code, be it a subroutine,
213anonymous, or whatever, then it's passed more or less straight through. The
214code should return `undef` in event of failure (or any false value, but
215`undef` is strongly preferred), or a true value in the event of success
216(ideally a `DateTime` object or some object that has the same interface).
217
218This all said, I generally wouldn't recommend using this feature unless you
219have to.
220
221## Callbacks
222
223I mention a number of callbacks in this document.
224
225Any time you see a callback being mentioned, you can, if you like, substitute
226an arrayref of coderefs rather than having the straight coderef.
227
228# MULTIPLE SPECIFICATIONS
229
230These are very easily described as an array of single specifications.
231
232Note that if the first element of the array is an arrayref, then you're
233specifying options.
234
235- preprocess
236
237    **preprocess** lets you specify a preprocessor that is called before any of the
238    parsers are tried. This lets you do things like strip off timezones or any
239    unnecessary data. The most common use people have for it at present is to get
240    the input date to a particular length so that the _length_ is usable
241    ([DateTime::Format::ICal](https://metacpan.org/pod/DateTime%3A%3AFormat%3A%3AICal) would use it to strip off the variable length
242    timezone).
243
244    Arguments are as for the _single parser_ _preprocess_ variant with the
245    exception that _label_ is never given.
246
247- on\_fail
248
249    **on\_fail** should be a reference to a subroutine that is called if the parser
250    fails. If this is not provided, the default action is to call
251    `DateTime::Format::Builder::on_fail`, or the `on_fail` method of the
252    subclass of DTFB that was used to create the parser.
253
254# EXECUTION FLOW
255
256Builder allows you to plug in a fair few callbacks, which can make following
257how a parse failed (or succeeded unexpectedly) somewhat tricky.
258
259## For Single Specifications
260
261A single specification will do the following:
262
263User calls parser:
264
265    my $dt = $class->parse_datetime($string);
266
2671. _preprocess_ is called. It's given `$string` and a reference to the parsing
268workspace hash, which we'll call `$p`. At this point, `$p` is empty. The
269return value is used as `$date` for the rest of this single parser.  Anything
270put in `$p` is also used for the rest of this single parser.
2712. _regex_ is applied.
2723. If _regex_ **did not** match, then _on\_fail_ is called (and is given `$date`
273and also _label_ if it was defined). Any return value is ignored and the next
274thing is for the single parser to return `undef`.
275
276    If _regex_ **did** match, then _on\_match_ is called with the same arguments
277    as would be given to _on\_fail_. The return value is similarly ignored, but we
278    then move to step 4 rather than exiting the parser.
279
2804. _postprocess_ is called with `$date` and a filled out `$p`. The return
281value is taken as a indication of whether the parse was a success or not. If
282it wasn't a success then the single parser will exit at this point, returning
283undef.
2845. `DateTime->new` is called and the user is given the resultant `DateTime`
285object.
286
287See the section on [error handling](#error-handling-and-bad-parses)
288regarding the `undef`s mentioned above.
289
290## For Multiple Specifications
291
292With multiple specifications:
293
294User calls parser:
295
296    my $dt = $class->complex_parse($string);
297
2981. The overall _preprocess_or is called and is given `$string` and the hashref
299`$p` (identically to the per parser _preprocess_ mentioned in the previous
300flow).
301
302    If the callback modifies `$p` then a **copy** of `$p` is given to each of the
303    individual parsers. This is so parsers won't accidentally pollute each other's
304    workspace.
305
3062. If an appropriate length specific parser is found, then it is called and the
307single parser flow (see the previous section) is followed, and the parser is
308given a copy of `$p` and the return value of the overall _preprocess_or as
309`$date`.
310
311    If a `DateTime` object was returned so we go straight back to the user.
312
313    If no appropriate parser was found, or the parser returned `undef`, then we
314    progress to step 3!
315
3163. Any non-_length_ based parsers are tried in the order they were specified.
317
318    For each of those the single specification flow above is performed, and is
319    given a copy of the output from the overall preprocessor.
320
321    If a real `DateTime` object is returned then we exit back to the user.
322
323    If no parser could parse, then an error is thrown.
324
325See the section on [error handling](#error-handling-and-bad-parses) regarding
326the `undef`s mentioned above.
327
328# METHODS
329
330In the general course of things you won't need any of the methods. Life often
331throws unexpected things at us so the methods are all available for use.
332
333## import
334
335`import` is a wrapper for `create_class`. If you specify the _class_ option
336(see documentation for `create_class`) it will be ignored.
337
338## create\_class
339
340This method can be used as the runtime equivalent of `import`. That is, it
341takes the exact same parameters as when one does:
342
343    use DateTime::Format::Builder ( ... )
344
345That can be (almost) equivalently written as:
346
347    use DateTime::Format::Builder;
348    DateTime::Format::Builder->create_class( ... );
349
350The difference being that the first is done at compile time while the second
351is done at run time.
352
353In the tutorial I said there were only two parameters at present. I
354lied. There are actually three of them.
355
356- parsers
357
358    **parsers** takes a hashref of methods and their parser specifications. See the
359    [DateTime::Format::Builder::Tutorial](https://metacpan.org/pod/DateTime%3A%3AFormat%3A%3ABuilder%3A%3ATutorial) for details.
360
361    Note that if you define a subroutine of the same name as one of the methods
362    you define here, an error will be thrown.
363
364- constructor
365
366    **constructor** determines whether and how to create a `new` function in the
367    new class. If given a true value, a constructor is created. If given a false
368    value, one isn't.
369
370    If given an anonymous sub or a reference to a sub then that is used as
371    `new`.
372
373    The default is `1` (that is, create a constructor using our default code
374    which simply creates a hashref and blesses it).
375
376    If your class defines its own `new` method it will not be overwritten. If you
377    define your own `new` and **also** tell Builder to define one an error will be
378    thrown.
379
380- verbose
381
382    **verbose** takes a value. If the value is `undef`, then logging is
383    disabled. If the value is a filehandle then that's where logging will go. If
384    it's a true value, then output will go to `STDERR`.
385
386    Alternatively, call `$DateTime::Format::Builder::verbose` with the relevant
387    value. Whichever value is given more recently is adhered to.
388
389    Be aware that verbosity is a global setting.
390
391- class
392
393    **class** is optional and specifies the name of the class in which to create
394    the specified methods.
395
396    If using this method in the guise of `import` then this field will cause an
397    error so it is only of use when calling as `create_class`.
398
399- version
400
401    **version** is also optional and specifies the value to give `$VERSION` in the
402    class. It's generally not recommended unless you're combining with the
403    _class_ option. A `ExtUtils::MakeMaker` / `CPAN` compliant version
404    specification is much better.
405
406In addition to creating any of the methods it also creates a `new` method
407that can instantiate (or clone) objects.
408
409# SUBCLASSING
410
411In the rest of the documentation I've often lied in order to get some of the
412ideas across more easily. The thing is, this module's very flexible. You can
413get markedly different behaviour from simply subclassing it and overriding
414some methods.
415
416## create\_method
417
418Given a parser coderef, returns a coderef that is suitable to be a method.
419
420The default action is to call `on_fail` in the event of a non-parse, but you
421can make it do whatever you want.
422
423## on\_fail
424
425This is called in the event of a non-parse (unless you've overridden
426`create_method` to do something else.
427
428The single argument is the input string. The default action is to call
429`croak`. Above, where I've said parsers or methods throw errors, this is
430the method that is doing the error throwing.
431
432You could conceivably override this method to, say, return `undef`.
433
434# USING BUILDER OBJECTS aka USERS USING BUILDER
435
436The methods listed in the [METHODS](https://metacpan.org/pod/METHODS) section are all you generally need when
437creating your own class. Sometimes you may not want a full blown class to
438parse something just for this one program. Some methods are provided to make
439that task easier.
440
441## new
442
443The basic constructor. It takes no arguments, merely returns a new
444`DateTime::Format::Builder` object.
445
446    my $parser = DateTime::Format::Builder->new;
447
448If called as a method on an object (rather than as a class method), then it
449clones the object.
450
451    my $clone = $parser->new;
452
453## clone
454
455Provided for those who prefer an explicit `clone` method rather than using
456`new` as an object method.
457
458    my $clone_of_clone = $clone->clone;
459
460## parser
461
462Given either a single or multiple parser specification, sets the object to
463have a parser based on that specification.
464
465    $parser->parser(
466        regex  => qr/^ (\d{4}) (\d\d) (\d\d) $/x;
467        params => [qw( year    month  day    )],
468    );
469
470The arguments given to `parser` are handed directly to `create_parser`. The
471resultant parser is passed to `set_parser`.
472
473If called as an object method, it returns the object.
474
475If called as a class method, it creates a new object, sets its parser and
476returns that object.
477
478## set\_parser
479
480Sets the parser of the object to the given parser.
481
482    $parser->set_parser($coderef);
483
484Note: this method does not take specifications. It also does not take anything
485except coderefs. Luckily, coderefs are what most of the other methods produce.
486
487The method return value is the object itself.
488
489## get\_parser
490
491Returns the parser the object is using.
492
493    my $code = $parser->get_parser;
494
495## parse\_datetime
496
497Given a string, it calls the parser and returns the `DateTime` object that
498results.
499
500    my $dt = $parser->parse_datetime('1979 07 16');
501
502The return value, if not a `DateTime` object, is whatever the parser wants to
503return. Generally this means that if the parse failed an error will be thrown.
504
505## format\_datetime
506
507If you call this function, it will throw an error.
508
509# LONGER EXAMPLES
510
511Some longer examples are provided in the distribution. These implement some of
512the common parsing DateTime modules using Builder. Each of them are, or were,
513drop in replacements for the modules at the time of writing them.
514
515# THANKS
516
517Dave Rolsky (DROLSKY) for kickstarting the DateTime project, writing
518[DateTime::Format::ICal](https://metacpan.org/pod/DateTime%3A%3AFormat%3A%3AICal) and [DateTime::Format::MySQL](https://metacpan.org/pod/DateTime%3A%3AFormat%3A%3AMySQL), and some much needed
519review.
520
521Joshua Hoblitt (JHOBLITT) for the concept, some of the API, impetus for
522writing the multi-length code (both one length with multiple parsers and
523single parser with multiple lengths), blame for the Regex custom constructor
524code, spotting a bug in Dispatch, and more much needed review.
525
526Kellan Elliott-McCrea (KELLAN) for even more review, suggestions,
527[DateTime::Format::W3CDTF](https://metacpan.org/pod/DateTime%3A%3AFormat%3A%3AW3CDTF) and the encouragement to rewrite these docs almost
528100%!
529
530Claus Färber (CFAERBER) for having me get around to fixing the
531auto-constructor writing, providing the 'args'/'self' patch, and suggesting
532the multi-callbacks.
533
534Rick Measham (RICKM) for [DateTime::Format::Strptime](https://metacpan.org/pod/DateTime%3A%3AFormat%3A%3AStrptime) which Builder now
535supports.
536
537Matthew McGillis for pointing out that `on_fail` overriding should be
538simpler.
539
540Simon Cozens (SIMON) for saying it was cool.
541
542# SEE ALSO
543
544`datetime@perl.org` mailing list.
545
546http://datetime.perl.org/
547
548[perl](https://metacpan.org/pod/perl), [DateTime](https://metacpan.org/pod/DateTime), [DateTime::Format::Builder::Tutorial](https://metacpan.org/pod/DateTime%3A%3AFormat%3A%3ABuilder%3A%3ATutorial),
549[DateTime::Format::Builder::Parser](https://metacpan.org/pod/DateTime%3A%3AFormat%3A%3ABuilder%3A%3AParser)
550
551# SUPPORT
552
553Bugs may be submitted at [https://github.com/houseabsolute/DateTime-Format-Builder/issues](https://github.com/houseabsolute/DateTime-Format-Builder/issues).
554
555I am also usually active on IRC as 'autarch' on `irc://irc.perl.org`.
556
557# SOURCE
558
559The source code repository for DateTime-Format-Builder can be found at [https://github.com/houseabsolute/DateTime-Format-Builder](https://github.com/houseabsolute/DateTime-Format-Builder).
560
561# DONATIONS
562
563If you'd like to thank me for the work I've done on this module, please
564consider making a "donation" to me via PayPal. I spend a lot of free time
565creating free software, and would appreciate any support you'd care to offer.
566
567Please note that **I am not suggesting that you must do this** in order for me
568to continue working on this particular software. I will continue to do so,
569inasmuch as I have in the past, for as long as it interests me.
570
571Similarly, a donation made in this way will probably not make me work on this
572software much more, unless I get so many donations that I can consider working
573on free software full time (let's all have a chuckle at that together).
574
575To donate, log into PayPal and send money to autarch@urth.org, or use the
576button at [https://www.urth.org/fs-donation.html](https://www.urth.org/fs-donation.html).
577
578# AUTHORS
579
580- Dave Rolsky <autarch@urth.org>
581- Iain Truskett <spoon@cpan.org>
582
583# CONTRIBUTORS
584
585- Daisuke Maki <daisuke@endeworks.jp>
586- James Raspass <jraspass@gmail.com>
587
588# COPYRIGHT AND LICENSE
589
590This software is Copyright (c) 2020 by Dave Rolsky.
591
592This is free software, licensed under:
593
594    The Artistic License 2.0 (GPL Compatible)
595
596The full text of the license can be found in the
597`LICENSE` file included with this distribution.
598