Relative times

Last week Phil posted a little update about his excellent site, ooh.directory:

If you’re in the habit of visiting the Recently Updated Blogs page, and leaving it open, the times when each blog was updated will now keep up with the relentless passing of time.

Does that make sense? “3 minutes ago” will change to “4 minutes ago” and so on and on and on, until you refresh the page.

I thought that was a nice little addition, and I immediately thought of The Session. There are time elements all over the site with relative times as the text content: 2 minutes ago, 7 hours ago, 1 year ago, and so on. Those strings of text are generated on the server. But I figured it would be nice enhancement to periodically update them in the browser after the page has loaded.

I viewed source to see how Phil was doing it. The code is nice and short, using a library called Day.js with a plug-in for relative time.

“Hang on”, I thought, “isn’t there some web standard for doing this kind of thing?” I had a vague memory of some JavaScript API for formatting dates and times.

Sure enough, we’ve now got the Intl.RelativeTimeFormat object. It’s got browser support across the board.

Here’s the code I wrote.

I’ve got a function that loops through all the time elements with datetime attributes. It compares the current timestamp to that value to get the elapsed time. Then that’s formatted using the format() method and output as innerText.

You need to tell the format() method which units you want to use: seconds, minutes, hours, days, etc. So there’s a little bit of looping to figure out which unit is most appropriate. If the elapsed time is less than a minute, use seconds. If the elapsed time is less than an hour, use minutes. If the elapsed time is less than a day, use hours. You get the idea.

It’s a pity there isn’t some kind of magic unit like “auto” to do this, but it’s not much extra code to figure it out.

Anyway, that function runs periodically using setInterval(). I’ve set it to run every 30 seconds in my gist. On The Session I’ve set it to one minute.

You’ll notice that I’m grabbing all the relevant time elements—using document.querySelector('time[datetime]')—every time the function is run. That may seem inefficient. Couldn’t I just grab them once and then keep them stored as an array? But I want this to work even if the page contents have been updated with Ajax. (Do people even say “Ajax” any more? Get off my lawn, you pesky kids!)

I think I’ve written this code in an abstract way so that you should be able to drop it into any web page. For the calculations to work, you’ll need to either make sure that your datetime attributes are using timezones. Or, if there’s no timezone info, UTC is assumed.

This was a fun little piece of functionality to play around with. Now I know a little more about this Intl.RelativeTimeFormat object. The way I’m using it as a classic example of progressive enhancement. If a browser doesn’t support it, or if my code breaks, it’s no big deal. The funtionality is a little bonus that almost nobody will notice anyway. Just a small delighter …if you’re the kind of person who finds it delightful when relative time strings automatically update.

Responses

Phil Gyford

@adactio Ooh, nice! Thank you for writing that up. I’ll be delighted to copy that – including a whole library for that one tiny feature seemed a bit overkill.

3 Shares

# Shared by matt_panaro@octodon.social on Monday, August 7th, 2023 at 12:16pm

# Shared by Chris Taylor on Tuesday, August 8th, 2023 at 7:12am

# Shared by Clearleft on Tuesday, August 8th, 2023 at 12:28pm

8 Likes

# Liked by Chee Aun 🤔 on Monday, August 7th, 2023 at 12:16pm

# Liked by matt_panaro@octodon.social on Monday, August 7th, 2023 at 12:16pm

# Liked by greg on Monday, August 7th, 2023 at 12:44pm

# Liked by Large Heydon Collider on Monday, August 7th, 2023 at 1:17pm

# Liked by Chris Taylor on Tuesday, August 8th, 2023 at 7:12am

# Liked by Clearleft on Tuesday, August 8th, 2023 at 12:28pm

# Liked by John Michel on Wednesday, August 9th, 2023 at 3:51am

# Liked by Pratyush Mittal on Wednesday, August 16th, 2023 at 5:03am

Related posts

Securing client-side JavaScript

Tightening up my content security policy.

My approach to HTML web components

Naming custom elements, naming attributes, the single responsibility principle, and communicating across components.

Pickin’ dates

HTML web components for augmenting date inputs.

Speedy tunes

Improving performance on The Session.

Web Audio API update on iOS

The behaviour is more consistent now.

Related links

1loc | Favorite JavaScript single line of code

