Last week’s article received a comment on a private Facebook group that amounted to just use JavaScript’s built-​in formatting.” 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;
        qq<new Date($date_params).toLocaleString( [], {dateStyle: "$style"})>;

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

It’s structured much like the Perl-​only solution, with a default "/" route and a localize_date Mojolicious helper to do the formatting. I opted to output a piece of JavaScript from the helper on lines 11 through 14 since it could be repeated several times in a document. You could instead declare a function in the default layout’s HTML <head> on line 38 that would receive a date and a formatting style, outputting the resulting formatted date.

In the template’s list from lines 22 through 31 I decided to use JavaScript document.write method calls to add our generated code. This has a slew of caveats but works for our example here.

Worth noting is the double equals sign (<%== %>) when embedding a Perl expression. This prevents Mojolicious from XML-​escaping special characters, e.g., replacing "quotes" with &quot;, <angle brackets> with &lt; and &gt;, etc.. This is important when returning HTML and JavaScript code.

I also chose to use the JavaScript Date object’s toLocaleString() method for my formatting on line 12. There are other ways to do this:

  • Date objects also have a toLocaleDateString method. However, Mozilla has a performance note that states it’s better to use the Intl.DateTimeFormat object’s format property.
  • But Intl.DateTimeFormats browser support stands at about 70%, leaving out Safari (that’s Mac, iPhone, and iPad) and Internet Explorer users.
  • There are JavaScript libraries and polyfills to address these issues, but I’m trying to keep this example simple.

Note that line 10 builds the parameters for JavaScript’s Date constructor using the year, month_0, and day methods of our Perl DateTime object; month_0 because the Date constructor takes its month as an integer from 0 to 11 rather than 1 to 12. JavaScript Dates can be constructed in many ways; this seemed the simplest without having to explain things like epochs and inconsistent parsing.

Why are we using Perl DateTimes and a helper anyway? I’m assuming that our dates are coming from the backend of our application, possibly inflated from a database column. If your dates are strictly on the frontend, you might decide to put your formatting code there in a JavaScript function, perhaps using a JavaScript-​based templating library.

The bottom line is to do whatever makes sense for your situation. I prefer the Perl solution because I like the language and its ecosystem and perhaps have acclimated to its quirks. The complications of JavaScript browser support, competing frameworks, and layers of tooling make my head hurt. Despite this, I’m still learning; if you have any comments or suggestions, please leave them below.