aboutsummaryrefslogtreecommitdiff
path: root/challenge-132/abigail/perl/ch-1.pl
diff options
context:
space:
mode:
Diffstat (limited to 'challenge-132/abigail/perl/ch-1.pl')
-rw-r--r--challenge-132/abigail/perl/ch-1.pl81
1 files changed, 81 insertions, 0 deletions
diff --git a/challenge-132/abigail/perl/ch-1.pl b/challenge-132/abigail/perl/ch-1.pl
new file mode 100644
index 0000000000..1500742a2c
--- /dev/null
+++ b/challenge-132/abigail/perl/ch-1.pl
@@ -0,0 +1,81 @@
+#!/opt/perl/bin/perl
+
+use 5.032;
+
+use strict;
+use warnings;
+no warnings 'syntax';
+
+use experimental 'signatures';
+use experimental 'lexical_subs';
+
+#
+# See ../README.md
+#
+
+#
+# Run as: perl ch-1.pl < input-file
+#
+
+#
+# First question we need to ask for any date related exercise is
+# "What calendar are we using?". If you answer "Gregorian", then
+# the next question is, "Where are we using the calendar?", as
+# different countries switched to the Gregorian calendar at different
+# times. The first countries switched in the 16th century, but others
+# switched as late as the 20th century.
+#
+
+#
+# We will opt to use the proleptic Gregorian calendar, which is basically
+# the Gregorian calendar extended backwards to the time no Gregorian
+# calender existed.
+#
+# Since the format is given as YYYY/MM/DD, we will assume non-negative years.
+#
+
+#
+# We could pull one of the gazillion date modules from CPAN and let it
+# do the calculations. But we'll do the calculations ourselves. We'll
+# take the date, calculate its Julian Day number (rounded down, as we don't
+# care about hours and minutes), compare it to the Julian Day number of today,
+# and then calculate the Julian Day numbers of the target dates, after
+# which we convert them back to dates.
+#
+
+#
+# Conversion functions from Wikipedia
+#
+
+sub g2j ($Y, $M, $D) {
+ use integer;
+ (1461 * ($Y + 4800 + ($M - 14) / 12)) / 4 +
+ (367 * ($M - 2 - 12 * (($M - 14) / 12))) / 12 -
+ (3 * (($Y + 4900 + ($M - 14) / 12) / 100)) / 4 + $D - 32075
+}
+
+sub j2g ($J) {
+ use integer;
+ my $e = 4 * ($J + 1401 + (((4 * $J + 274277) / 146097) * 3) / 4 - 38) + 3;
+ my $D = ((5 * (($e % 1461) / 4) + 2) % 153) / 5 + 1;
+ my $M = (((5 * (($e % 1461) / 4) + 2) / 153 + 2) % 12) + 1;
+ my $Y = ($e / 1461) - 4716 + (12 + 2 - $M) / 12;
+ ($Y, $M, $D)
+}
+
+
+my @TODAY = (2021, 9, 22); # Use a fixed today, so we have expected
+ # test results.
+
+my $julian_today = g2j @TODAY;
+
+while (<>) {
+ my ($Y, $M, $D) = /[0-9]+/g;
+ my $julian_then = g2j $Y, $M, $D;
+ printf "%04d/%02d/%02d, %04d/%02d/%02d\n",
+ j2g (2 * $julian_then - $julian_today),
+ j2g (2 * $julian_today - $julian_then);
+}
+
+
+__END__