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]