#!/usr/bin/env perl use utf8; ############################################################################### # This program computes the Ordinal Day of a date. # # Copyright © 2020 Richard Lesh. All rights reserved. ############################################################################### use List::Util qw(min max); use Utils; use strict; use warnings; ############################################################################### # This function computes the Oridnal Date or number of # days starting with January 1 of the year in the proleptic # Gregorian calendar. # Source: https://en.wikipedia.org/wiki/Ordinal_date#Modulo_7 ############################################################################### sub ordinal_date { my ($M, $D, $Y) = @_; my $JAN = max(0, min(1, $M - 1)) * 31; my $FEB = max(0, min(1, $M - 2)) * 28; my $MAR = max(0, min(1, $M - 3)) * 31; my $APR = max(0, min(1, $M - 4)) * 30; my $MAY = max(0, min(1, $M - 5)) * 31; my $JUN = max(0, min(1, $M - 6)) * 30; my $JUL = max(0, min(1, $M - 7)) * 31; my $AUG = max(0, min(1, $M - 8)) * 31; my $SEP = max(0, min(1, $M - 9)) * 30; my $OCT = max(0, min(1, $M - 10)) * 31; my $NOV = max(0, min(1, $M - 11)) * 30; my $LEAP_YEAR = (int($Y / 4) - int($Y / 100) + int($Y / 400) - (int(($Y - 1) / 4) - int(($Y - 1) / 100) + int(($Y - 1) / 400))) * max(0, min(1, $M - 2)); my $od = $JAN + $FEB + $MAR + $APR + $MAY + $JUN + $JUL + $AUG + $SEP + $OCT + $NOV + $D + $LEAP_YEAR; return $od; } MAIN: { my $month = 0; my $day = 0; my $year = 0; if (scalar(@ARGV) == 3) { $month = Utils::stoiWithDefault($ARGV[0], 0); $day = Utils::stoiWithDefault($ARGV[1], 0); $year = Utils::stoiWithDefault($ARGV[2], 0); } else { print Utils::messageFormat("Syntax: \{0:s\} month day year", "OrdinalDate1"), "\n"; exit 1; } my $od = ordinal_date($month, $day, $year); print Utils::messageFormat("\{0:d\}/\{1:d\}/\{2:d\} = \{3:d\} Ordinal Date", $month, $day, $year, $od), "\n"; }