How to Create a Dynamic Timezone Clock Component in Vue with Day.js

In this tutorial, we'll build a lightweight, reusable Vue.js component that displays the current time in any specified timezone. This component will automatically update every second and handle timezone conversions seamlessly.
Prerequisites
Basic knowledge of Vue.js
Node.js and npm installed
Vue 3 with Composition API
Step 1: Set Up a New Vue Project
First, let's create a new Vue project using Vite:
npm create vite@latest timezone-clock -- --template vue
cd timezone-clock
npm install
Step 2: Install Required Dependencies
We'll use dayjs
for timezone handling:
npm install dayjs
Understanding Timezone Handling
Before we dive into the code, let's break down why we need additional libraries for timezone management:
JavaScript's native
Date
object doesn't provide robust timezone conversiondayjs
with its UTC and timezone plugins allows easy, accurate timezone transformationsThe plugins extend dayjs's capabilities to parse, manipulate, and display times across different timezones
Step 3: Create the Timezone Clock Component
Create a new file TimezoneClock.vue
in your src/components
directory:
<script setup>
import { computed, ref, onBeforeUnmount } from 'vue';
import dayjs from 'dayjs';
import utc from 'dayjs/plugin/utc';
import dayjsTimezone from 'dayjs/plugin/timezone';
// Define component props
const props = defineProps({
timezone: {
type: String,
required: true,
},
});
// Extend dayjs with UTC and timezone plugins
dayjs.extend(utc);
dayjs.extend(dayjsTimezone);
// Reactive reference to current time
const currentTime = ref(new Date());
// Function to update current time
const updateCurrentTime = () => {
currentTime.value = new Date();
};
// Computed property to format time in specified timezone
const formattedTime = computed(() =>
dayjs(currentTime.value).tz(props.timezone).format('h:mm a z')
);
// Set up interval to update time every second
const updateTimeInterval = setInterval(updateCurrentTime, 1000);
// Clean up interval when component is unmounted
onBeforeUnmount(() => {
clearInterval(updateTimeInterval);
});
</script>
<template>{{ formattedTime }}</template>
Key Concepts Explained
1. Props and Component Configuration
defineProps()
creates a prop calledtimezone
required: true
ensures a timezone must be provided when using the componentProp is typed as a
String
to accept timezone names like "America/New_York"
2. Reactive Time Management
ref(new Date())
creates a reactive reference to the current timeupdateCurrentTime()
updates this referencesetInterval()
calls this function every second, creating a "live" clock
3. Time Formatting with dayjs
dayjs().tz()
converts the current time to the specified timezone.format('h:mm a z')
displays time as:h
: Hour in 12-hour formatmm
: Minutesa
: AM/PM indicatorz
: Timezone abbreviation
4. Cleanup with onBeforeUnmount
clearInterval()
stops the timer when the component is removedPrevents memory leaks and unnecessary background processes
Step 4: Using the Component
In your App.vue
, demonstrate the component:
<script setup>
import TimezoneClock from '@/components/TimezoneClock.vue';
</script>
<template>
<div>
<div>
<h1>World Clocks</h1>
New York: <TimezoneClock timezone="America/New_York" />
<br />
<br />
London: <TimezoneClock timezone="Europe/London" />
<br />
<br />
Tokyo: <TimezoneClock timezone="Asia/Tokyo" />
</div>
</div>
</template>
Advanced Tips
Always use IANA timezone names (like "America/New_York")
Handle potential timezone name errors with a default fallback
Consider adding props for custom date formatting
Conclusion
You've now created a flexible, reactive timezone clock component in Vue.js. By leveraging dayjs and Vue's Composition API, we've built a powerful time display solution that's both performant and easy to use.
Learning Challenges
Add a prop to customize the time format
Implement error handling for invalid timezones
Create a timezone selector feature
Happy coding! ๐โจ
Subscribe to my newsletter
Read articles from Kellen directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
