in reply to Re^5: Date::Manip and daylight savings
in thread Date::Manip and daylight savings

you will produce an invalid local time, and therefore an exception will be thrown.

As it should. Returning an invalid local time (2003-04-06T02:00:00) would be wrong.

Are you implying that Date::Manip behaves differently?

Just convert your datetime object to the "UTC" time zone before doing date math on it, and switch it back to the local time zone afterwards.

That's bad advice. It's just a very expensive way of doing $dt->add( hours => 24 );, which is very different than adding a day.

use feature qw( say );; use DateTime; my $dt = DateTime->new( year => 2003, month => 4, day => 5, hour => 2, time_zone => 'America/Chicago', ); $dt->set_time_zone('UTC'); $dt->add( days => 1 ); $dt->set_time_zone('America/Chicago'); say $dt; # ERROR: 2003-04-06T03:00:00

My question went unanswered. Is Date::Manip only able to add 24 hours, or is it also able to add one day?

Replies are listed 'Best First'.
Re^7: Date::Manip and daylight savings
by SBECK (Chaplain) on Nov 08, 2011 at 12:45 UTC

    Here's the deal with Date::Manip.

    There are some differences between how DateTime and Date::Manip do calculations. I don't know that I agree that either is 'right' or 'wrong' because so much of it is subject to opinion... however, let me see if I can detail the differences.

    Date::Manip can add a year, and most of the time it's result is the same as DateTime. One difference is that 2004-02-29 plus one year is 2005-02-28. With DateTime, the result is 2005-03-01.

    Date::Manip can add a month. 2004-03-31 plus one month is 2004-04-30. With DateTime, the result is 2004-05-01.

    Date::Manip can add a minute, but unlike DateTime, I don't use leap seconds, so a minute is always 60 seconds. Unlike leap years, variable length months, and daylight saving time transitions, leap seconds are not something the people use in a day-to-day usage, and since I was trying to do operations as people did them, I chose to ignore leap seconds. Date::Manip also does not use fractional seconds. They are never used, except they are allowed in parsing where they are truncated and ignored.

    The relationship 1 day = 24 hours has been in Date::Manip all along, but I am working on changing that. Since adding true support for daylight saving time, that relationship isn't acceptable. However I'm not sure of all the details of how I want to change it, so I won't go into any more detail than what I said earlier in this thread. One thing though is that I won't throw an exception (or return an empty date). If you have a valid date and a valid amount of time, I'll try to figure out what is intuitively expected and return that, and so in the example above, I'll probably fall back on the 1 day = 24 hours so that I can return a valid date.

      For God sakes. Are you intentionally not answering the question?

      Is 2011-11-08 plus one year equal to 2012-11-08 in Date::Manip, or can it only add 365 days (2012-11-07)? I'd try myself, but I don't want to waste my time possibly using the wrong interface when you can do it in 30 seconds.

      I don't know that I agree that either is 'right' or 'wrong' because so much of it is subject to opinion...

      Actually, a year of a date is quite well defined. In 2011-11-08, 2011 is the year. This isn't a matter of opinion. If you add one year, you have 2012-11-08.

      I can agree there's some ambiguity as to how to handle dates that don't exist in the new calendar, but returning 2012-11-07 is not adding one year, it's adding 365 days.

        I'm not avoiding answering the question. I thought I DID answer the question. I'll try again... but please remain civil in your reply or I'll probably drop out of this conversation.

        Can Date::Manip add a year or only 365 days? I clearly stated that Date::Manip would add a year the same as TimeDate. So yes, Date::Manip can add either a year OR 365 days. The results are identical for Date::Manip and TimeDate except for the case that I cited (i.e. starting on Feb 29 on a leap year) so 2007-11-07 plus one year is 2008-11-07. The two modules differ only in the case of leap year.

        Actually, a year of a date is quite well defined. In 2011-11-08, 2011 is the year.

        True, but not relevant to the discussion. We're discussing an amount of time. The actual date is irrelevant except for the fact that the date does impacts how we think of the amount of time. That's why this is all so hard... the amount of time is not defined in a mathematical way, it's defined in a human-perspective way which is definitely not simple to enumerate. The example of adding a year is a simple example though. What does it mean to add a year to 2004-02-29. The answer is obviously not to add 365 or 366 days, and the answer is NOT just to modify the year field, because then you'd end up with 2005-02-29 which is not valid, so adding an amount of time is not a simple operation.

        It appears that the operation to add a year to a date for DateTime is as follows. Increment the year. If the resulting date is invalid (which only happens in the case of leap years), move forward the number of days you're off by. This is supported by the fact that Jan 31 + 1 month = Mar 3.

        The operation used by Date::Manip is different. Increment the year. If the resulting date is invalid, drop back to the last valid date. The advantage is that the month is preserved (you can basically think that I went from the last day in February 2004 to the last day in February 2005). In a similar fashion, Jan 31 plus 1 month is Feb 28 (or 29).

        So Date::Manip can add years, months, weeks, hours, minutes, and seconds in a similar (though not identical) fashion as DateTime. Days is the only one where we differ significantly, and I'm working on that now (I'd been intending to add this... and this discussion has pushed this to the forefront). However, here too, the results won't be the same because I'll use a operation (for example, it won't ever return an empty date).

        I'll be happy to clarify any points that are not clear.

        For God sakes.

        For gods sake are you intentionally being thick or does it come naturally. (Don't answer, we all already know!).

        What is "1 year" forward or back from the 29th of February?

        (Hint: There is no correct answer!).

        What is "1 day" forward from 1:30 am on the day daylight savings comes into force; or "1 day" back from 1:30am on the day daylight savings ends?

        (Hint: The is no one correct answer! (Even if I've mixed up my forward and backward.))

        Stop jumping up and down like a merkat on guard duty. Read what the man -- who's forgotten more on the subject than you will ever allow yourself to know -- has said, and realise he has answered you. You just aren't being receptive to the answer given.

        And don't bother responding to me. Cos I'll just downvote it and will not reply, no matter how provocative you attempt to be.


        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.