Camel
Peter
Peter Campbell Smith

Frequent funny formats

Weekly challenge 347 — 10 November 2025

Week 347: 10 Nov 2025

Task 1

Task — Format date

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.

  • @DAYS = ("1st", "2nd", "3rd", ....., "30th", "31st")
  • @MONTHS = ("Jan", "Feb", "Mar", ....., "Nov", "Dec")
  • @YEARS = (1900..2100)

Examples


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'

Analysis

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.

Try it 

Try running the script with any input:



example: 25th Dec 2025

Script


#!/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];
}

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