Dean Fogarty

df.id.au

Dean Fogarty

/ home / technical / svelte / wallclocks

Display the current date and time from multiple timezones as a bunch of wall clocks.


Our goal?

We want to display the current time for a number of locations around the world in the form of a wall of clocks:

5:40:05 PM
America/New_York

10:40:05 PM
Europe/London

6:40:05 AM
Asia/Tokyo

7:40:05 AM
Australia/Brisbane

5:40:05 AM
Australia/Perth

Method

We will need two components: an individual clock component (say ./WallClock.svelte) and a container that manages the clocks by feeding them the current local time and required locale (say ./WallClocks.svelte). WallClock.svelte will calculate the time in it’s locale and draw a clock with this time.

WallClocks.svelte

Similarly to our table of locations and times, we will set an interval that updates a variable, which is used as a prop to the clock component:

<script>
    import { onMount, onDestroy } from 'svelte';
    import WallClock from './WallClock.svelte';

    export let timezones = [
        'America/New_York',
        'Europe/London',
        'Asia/Tokyo',
        'Australia/Brisbane',
    ];

    let intervalId;
    let now = new Date();

    onMount(() => {
        intervalId = setInterval(() => {
            now = new Date();
        }, 1000);
    });

    onDestroy(() => {
        if (intervalId) {
            clearInterval(intervalId);
        }
    });
</script>

<div class="clocks">
    {#each timezones as timezone}
        <div class="clock">
            <WallClock {now} {timezone} />
        </div>
    {/each}
</div>

WallClock.svelte

The individual clock component uses toLocaleString() as our table version, and parses the output:

<script>
    export let timezone;
    export let now;

    let hours = 0;
    let minutes = 0;
    let seconds = 0;
    let amPm = '';

    $: {
        const d = now.toLocaleString('en-US', {
            timeZone: timezone,
            hour: 'numeric',
            minute: 'numeric',
            second: 'numeric',
        });

        [ hours, minutes, seconds, amPm ] = d.split(/[ :]/);
    }
</script>

<div>
    <svg>
        ...
    </svg>
</div>

The clock face itself is built with SVG. Rather than reproduce the it here, you are encouraged to check the clock example from the Svelte Example list; the example at the top of this page uses this code verbatim.

Usage

Use the component wherever it’s required:

<script>
    import WallClocks from './WallClocks.svelte';
</script>

<WallClocks />

Summary

We have created two components that can be used to display wall clocks based on timezone.

More information