This is very handy indeed! Quick one-line JavaScript helpers categorised by type.

And, no, you don’t need to npm install any of these. Try “vendoring” them instead (that’s copying and pasting to you and me).

Tagged with

A day without Javascript

Charlie conducts an experiment by living without JavaScript for a day.

So how was it? Well, with just a few minutes of sans-javascript life under my belt, my first impression was “Holy shit, things are fast without javascript”. There’s no ads. There’s no video loading at random times. There’s no sudden interrupts by “DO YOU WANT TO FUCKING SUBSCRIBE?” modals.

As you might expect, lots of sites just don’t work, but there are plenty of sites that work just fine—Google search, Amazon, Wikipedia, BBC News, The New York Times. Not bad!

This has made me appreciate the number of large sites that make the effort to build robust sites that work for everybody. But even on those sites that are progressively enhanced, it’s a sad indictment of things that they can be so slow on the multi-core hyperpowerful Mac that I use every day, but immediately become fast when JavaScript is disabled.

Tagged with

traintimes.org.uk performance notes

I love, love, *love, traintimes.org.uk—partly because it’s so useful, but also because it’s so fast. I know public transport is the clichéd use-case when it comes to talking about web performance, but in this case it’s genuine: I use the site on trains and in airports.

Matthew gives a blow-by-blow account of the performance optimisations he’s made for the site, including a service worker. The whole thing is a masterclass in performance and progressive enhancement. I’m so glad he took the time to share this!

Tagged with

Pivoting From React to Native DOM APIs: A Real World Example - The New Stack

One dev team made the shift from React’s “overwhelming VDOM” to modern DOM APIs. They immediately saw speed and interaction improvements.

Yay! But:

…finding developers who know vanilla JavaScript and not just the frameworks was an “unexpected difficulty.”

Boo!

Also, if you have a similar story to tell about going cold turkey on React, you should share it with Richard:

If you or your company has also transitioned away from React and into a more web-native, HTML-first approach, please tag me on Mastodon or Threads. We’d love to share further case studies of these modern, dare I say post-React, approaches.

Tagged with

An origin trial for a new HTML <permission> element  |�� Blog  |  Chrome for Developers

This looks interesting. On the hand, it’s yet another proprietary creation by one browser vendor (boo!), but on the other hand it’s a declarative API with no JavaScript required (yay!).

Even if this particular feature doesn’t work out, I hope that this is the start of a trend for declarative access to browser features.

Tagged with

Previously on this day

6 years ago I wrote Console methods

Debugging fetch events in service workers.

11 years ago I wrote August in America, day four

Alexandria, Virginia.

20 years ago I wrote Lust

This collection of 1920s erotic photos features one flapper with a mandolin and another with a bouzouki.

20 years ago I wrote Anger

If you’d like to make a difference in the ever-worsening situation in Darfur, please, please, please make a donation (via the secure WorldPay service) to the World Food Program. I’ve made a modest contribution which, by itself, won’t amo

20 years ago I wrote Envy

File this under "Now, why didn’t I think of that?".

20 years ago I wrote Greed

I finally caved in and succumbed to the temptation of owning the style gadget de-siècle. I’ve ordered an iPod.

20 years ago I wrote Gluttony

Richard points out that Jamie Oliver’s website is now written in XHTML and CSS.

20 years ago I wrote Sloth

When I really should be working, the last thing I need to read is this excellent article by Tom Hodgkinson in The Guardian entitled The Virtue Of Idleness, taken from his forthcoming book How To Be Idle:

20 years ago I wrote Pride

It’s that time of year again. Brighton is party-central this weekend. Brighton Pride is an annual event celebrating the town—, sorry, city’s gay and lesbian community. It’s Fun with a capital F and it’s make me proud to live

21 years ago I wrote Wireless Mall

I’ve just made a nifty little discovery: the mall in Sierra Vista has Wi-Fi.

21 years ago I wrote Budd Blog

Brighton web designer, pal and all-round good guy Andy Budd has joined the blogosphere.

22 years ago I wrote Plustech Walking Technology

That is one cool looking machine. Eco friendly, too.

22 years ago I wrote Why I Hate Star Wars

"I thought it would be funny to go dressed up as Spock".