Last week’s arti­cle received a com­ment on a pri­vate Facebook group that amount­ed to just use JavaScript’s built-​in for­mat­ting.” So what would that look like?

#!/usr/bin/env perl

use Mojolicious::Lite -signatures;
use DateTime;

get '/' =>
    sub ($c) { $c->render( template => 'index', date => DateTime->today ) };

helper localize_date => sub ( $c, $date = DateTime->today, $style = 'full' ) {
    my $date_params = join ',' => $date->year, $date->month_0, $date->day;
    return
        qq<new Date($date_params).toLocaleString( [], {dateStyle: "$style"})>;
};

app->start;
__DATA__
@@ index.html.ep
% layout 'default';
% title 'Today';
<ul>
    <li><script>
        document.write(<%== localize_date $date %>)
    </script></li>
    % for my $style ( qw(long medium short) ) {
    <li><script>
        document.write(<%== localize_date $date, $style %>)
    </script></li>
    % }
</ul>
@@ layouts/default.html.ep
<!DOCTYPE html>
<html>
    <head><title><%= title %></title></head>
    <body><%= content %></body>
</html>

It’s struc­tured much like the Perl-​only solu­tion, with a default "/" route and a localize_date Mojolicious helper to do the for­mat­ting. I opt­ed to out­put a piece of JavaScript from the helper on lines 11 through 14 since it could be repeat­ed sev­er­al times in a doc­u­ment. You could instead declare a func­tion in the default lay­out’s HTML <head> on line 38 that would receive a date and a for­mat­ting style, out­putting the result­ing for­mat­ted date.

In the tem­plate’s list from lines 22 through 31 I decid­ed to use JavaScript document.write method calls to add our gen­er­at­ed code. This has a slew of caveats but works for our exam­ple here.

Worth not­ing is the dou­ble equals sign (<%== %>) when embed­ding a Perl expres­sion. This pre­vents Mojolicious from XML-​escaping spe­cial char­ac­ters, e.g., replac­ing "quotes" with &quot;, <angle brack­ets> with &lt; and &gt;, etc.. This is impor­tant when return­ing HTML and JavaScript code.

I also chose to use the JavaScript Date objec­t’s toLocaleString() method for my for­mat­ting on line 12. There are oth­er ways to do this:

Note that line 10 builds the para­me­ters for JavaScript’s Date con­struc­tor using the year, month_0, and day meth­ods of our Perl DateTime object; month_0 because the Date con­struc­tor takes its month as an inte­ger from 0 to 11 rather than 1 to 12. JavaScript Dates can be con­struct­ed in many ways; this seemed the sim­plest with­out hav­ing to explain things like epochs and incon­sis­tent parsing.

Why are we using Perl DateTimes and a helper any­way? I’m assum­ing that our dates are com­ing from the back­end of our appli­ca­tion, pos­si­bly inflat­ed from a data­base col­umn. If your dates are strict­ly on the fron­tend, you might decide to put your for­mat­ting code there in a JavaScript func­tion, per­haps using a JavaScript-​based tem­plat­ing library.

The bot­tom line is to do what­ev­er makes sense for your sit­u­a­tion. I pre­fer the Perl solu­tion because I like the lan­guage and its ecosys­tem and per­haps have accli­mat­ed to its quirks. The com­pli­ca­tions of JavaScript brows­er sup­port, com­pet­ing frame­works, and lay­ers of tool­ing make my head hurt. Despite this, I’m still learn­ing; if you have any com­ments or sug­ges­tions, please leave them below.