DateTime::Format::Builder::Tutorial man page on Pidora

Man page or keyword search:  
man Server   31170 pages
apropos Keyword Search (all sections)
Output format
Pidora logo
[printable version]

DateTime::Format::BuilUser:Contributed PDateTime::Format::Builder::Tutorial(3)

NAME
       DateTime::Format::Builder::Tutorial - Quick class on using Builder

CREATING A CLASS
       As most people who are writing modules know, you start a package with a
       package declaration and some indication of module version:

	   package DateTime::Format::ICal;
	   our $VERSION = '0.04';

       After that, you call Builder with some options. There are only a few
       (detailed later). Right now, we're only interested in parsers.

	   use DateTime::Format::Builder
	   (
	       parsers => {
	       ...
	       }
	   );

       The parsers option takes a reference to a hash of method names and
       specifications:

	       parsers => {
		   parse_datetime => ... ,
		   parse_datetime_with_timezone => ... ,
		   ...
	       }

       Builder will create methods in your class, each method being a parser
       that follows the given specifications. It is strongly recommended that
       one method is called parse_datetime, be it a Builder created method or
       one of your own.

       In addition to creating any of the parser methods it also creates a
       "new()" method that can instantiate (or clone) objects of this class.
       This behaviour can be modified with the constructor option, but we
       don't need to know that yet.

       Each value corresponding to a method name in the parsers list is either
       a single specification, or a list of specifications. We'll start with
       the simple case.

	       parse_briefdate => {
		   params => [ qw( year month day ) ],
		   regex  => qr/^(\d\d\d\d)(\d\d)(\d\d)$/,
	       },

       This will result in a method named parse_briefdate which will take
       strings in the form 20040716 and return DateTime objects representing
       that date. A user of the class might write:

	   use DateTime::Format::ICal;
	   my $date = "19790716";
	   my $dt = DateTime::Format::ICal->parse_briefdate( $date );
	   print "My birth month is ", $dt->month_name, "\n";

       The "regex" is applied to the input string, and if it matches, then $1,
       $2, ... are mapped to the params given and handed to "DateTime->new()".
       Essentially:

	   my $rv = DateTime->new( year => $1, month => $2, day => $3 );

       There are more complicated things one can do within a single
       specification, but we'll cover those later.

       Often, you'll want a method to be able to take one string, and run it
       against multiple parser specifications. It would be very irritating if
       the user had to work out what format the datetime string was in and
       then which method was most appropriate.

       So, Builder lets you specify multiple specifications:

	   parse_datetime => [
	       {
		   params => [ qw( year month day hour minute second ) ],
		   regex  => qr/^(\d\d\d\d)(\d\d)(\d\d)T(\d\d)(\d\d)(\d\d)$/,
	       },
	       {
		   params => [ qw( year month day hour minute ) ],
		   regex  => qr/^(\d\d\d\d)(\d\d)(\d\d)T(\d\d)(\d\d)$/,
	       },
	       {
		   params => [ qw( year month day hour ) ],
		   regex  => qr/^(\d\d\d\d)(\d\d)(\d\d)T(\d\d)$/,
	       },
	       {
		   params => [ qw( year month day ) ],
		   regex  => qr/^(\d\d\d\d)(\d\d)(\d\d)$/,
	       },
	   ],

       It's an arrayref of specifications. A parser will be created that will
       try each of these specifications sequentially, in the order you
       specified.

       There's a flaw with this though. In this example, we're building a
       parser for ICal datetimes. One can place a timezone id at the start of
       an ICal datetime. You might extract such an id with the following code:

	   if ( $date =~ s/^TZID=([^:]+):// )
	   {
	       $time_zone = $1;
	   }
	   # Z at end means UTC
	   elsif ( $date =~ s/Z$// )
	   {
	       $time_zone = 'UTC';
	   }
	   else
	   {
	       $time_zone = 'floating';
	   }

       $date would end up without the id, and $time_zone would contain
       something appropriate to give to DateTime's set_time_zone method, or
       time_zone argument.

       But how to get this scrap of code into your parser? You might be
       tempted to call the parser something else and build a small wrapper.
       There's no need though because an option is provided for preprocesing
       dates:

	   parse_datetime => [
	       [ preprocess => \&_parse_tz ], # Only changed line!
	       {
		   params => [ qw( year month day hour minute second ) ],
		   regex  => qr/^(\d\d\d\d)(\d\d)(\d\d)T(\d\d)(\d\d)(\d\d)$/,
	       },
	       {
		   params => [ qw( year month day hour minute ) ],
		   regex  => qr/^(\d\d\d\d)(\d\d)(\d\d)T(\d\d)(\d\d)$/,
	       },
	       {
		   params => [ qw( year month day hour ) ],
		   regex  => qr/^(\d\d\d\d)(\d\d)(\d\d)T(\d\d)$/,
	       },
	       {
		   params => [ qw( year month day ) ],
		   regex  => qr/^(\d\d\d\d)(\d\d)(\d\d)$/,
	       },
	   ],

       It will necessitate _parse_tz to be written, and that routine looks
       like this:

	   sub _parse_tz
	   {
	       my %args = @_;
	       my ($date, $p) = @args{qw( input parsed )};
	       if ( $date =~ s/^TZID=([^:]+):// )
	       {
		   $p->{time_zone} = $1;
	       }
	       # Z at end means UTC
	       elsif ( $date =~ s/Z$// )
	       {
		   $p->{time_zone} = 'UTC';
	       }
	       else
	       {
		   $p->{time_zone} = 'floating';
	       }
	       return $date;
	   }

       On input it is given a hash containing two items: the input date and a
       hashref that will be used in the parsing. The return value from the
       routine is what the parser specifications will run against, and
       anything in the parsed hash ($p in the example) will be put in the call
       to "DateTime->new(...)".

       So, we now have a happily working ICal parser. It parses the assorted
       formats, and can also handle timezones. Is there anything else it needs
       to do? No. But we can make it work more efficiently.

       At present, the specifications are tested sequentially.	However, each
       one applies to strings of particular lengths.  Thus we could be
       efficient and have the parser only test the given strings against a
       parser that handles that string length. Again, Builder makes it easy:

	   parse_datetime => [
	       [ preprocess => \&_parse_tz ],
	       {
		   length => 15, # We handle strings of exactly 15 chars
		   params => [ qw( year month day hour minute second ) ],
		   regex  => qr/^(\d\d\d\d)(\d\d)(\d\d)T(\d\d)(\d\d)(\d\d)$/,
	       },
	       {
		   length => 13, # exactly 13 chars...
		   params => [ qw( year month day hour minute ) ],
		   regex  => qr/^(\d\d\d\d)(\d\d)(\d\d)T(\d\d)(\d\d)$/,
	       },
	       {
		   length => 11, # 11..
		   params => [ qw( year month day hour ) ],
		   regex  => qr/^(\d\d\d\d)(\d\d)(\d\d)T(\d\d)$/,
	       },
	       {
		   length => 8, # yes.
		   params => [ qw( year month day ) ],
		   regex  => qr/^(\d\d\d\d)(\d\d)(\d\d)$/,
	       },
	       ],

       Now the created parser will create a parser that only runs
       specifications against appropriate strings.

       So our complete code looks like:

	   package DateTime::Format::ICal;
	   use strict;
	   our $VERSION = '0.04';

	   use DateTime::Format::Builder
	   (
	       parsers => {
		   parse_datetime => [
		   [ preprocess => \&_parse_tz ],
		   {
		       length => 15,
		       params => [ qw( year month day hour minute second ) ],
		       regex  => qr/^(\d\d\d\d)(\d\d)(\d\d)T(\d\d)(\d\d)(\d\d)$/,
		   },
		   {
		       length => 13,
		       params => [ qw( year month day hour minute ) ],
		       regex  => qr/^(\d\d\d\d)(\d\d)(\d\d)T(\d\d)(\d\d)$/,
		   },
		   {
		       length => 11,
		       params => [ qw( year month day hour ) ],
		       regex  => qr/^(\d\d\d\d)(\d\d)(\d\d)T(\d\d)$/,
		   },
		   {
		       length => 8,
		       params => [ qw( year month day ) ],
		       regex  => qr/^(\d\d\d\d)(\d\d)(\d\d)$/,
		   },
		   ],
	       },
	   );

	   sub _parse_tz
	   {
	       my %args = @_;
	       my ($date, $p) = @args{qw( input parsed )};
	       if ( $date =~ s/^TZID=([^:]+):// )
	       {
		   $p->{time_zone} = $1;
	       }
	       # Z at end means UTC
	       elsif ( $date =~ s/Z$// )
	       {
		   $p->{time_zone} = 'UTC';
	       }
	       else
	       {
		   $p->{time_zone} = 'floating';
	       }
	       return $date;
	   }

	   1;

       And that's an ICal parser. The actual DateTime::Format::ICal module
       also includes formatting methods and parsing for durations, but Builder
       doesn't support those yet. A drop in replacement (at the time of
       writing the replacement) can be found in the examples directory of the
       Builder distribution, along with similar variants of other common
       modules.

SUPPORT
       Any errors you see in this document, please log them with CPAN RT
       system via the web or email:

	   http://perl.dellah.org/rt/dtbuilder
	   bug-datetime-format-builder@rt.cpan.org

       This makes it much easier for me to track things and thus means your
       problem is less likely to be neglected.

LICENSE AND COPYRIGHT
       Copyright (C) Iain Truskett, 2003. All rights reserved.

       You can redistribute this document and/or modify it under the same
       terms as Perl itself.

       The full text of the licenses can be found in the Artistic and COPYING
       files included with this document.

AUTHOR
       Iain Truskett <spoon@cpan.org>

SEE ALSO
       "datetime@perl.org" mailing list.

       http://datetime.perl.org/

       perl, DateTime, DateTime::Format::Builder

perl v5.14.1			  2011-0DateTime::Format::Builder::Tutorial(3)
[top]

List of man pages available for Pidora

Copyright (c) for man pages and the logo by the respective OS vendor.

For those who want to learn more, the polarhome community provides shell access and support.

[legal] [privacy] [GNU] [policy] [cookies] [netiquette] [sponsors] [FAQ]
Tweet
Polarhome, production since 1999.
Member of Polarhome portal.
Based on Fawad Halim's script.
....................................................................
Vote for polarhome
Free Shell Accounts :: the biggest list on the net