Re: Error with the leap year

2012-03-02 Thread Matthew Hall
On Fri, Mar 02, 2012 at 10:17:08AM +, Zefram wrote:
 In the awkward case, it advances to March 1st:

...

 Of course, it has the downside that year addition isn't associative:
 advancing from a February 29th by four years gives a different result
 from advancing by one year four times.

...

 It's nicer, in that day addition *is* associative.  Of course, a quarter
 of the time (when the 365 days spans a leap day), the 365-days-later
 won't be the same-date-next-year.  Is that what you mean by the leap
 year problem?

Reasons Why You Should Never Write Custom Date / Time Handling Code Yourself 
Vol. 1 No. 1 - 3...

Matthew


Re: datetime question

2010-10-31 Thread Matthew Hall
On Sunday, October 31, 2010 15:26:04 Guustaaf Damave wrote:
 Is there a way to retrieve the next switchover time for a time zone? I
 could then store that in the cache and stop using that cache entry after
 that time, similar to how web browsers do that.

Your best bet is probably finding a way to query the TZ database directly to 
get this information. The C library calls don't directly support looking up 
the switchover so this might not be real easy to do. You can probably pull 
up the data from the raw or compiled zoneinfo files.

http://en.wikipedia.org/wiki/Tz_database

Some APIs exist for this in DateTime:

http://search.cpan.org/dist/DateTime-
TimeZone/lib/DateTime/TimeZone/OlsonDB.pm

But one of the sentences in the docs says:

USAGE-- Not yet documented. This stuff is a mess.

 Thanks again!
 Best regards,
 Guustaaf

Regards,
Matthew Hall


DateTime::Format::Strptime bug report

2010-09-02 Thread Matthew Hall
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]


Re: DateTime::Format::Strptime bug report

2010-09-02 Thread Matthew Hall
It'd also be good to fix the bug where errors don't work if croak is 
disabled. Makes it real hard to do good automated processing of 
potentially bad input.

On Thu, Sep 02, 2010 at 10:55:16AM -0700, Matthew Hall wrote:
 On Thu, Sep 02, 2010 at 01:24:03PM -0400, Metz, Bobby wrote:
  You can add the current year to your string value prior to parsing.
 
 Thanks. I'll adopt the DateTime based version in your second mail.
 
  Of course you could also alter you syslog config to include the year, 
  right?
 
 It's more complicated than that. This is part of some generalized code 
 to process a whole bunch of different weird timestamps coming in 
 through Syslog, and the BSD classic one was the one which was causing 
 me problems because the others were working. They were commented out in 
 the parser array to make the code easier to debug and explain in the 
 post. Some of the dates and times in the message header could be fixed, 
 but the ones inside the message themselves are stuck as they are.
 
 Matthew.
 
  
   -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

Re: DateTime::Format::Strptime bug report

2010-09-02 Thread Matthew Hall
On Thu, Sep 02, 2010 at 01:51:42PM -0500, Dave Rolsky wrote:
 Or you could do the simple version ...
 DateTime-now()-year();

Good call. Implemented.

 -dave

Matthew.