atoomic / perl-TimeDate

time & date parsing and formatting perl library
http://search.cpan.org/dist/TimeDate/
1 stars 4 forks source link

str2time parses incorrectly. [rt.cpan.org #113726] #35

Open atoomic opened 4 years ago

atoomic commented 4 years ago

Migrated from rt.cpan.org#113726 (status was 'open')

Requestors:

From sebastianokur@gmail.com on 2016-04-13 00:43:54 :

Hi,

As much as I can see from the documentation, there is no information
regarding to inability to parse "YYYY-MM-DD hh:mm:ss.SSS" format. Also, I
noticed it is mentioned that the str2time function should return undef if
it doesn't support string for parsing.

Below is the code and its output:

*===*
#!/usr/bin/perl

use strict;
use warnings;
use Date::Parse;

my $date1_str = "2016-01-28 23:27:13,995";
my $date1_epoch = str2time($date1_str);
print "date1_epoch: [$date1_epoch]\n";

my $date2_str = "2016-01-28 23:27:13,996";
my $date2_epoch = str2time($date2_str);
print "date2_epoch: [$date2_epoch]\n";

# OUTPUT:
#
# date1_epoch: [1453985533]
# date2_epoch: [1453985473]
*===*

Notice that *date2_epoch* is earlier than *date1_epoch*, and –if anything–
epoch values should be the same.

Thanks for your time and assistance in advance,

--Sebastian Okur

From srezic@cpan.org on 2016-04-13 06:45:19 :

On 2016-04-12 20:43:54, sebastianokur@gmail.com wrote:
> Hi,
> 
> As much as I can see from the documentation, there is no information
> regarding to inability to parse "YYYY-MM-DD hh:mm:ss.SSS" format. Also, I
> noticed it is mentioned that the str2time function should return undef if
> it doesn't support string for parsing.
> 
> Below is the code and its output:
> 
> *===*
> #!/usr/bin/perl
> 
> use strict;
> use warnings;
> use Date::Parse;
> 
> my $date1_str = "2016-01-28 23:27:13,995";
> my $date1_epoch = str2time($date1_str);
> print "date1_epoch: [$date1_epoch]\n";
> 
> my $date2_str = "2016-01-28 23:27:13,996";
> my $date2_epoch = str2time($date2_str);
> print "date2_epoch: [$date2_epoch]\n";
> 
> # OUTPUT:
> #
> # date1_epoch: [1453985533]
> # date2_epoch: [1453985473]
> *===*
> 
> Notice that *date2_epoch* is earlier than *date1_epoch*, and –if anything–
> epoch values should be the same.
> 
> Thanks for your time and assistance in advance,
> 
> --Sebastian Okur

Actually, if the comma in the test script is replaced with a dot, then things work fine. I wouldn't expect that Date::Parse should parse the comma as a decimal dot.

From sebastianokur@gmail.com on 2016-04-13 15:18:05 :

Thanks for the heads up. I already found that out and fixed my code to
accommodate it.

I guess the point I was trying to make is that *str2time* function silently
fails by producing unpredictable results instead of failing hard by
returning *undef* for input formats that are not supported or not entirely
correct in its form.

Since epoch values are scalars that are not as easily distinguishable as
other-more readable date formats (*1454023633995* VS *2016-01-28
23:27:13,995*), especially when the first couple of digits are correct, it
is not immediately obvious to the developer that the result is wrong.

It would be very helpful if functions fail hard in a conspicuous fashion
when they fail.

On Wed, Apr 13, 2016 at 2:45 AM, Slaven_Rezic via RT <
bug-TimeDate@rt.cpan.org> wrote:

> <URL: https://rt.cpan.org/Ticket/Display.html?id=113726 >
>
> On 2016-04-12 20:43:54, sebastianokur@gmail.com wrote:
> > Hi,
> >
> > As much as I can see from the documentation, there is no information
> > regarding to inability to parse "YYYY-MM-DD hh:mm:ss.SSS" format. Also, I
> > noticed it is mentioned that the str2time function should return undef if
> > it doesn't support string for parsing.
> >
> > Below is the code and its output:
> >
> > *===*
> > #!/usr/bin/perl
> >
> > use strict;
> > use warnings;
> > use Date::Parse;
> >
> > my $date1_str = "2016-01-28 23:27:13,995";
> > my $date1_epoch = str2time($date1_str);
> > print "date1_epoch: [$date1_epoch]\n";
> >
> > my $date2_str = "2016-01-28 23:27:13,996";
> > my $date2_epoch = str2time($date2_str);
> > print "date2_epoch: [$date2_epoch]\n";
> >
> > # OUTPUT:
> > #
> > # date1_epoch: [1453985533]
> > # date2_epoch: [1453985473]
> > *===*
> >
> > Notice that *date2_epoch* is earlier than *date1_epoch*, and –if
> anything–
> > epoch values should be the same.
> >
> > Thanks for your time and assistance in advance,
> >
> > --Sebastian Okur
>
> Actually, if the comma in the test script is replaced with a dot, then
> things work fine. I wouldn't expect that Date::Parse should parse the comma
> as a decimal dot.
>
>
>

From srezic@cpan.org on 2016-04-14 18:42:44 :

I did some debugging what's going on here. An early transformation replaces all commas into spaces, so we get something like "2016-01-28 23:27:13 995". If the bit behind the seconds looks vaguely like a timezone specification, then it seems that it's used as one. In this case this means an offset of 9 hours and 95 minutes, which is causing the difference.

Probably everything >= 60 minutes could generate an error here.

It would probably also be good to improve the comma replacement, maybe don't do it all over the place.

On 2016-04-13 11:18:05, sebastianokur@gmail.com wrote:
> Thanks for the heads up. I already found that out and fixed my code to
> accommodate it.
> 
> I guess the point I was trying to make is that *str2time* function
> silently
> fails by producing unpredictable results instead of failing hard by
> returning *undef* for input formats that are not supported or not
> entirely
> correct in its form.
> 
> Since epoch values are scalars that are not as easily distinguishable
> as
> other-more readable date formats (*1454023633995* VS *2016-01-28
> 23:27:13,995*), especially when the first couple of digits are
> correct, it
> is not immediately obvious to the developer that the result is wrong.
> 
> It would be very helpful if functions fail hard in a conspicuous
> fashion
> when they fail.
> 
> 
> On Wed, Apr 13, 2016 at 2:45 AM, Slaven_Rezic via RT <
> bug-TimeDate@rt.cpan.org> wrote:
> 
> > <URL: https://rt.cpan.org/Ticket/Display.html?id=113726 >
> >
> > On 2016-04-12 20:43:54, sebastianokur@gmail.com wrote:
> > > Hi,
> > >
> > > As much as I can see from the documentation, there is no
> > > information
> > > regarding to inability to parse "YYYY-MM-DD hh:mm:ss.SSS" format.
> > > Also, I
> > > noticed it is mentioned that the str2time function should return
> > > undef if
> > > it doesn't support string for parsing.
> > >
> > > Below is the code and its output:
> > >
> > > *===*
> > > #!/usr/bin/perl
> > >
> > > use strict;
> > > use warnings;
> > > use Date::Parse;
> > >
> > > my $date1_str = "2016-01-28 23:27:13,995";
> > > my $date1_epoch = str2time($date1_str);
> > > print "date1_epoch: [$date1_epoch]\n";
> > >
> > > my $date2_str = "2016-01-28 23:27:13,996";
> > > my $date2_epoch = str2time($date2_str);
> > > print "date2_epoch: [$date2_epoch]\n";
> > >
> > > # OUTPUT:
> > > #
> > > # date1_epoch: [1453985533]
> > > # date2_epoch: [1453985473]
> > > *===*
> > >
> > > Notice that *date2_epoch* is earlier than *date1_epoch*, and –if
> > anything–
> > > epoch values should be the same.
> > >
> > > Thanks for your time and assistance in advance,
> > >
> > > --Sebastian Okur
> >
> > Actually, if the comma in the test script is replaced with a dot,
> > then
> > things work fine. I wouldn't expect that Date::Parse should parse the
> > comma
> > as a decimal dot.
> >
> >
> >

From sebastianokur@gmail.com on 2016-04-15 00:48:08 :

It might be better to match the regex based on supported formats and overload the missing time items (milliseconds, time, etc) with default values.

Main things is not making the program intelligent in order to make it try and assume what the caller is trying to do.

More importantly, making the program fail hard if an input doesn't match any of the supported formats, completely.

> On Apr 14, 2016, at 2:42 PM, Slaven_Rezic via RT <bug-TimeDate@rt.cpan.org> wrote:
> 
> <URL: https://rt.cpan.org/Ticket/Display.html?id=113726 >
> 
> I did some debugging what's going on here. An early transformation replaces all commas into spaces, so we get something like "2016-01-28 23:27:13 995". If the bit behind the seconds looks vaguely like a timezone specification, then it seems that it's used as one. In this case this means an offset of 9 hours and 95 minutes, which is causing the difference.
> 
> Probably everything >= 60 minutes could generate an error here.
> 
> It would probably also be good to improve the comma replacement, maybe don't do it all over the place.
> 
>> On 2016-04-13 11:18:05, sebastianokur@gmail.com wrote:
>> Thanks for the heads up. I already found that out and fixed my code to
>> accommodate it.
>> 
>> I guess the point I was trying to make is that *str2time* function
>> silently
>> fails by producing unpredictable results instead of failing hard by
>> returning *undef* for input formats that are not supported or not
>> entirely
>> correct in its form.
>> 
>> Since epoch values are scalars that are not as easily distinguishable
>> as
>> other-more readable date formats (*1454023633995* VS *2016-01-28
>> 23:27:13,995*), especially when the first couple of digits are
>> correct, it
>> is not immediately obvious to the developer that the result is wrong.
>> 
>> It would be very helpful if functions fail hard in a conspicuous
>> fashion
>> when they fail.
>> 
>> 
>> On Wed, Apr 13, 2016 at 2:45 AM, Slaven_Rezic via RT <
>> bug-TimeDate@rt.cpan.org> wrote:
>> 
>>> <URL: https://rt.cpan.org/Ticket/Display.html?id=113726 >
>>> 
>>>> On 2016-04-12 20:43:54, sebastianokur@gmail.com wrote:
>>>> Hi,
>>>> 
>>>> As much as I can see from the documentation, there is no
>>>> information
>>>> regarding to inability to parse "YYYY-MM-DD hh:mm:ss.SSS" format.
>>>> Also, I
>>>> noticed it is mentioned that the str2time function should return
>>>> undef if
>>>> it doesn't support string for parsing.
>>>> 
>>>> Below is the code and its output:
>>>> 
>>>> *===*
>>>> #!/usr/bin/perl
>>>> 
>>>> use strict;
>>>> use warnings;
>>>> use Date::Parse;
>>>> 
>>>> my $date1_str = "2016-01-28 23:27:13,995";
>>>> my $date1_epoch = str2time($date1_str);
>>>> print "date1_epoch: [$date1_epoch]\n";
>>>> 
>>>> my $date2_str = "2016-01-28 23:27:13,996";
>>>> my $date2_epoch = str2time($date2_str);
>>>> print "date2_epoch: [$date2_epoch]\n";
>>>> 
>>>> # OUTPUT:
>>>> #
>>>> # date1_epoch: [1453985533]
>>>> # date2_epoch: [1453985473]
>>>> *===*
>>>> 
>>>> Notice that *date2_epoch* is earlier than *date1_epoch*, and –if
>>> anything–
>>>> epoch values should be the same.
>>>> 
>>>> Thanks for your time and assistance in advance,
>>>> 
>>>> --Sebastian Okur
>>> 
>>> Actually, if the comma in the test script is replaced with a dot,
>>> then
>>> things work fine. I wouldn't expect that Date::Parse should parse the
>>> comma
>>> as a decimal dot.
> 
> 
>