Saturday, November 28, 2020

[jtmyersj] March 2020 epoch

below is Perl script which converts a date given as YEAR MONTH DAY to a day in March 2020, inspired by the start of lockdowns due to COVID-19.  Since then, days became the same, no special events, no going anywhere, working from home every day.

$ perl marchn.pl 2020 3 1
Sunday, March 1, 2020 = March 1, 2020

$ perl marchn.pl 2020 4 1
Wednesday, April 1, 2020 = March 32, 2020

$ perl marchn.pl 2020 11 3
Tuesday, November 3, 2020 = March 248, 2020

$ perl marchn.pl 2021 1 1
Friday, January 1, 2021 = March 307, 2020

$ perl marchn.pl 2021 3 1
Monday, March 1, 2021 = March 366, 2020

dates before March 1:

curiously, March 0 was a leap day:

$ perl marchn.pl 2020 2 29
Saturday, February 29, 2020 = March 0, 2020

$ perl marchn.pl 2020 2 28
Friday, February 28, 2020 = March -1, 2020

$ perl marchn.pl 2020 2 1
Saturday, February 1, 2020 = March -28, 2020

$ perl marchn.pl 2020 1 1
Wednesday, January 1, 2020 = March -59, 2020

$ perl marchn.pl 2000 1 1
Saturday, January 1, 2000 = March -7364, 2020

$ perl marchn.pl 1900 1 1
Monday, January 1, 1900 = March -43888, 2020

proleptic Gregorian calendar:

$ perl marchn.pl 1500 2 28
Wednesday, February 28, 1500 = March -189927, 2020

$ perl marchn.pl 1500 2 29
Thursday, March 1, 1500 = March -189926, 2020

things break for dates prior to Wednesday, March 1, year 0 (1 BCE / BC):

$ perl marchn.pl 0 3 1
Wednesday, March 1, 0 = March -737789, 2020

$ perl marchn.pl 0 2 29
Wednesday, March 1, 0 = March -737790, 2020

$ perl marchn.pl 0 2 28
Tuesday, February 31, 0 = March -737791, 2020

Due to the way mktime is implemented -- you can put any number in the day field -- the script can also do the reverse conversion:

$ perl marchn.pl 2020 3 100
Monday, June 8, 2020 = March 100, 2020

$ perl marchn.pl 2020 3 666
Sunday, December 26, 2021 = March 666, 2020

$ perl marchn.pl 2020 3 1000
Friday, November 25, 2022 = March 1000, 2020

$ perl marchn.pl 2020 3 -59
Wednesday, January 1, 2020 = March -59, 2020

counting days from the start of an epoch is intriguing because it enables decimal time.  partial days, amount of time past midnight, could be denoted by a decimal fraction.  (but the script below does not support partial days.)

because the epoch marks something important for humans, and because the day-night cycle is important for humans, let leap seconds cause the length of the day to be non-uniform, like UTC.  one can calculate the rough time difference between two dates to the precision of a day with subtraction, but computing the difference in seconds between of two precisely specified decimal dates will require leap second tables.

Julian Dates used by astronomers also counts days from a date in the distant past (offset by 0.5 because days start at noon).

midnight, Saturday, February 29, 2020 = March 0.0 , 2020 = JD 2458908.5

without arguments, the script converts today's date to its day in March 2020.

update: the sdate utility is very similar.  recent versions include a switch to specify the COVID-19 epoch.  its syntax was dark humorously chosen to be flexible enough to specify COVID epochs beyond 19, to be implemented when we know when they begin.


#!perl -wl
use POSIX qw(strftime mktime round);
if(@ARGV){
  die unless defined($year=shift @ARGV);
  die unless defined($month=shift @ARGV);
  die unless defined($day=shift @ARGV);
} else {
  @brokendowntime=localtime;
  $day=$brokendowntime[3];
  $month=$brokendowntime[4]+1;
  $year=$brokendowntime[5]+1900;
}
$second=$minute=0;
$hour=12; # use noon to smooth over weirdness of daylight saving time changes

($mval=strftime("%e",$second,$minute,$hour,$day,$month-1,$year-1900)) =~ s/^\s*//; # remove ugly leading space

$t=mktime($second,$minute,$hour,$day,$month-1,$year-1900);
$start=mktime($second,$minute,$hour,29,2-1,2020-1900); # February 29, 2020 is March 0, 2020

$elapseddays=($t-$start)/60./60./24.;
# print $elapseddays;
print "",strftime('%A, %B '.$mval.', %Y',$second,$minute,$hour,$day,$month-1,$year-1900), " = March ",round($elapseddays),", 2020";
# rounding to the nearest integer deals with daylight saving time.

No comments :