You can add the current year to your string value prior to parsing.

my $val = "Sep 1 05:39:02";

# Grab the year either via exec or via DateTime, your choice
chomp(my $year = `date '+%Y'`);
# --or--
my $year  = strftime('%Y',localtime(time));

# Then combine and parse the string value into a DT object
$val = $val . " " . $year;
my $parser = DateTime::Format::Strptime->new(pattern => '%b %d %H:%M:%S %Y');
my $dt = $parser->parse_datetime($val);


Of course you could also alter you syslog config to include the year, right?

> -----Original Message-----
> From: Matthew Hall [mailto:mh...@mhcomputing.net]
> Sent: Wednesday, September 01, 2010 8:33 PM
> To: datetime@perl.org
> Subject: DateTime::Format::Strptime bug report
> 
> Hello all,
> 
> I am trying to parse BSD Syslog format time stamps, like this one:
> 
> Sep 1 05:39:02
> 
> Using the DateTime::Format::Strptime class, the call is failing with
> the following result, when I use the format string '%b %d %H:%M:%S'.
> 
> There is no use providing a month name (Sep) without providing a year.
> at /homes/megahall/workspace/montage/src/Yahoo/Montage/WelfParser.pm line
> 55
> 
> Searching for the error on the Internet even with the "(Sep)" removed
> does not return any meaningful results.
> 
> I am wondering what I can do to fix this issue so I can get DateTime
> working, or if there is a workaround of some sort. It does not seem
> reasonable to croak or return undef time object because then there is
> no way to set a valid year using a member function plus some external
> year logic.
> 
> In addition, when trying to debug using the default on_error undef
> setup, I discovered it is not possible to see this error message, and
> that the $object->errstr() method mentioned in the documentation does
> not seem to exist. Grepping the perl lib folder did not reveal it
> either and I got an error trying to call it as well.
> 
> Further information below.
> 
> Thanks,
> Matthew.
> 
> In the grep output; only a documentation passage is mentioned. This is
> the passage from the documentation:
> 
> This is the default behavior. The module will return undef whenever it
> gets upset. The error can be accessed using the $object->errstr method.
> This is the ideal behaviour for interactive use where a user might
> provide an illegal pattern or a date that doesn't match the pattern.
> 
> Here are my package versions.
> 
> DateTime-Format-Builder-0.7901_02
> DateTime-Format-Epoch-0.10_01
> DateTime-Format-ISO8601-0.0601_01
> DateTime-Format-Strptime-1.0702_02
> DateTime-Locale-0.42_01
> DateTime-TimeZone-1.01_01
> DateTime-0.5000_01
> 
> Here is a code snippet.
> 
> my @date_time_formats = (
>     # BSD: 'Mmm DD HH:MM:SS'
>     ['BSD Syslog'           , new DateTime::Format::Strptime(pattern =>
> '%b %d %H:%M:%S'      , locale => 'en_US', time_zone => 'GMT', diagnostic
> => $diagnostic, on_error => 'croak')],
> );
> 
> sub welf_time {
>     my ($time_str) = @_;
> 
>     $log->debug("process time_str [$time_str]");
> 
>     my $date_time;
>     my $type;
>     my $parser;
>     for (my $i = 0; $i < scalar(@date_time_formats); $i++) {
>         eval {
>             $type = $date_time_formats[$i][0];
>             $parser = $date_time_formats[$i][1];
>             $log->trace("call parser [$type]");
> 
>             $date_time = $parser->parse_datetime($time_str);
> 
>             $log->trace("return parser [$type] result [" .
> display($date_time) . "] errstr [" . display($parser->errstr()) . "]");
>         };
> 
>         if ($@) {
>             $log->info("parser [$type] experienced exception {...@}\n");
>         }
>     }
> 
>     $log->log(!defined($date_time)? $WARN : $TRACE,
>         "processed time_str [$time_str] into date_time [" .
> display($date_time) . "]");
> 
>     if (!defined($date_time)) {
>         $date_time = DateTime->now();
>     }
> 
>     return $date_time->epoch();
> }
> 
> Below is the log4perl output, along with diagnostic enabled on the
> parser.
> 
> [2010/09/01 20:06:30] [WelfParser.pm:44] [DEBUG]
> process time_str [Sep 1 05:39:02]
> [2010/09/01 20:06:30] [WelfParser.pm:53] [TRACE]
> call parser [BSD Syslog]
> 
> Entered     = Sep 1 05:39:02
> Parser            = ($month_name, $day, $hour_24, $minute, $second) =
>     $time_string =~ /(\S+) ([\d ]?\d) ([\d ]?\d):([\d ]?\d):([\d ]?\d)/
> 
> dow_name    =
> month_name  = Sep
> century     =
> day         = 1
> hour_24     = 05
> hour_12     =
> doy         =
> month       =
> minute      = 39
> ampm        =
> second      = 02
> nanosecond  =
> week_sun_0  =
> dow_sun_0   =
> dow_mon_1   =
> week_mon_1  =
> year_100    =
> year        =
> ce_year     =
> tz_offset   =
> tz_olson    =
> timezone    =
> epoch       =
> iso_week_year     =
> iso_week_year_100 =
> 
> Using timezone DateTime::TimeZone::UTC=HASH(0x9162350).
> 
> [2010/09/01 20:06:30] [WelfParser.pm:61] [INFO]
> parser [BSD Syslog] experienced exception {
> There is no use providing a month name (Sep) without providing a year.
> at /homes/megahall/workspace/montage/src/Yahoo/Montage/WelfParser.pm line
> 55
> }
> 
> [2010/09/01 20:06:30] [WelfParser.pm:65] [WARN]
> processed time_str [Sep 1 05:39:02] into date_time [undef]

Reply via email to