|There's more than one way to do things|
Custom date calculations using Date::Manipby cavac (Curate)
|on Nov 27, 2019 at 17:57 UTC||Need Help??|
To quote: "I'm Canadian, so for us folk, it would be preferred if it was eternaldecemberize() where there's a single month of warm weather (August), and the rest December"
I have uploaded Acme::December::Eternal to CPAN. But before that, i wrote a small test program to check out the math involved. The premise is that the year starts on 1st of August, and except of August everything else is the month of December. Let's take a look (you might need to click, i've put most of the article into a readmore tag)...
Ok, that was quite a lot, let's go through it step by step:
The scripts starts with the usual boilerplate stuff, then loads Date::Manip. We also load Lingua::EN::Numbers::Ordinate, because that helps us to turn the number "1" into "1st", "2" to "2nd" and whatever else you crazy english speaking people do to numbers ;-)
We also make a Date::Manip::Date object with the date we want to turn into an EternalDecembertm date (this is a simple test script, no interactivity required).
In this step, we extract some values out of the date object. We need to know the year, the month, the day of the month (in case of August) and the day of the year (in case of not-August). We also remove leading zeros from the strings. The CPAN module does some extra stuff, but for the date calculation test this is enough.
In case of not-August, we need to know the day of the year for the first of September as well (e.g. the first day of our EternalDecember). For this, we use the year extracted from the original date.
August is easy, we just basically reassemble the string based on the original date values.
If the original date involves the months september, october, november or december, we just calculate the number of days since first of september, call it december and we are good.
This is the special case of the lot. When the original date is before August, in our calendar this is still last years december. So need to add all the days beginning from last years 1st of September to year end, plus all the days in the current year up to our original date (e.g. day of the year).
You may note here that i don't account for the previous year being a leap year when getting the "day of the year" values for september-december. While leap years shift the offset of those days by one, they shift BOTH offsets at the same time. Since we calculate the difference, this will still result in the correct value.
Note: This is still technically incorrect, because there have been instances where countries skipped days on the calendar. For example, Samoa skipped the 30th of December 2011 so they could get to the other side of the dateline for some business reason. I'll have to fix my CPAN module to account for that kind of stuff.
print $outstring, "\n";
We output the calculated date string and we are done.
Note 2: Calculating exact dates in the future is not possible, no matter how good your date library is. Not only for reasons like countries skipping (or adding) days, switching calendars, changing timezones on short notice or redefining daylight savings time (or banning/reintroducing it) willy-nilly after every change of government. No, even if you could fix all that (hint: go into politics), the nice folks at the International Earth Rotation and Reference System Service who keep our atomic clocks in sync with our solar system release a new Bulletin C twice a year to tell you if there is going to be a leap second at the end of the six month period. So, good luck estimating future timestamps ;-)
perl -e 'use Crypt::Digest::SHA256 qw[sha256_hex]; print substr(sha256_hex("the Answer To Life, The Universe And Everything"), 6, 2), "\n";'