ETOOBUSY 🚀 minimal blogging for the impatient
PWC132 - Mirror Dates
TL;DR
Here we are with TASK #1 from The Weekly Challenge #132. Enjoy!
The challenge
You are given a date (yyyy/mm/dd).
Assuming, the given date is your date of birth. Write a script to find the mirror dates of the given date.
Dave Cross
has built cool site that does something similar.Assuming today is 2021/09/22.
Example 1:
Input: 2021/09/18 Output: 2021/09/14, 2021/09/26 On the date you were born, someone who was your current age, would have been born on 2021/09/14. Someone born today will be your current age on 2021/09/26.
Example 2:
Input: 1975/10/10 Output: 1929/10/27, 2067/09/05 On the date you were born, someone who was your current age, would have been born on 1929/10/27. Someone born today will be your current age on 2067/09/05.
Example 3:
Input: 1967/02/14 Output: 1912/07/08, 2076/04/30 On the date you were born, someone who was your current age, would have been born on 1912/07/08. Someone born today will be your current age on 2076/04/30.
The questions
Well well well… I live in Italy in 2021 and I’ll stick to a Gregorian calendar and to people whose birthday was in the XX century or later. This is non-negotiable.
The solution
Raku has a nice Date class that supports arithmetics, so it’s as easy as doing some basic maths:
#!/usr/bin/env raku
use v6;
sub mirror-dates ($birth-date is copy) {
$birth-date = Date.new(|($birth-date.comb(/\d+/)));
my $today = Date.new(DateTime.now);
my $delta = $today - $birth-date;
return ($birth-date - $delta, $today + $delta);
}
sub MAIN ($d = '1967/02/14') { mirror-dates($d).join(', ').put }
Perl follows suit, with just a little more effort and about half of the CPAN to install DateTime:
#!/usr/bin/env perl
use v5.24;
use warnings;
use experimental 'signatures';
no warnings 'experimental::signatures';
use DateTime;
sub mirror_dates ($birth_date) {
my %bd;
@bd{qw< year month day >} = split m{\D+}mxs, $birth_date;
$birth_date = DateTime->new(%bd, hour => 12, minute => 0, second => 0);
my $today = DateTime->now;
my $delta = $today->delta_days($birth_date);
return (
$birth_date->subtract_duration($delta)->ymd('/'),
$today->add_duration($delta)->ymd('/'),
);
}
say join ', ', mirror_dates(shift // '1967-02-14');
The logic is the same, just with a bit more verbose operations. There
must be care in choosing delta_days
or the result will be
incorrect - don’t ask me why, I only know that date and time stuff are a
headache.
So… enjoy your time!