Frequent funny formats
Weekly challenge 347 — 10 November 2025
Week 347: 10 Nov 2025
You are given a date in the form: 10th Nov 2025.
Write a script to format the given date in the form: 2025-11-10 using the set below.
Example 1 Input: $str = '1st Jan 2025' Output: '2025-01-01' Example 2 Input: $str = '22nd Feb 2025' Output: '2025-02-22' Example 3 Input: $str = '15th Apr 2025' Output: '2025-04-15' Example 4 Input: $str = '23rd Oct 2025' Output: '2025-10-23' Example 5 Input: $str = '31st Dec 2025' Output: '2025-12-31'
If I had £100 for every time I've had to decode or encode dates I'd have retired a lot sooner.
In this instance perhaps the only thing worth a few moments thought is the decoding of the month. I once had a project that handled a file every morning containing about 500,000 dates in the Jan .. Dec format, and I established by experiment that using a hash lookup like this:
%mo = (Jan => 1, Feb => 2, Mar => 3, Apr => 4,
May => 5, Jun => 6, Jul => 7, Aug => 8, Sep => 9,
Oct => 10, Nov => 11, Dec => 12);
was fastest, and also allowed trapping of misformatted months
such as Jna.
Of course there are many other ways to do it.
This challenge's output format is of course that specified by ISO 8601, and - of course - that should be the default choice of date (and time) text formatting today. The Wikipedia entry may be worth re-reading, as there have been minor changes to the standard as recently as 2022.
#!/usr/bin/perl # Blog: http://ccgi.campbellsmiths.force9.co.uk/challenge use v5.26; # The Weekly Challenge - 2025-11-10 use utf8; # Week 347 - task 1 - Format date use warnings; # Peter Campbell Smith binmode STDOUT, ':utf8'; use Encode; format_date('15th Jan 2025'); format_date('22nd Feb 2025'); format_date('1st Jan 1900'); format_date('31st Dec 2100'); format_date('10th Nov 2025'); sub format_date { my ($string, $output, %mo, $d, $m, $y, $i); # initialise $string = shift; %mo = (Jan => 1, Feb => 2, Mar => 3, Apr => 4, May => 5, Jun => 6, Jul => 7, Aug => 8, Sep => 9, Oct => 10, Nov => 11, Dec => 12); # do it if (($d, $m, $y) = $string =~ m|(\d{1,2}).+?([a-z]{3}).+?(\d{4})|i) { $output = sprintf('%04d-%02d-%02d', $y, $mo{$m}, $d); } else { $output = 'illegal format'; } say qq[\nInput: '$string']; say qq[Output: $output]; }
Input: '15th Jan 2025' Output: 2025-01-15 Input: '22nd Feb 2025' Output: 2025-02-22 Input: '1st Jan 1900' Output: 1900-01-01 Input: '31st Dec 2100' Output: 2100-12-31 Input: '10th Nov 2025' Output: 2025-11-10
Any content of this website which has been created by Peter Campbell Smith is in the public domain