Days to decompress
Weekly challenge 326 — 16 June 2025
Week 326: 16 Jun 2025
You are given a date in the format YYYY-MM-DD. Write a script to find the day number of the year that the given date represents.
Example 1 Input: $date = '2025-02-02' Output: 33 The 2nd Feb, 2025 is the 33rd day of the year. Example 2 Input: $date = '2025-04-10' Output: 100 Example 3 Input: $date = '2025-09-07' Output: 250
There are many ways to meet this challenge, and they fall into two categories: use a module or do it entirely in Perl. Which is better? I would say that in almost any imaginable real-life use case, it doesn't matter - the time taken for that calculation will be insignificant in the scale of whatever else you are doing with the data.
Also, if you are handling dates in bulk, they are very probably held in a database, from
which you can probably extract them in the day-of-year format using SQL fuctions. For example, MariaDB and
MySQL have a DAYOFYEAR()
function and Oracle has YearDay()
.
Nevertheless, my solution offers two results, one using Date::Calc 'Day_of_Year'
and the other using
simple Perl.
Both of these assume the Gregorian calendar and will require changes if you are handling dates prior to
the date that was adopted in your jurisdiction. However, with that proviso, both work from
0001-01-01 to
9999-12-31.
#!/usr/bin/perl # Blog: http://ccgi.campbellsmiths.force9.co.uk/challenge use v5.26; # The Weekly Challenge - 2025-06-16 use utf8; # Week 326 - task 1 - Day of the year use warnings; # Peter Campbell Smith binmode STDOUT, ':utf8'; use Encode; day_of_the_year('2025-02-02'); day_of_the_year('2025-04-10'); day_of_the_year('2025-09-07'); day_of_the_year('1900-12-31'); # not a leap year day_of_the_year('2000-12-31'); # was a leap year day_of_the_year('1819-05-24'); # Queeen Victoria born day_of_the_year('2047-11-09'); # my 100th birthday day_of_the_year('1752-12-31'); day_of_the_year('0001-01-01'); day_of_the_year('9999-12-31'); # today my @t = localtime; day_of_the_year(sprintf('%04d-%02d-%02d', $t[5] + 1900, $t[4] + 1, $t[3])); sub day_of_the_year { my($y, $m, $d, $day_of_year, @days_in_month); # initialise say qq[\nInput: \$date = '$_[0]']; ($y, $m, $d) = $_[0] =~ m|(\d\d\d\d)\-(\d\d)\-(\d\d)|; # method 1 - use a module use Date::Calc 'Day_of_Year'; say qq[Output 1: ] . Day_of_Year($y, $m, $d); # method 2 - use plain Perl @days_in_month = (0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31); # fix February $days_in_month[2] ++ if ($y % 4 == 0 and not ($y % 100 == 0 and $y / 400 % 4 == 0)); # days in this month plus total of previous months $day_of_year = $d + 0; $day_of_year += $days_in_month[$_] for 1 .. $m - 1; say qq[Output 2: $day_of_year]; }
Input: $date = '2025-02-02' Output 1: 33 Output 2: 33 Input: $date = '2025-04-10' Output 1: 100 Output 2: 100 Input: $date = '2025-09-07' Output 1: 250 Output 2: 250 Input: $date = '1900-12-31' Output 1: 365 Output 2: 365 Input: $date = '2000-12-31' Output 1: 366 Output 2: 366 Input: $date = '1819-05-24' Output 1: 144 Output 2: 144 Input: $date = '2047-11-09' Output 1: 313 Output 2: 313 Input: $date = '1752-12-31' Output 1: 366 Output 2: 366 Input: $date = '0001-01-01' Output 1: 1 Output 2: 1 Input: $date = '9999-12-31' Output 1: 365 Output 2: 365 Input: $date = '2025-06-16' Output 1: 167 Output 2: 167
Any content of this website which has been created by Peter Campbell Smith is in the public domain