DEV Community

Cover image for Create a digital clock using Javascript
Adam Nagy
Adam Nagy

Posted on • Edited on

Create a digital clock using Javascript

In today's tutorial we will create a digital clock that will show us the current time and it will also have a nice alarm feature. By the end of this tutorial you'll be familiar with working with the Javascript Date object, and also you'll have a minimal understanding of asynchronous code execution and the setTimeout API.

Video tutorial

If you prefer a detailed video tutorial instead, feel free to check out the tutorial that I created on my YouTube channel:

HTML

The html markup for this project is pretty simple. But before we implement that, let's add the custom font from Google that we will use in the head section of the HTML document. I'll also include the stylesheet that we will create later.

<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=Orbitron&display=swap" rel="stylesheet">
<link rel="stylesheet" href="style.css">
Enter fullscreen mode Exit fullscreen mode

We will have a section with a class of container which will hold our clock. Below that we need to create an empty div, which will be used to display the current time. I give it an id of clock, so it will be easier to target.

<section class="container">
  <div id="clock"></div>
</section>
Enter fullscreen mode Exit fullscreen mode

Next we will add the input field, so the user will be able to select a date and time to set the alarm. The important thing here is, that the input type should be "datetime-local". We'll also give it a name attribute and an onchange event handler. When the onchange event happens (so the value of the input field changes), we will fire this function setAlarmTime(this.value) that we will implement in our js file just in a bit. We pass this.value to the function which will give is the new, updated value of the input field.

<input onchange="setAlarmTime(this.value)" name="alarmTime" type="datetime-local">
Enter fullscreen mode Exit fullscreen mode

Next we have to add the control buttons. We will wrap these two buttons into a wrapper div, and give it a css class of controls. Inside that we'll add two buttons, "Set alarm" and "Clear alarm". Besides the css classes, we add click event hanler functions. We will create the functions: setAlarm() and clearAlarm() in javascript later.

<div class="controls">
  <button onclick="setAlarm()" class="button set-alarm">Set alarm</button>
  <button onclick="clearAlarm()" class="button clear-alarm">Clear alarm</button>
</div>
Enter fullscreen mode Exit fullscreen mode

Lastly, we have to include our javascript file at the bottom of our HTML document's body. We need to import it at the end of the document, so when our script will run, the DOM tree will be ready. (You could also include it in the head with the defer keyword).

<script src="index.js"></script>
Enter fullscreen mode Exit fullscreen mode

CSS

In our styles.css file I'll start with clearing every browser defined paddings and margins, and also set a dark background color.

body,html {
    margin: 0;
    padding: 0;
    background-color: #12181B;
}

* {
    box-sizing: border-box;
}
Enter fullscreen mode Exit fullscreen mode

Using flexbox we'll make the container take the full viewport, and center its content.

.container {
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
}
Enter fullscreen mode Exit fullscreen mode

For the clock we will set the font that we included earlier in the HTML, and set the desired font size. I'll also add a gradient color to the clock. To do that we will set a gradient as a background image, then we will color the font with the background gradient using the background-clip: text CSS rule.

#clock {
    font-family: 'Orbitron', sans-serif;
    font-size: 15vw;
    background-image: linear-gradient(180deg,
        rgba(99,253,136,1) 0%,
        rgba(51,197,142,1) 50%,
        rgba(39,97,116,1) 100%);
    background-clip: text;
    -webkit-background-clip: text;
    -moz-background-clip: text;
    -webkit-text-fill-color: transparent; 
    -moz-text-fill-color: transparent;
}
Enter fullscreen mode Exit fullscreen mode

Lastly, we make some styling to the control buttons and the wrapper div.

.controls {
    margin-top: 16px;
}

.button {
    font-weight: bold;
    border-radius: 5px;
    border: none;
    color: white;
    padding: 4px 8px;
    margin-left: 4px;
    cursor: pointer;
}

.set-alarm {
    background-color: #498AFB;
}

.clear-alarm {
    background-color: #FF3860;
}
Enter fullscreen mode Exit fullscreen mode

Javascript

This will be the hearth of our clock application. First, we will save a reference to our clock display (the div with the clock id) into a display variable. We'll also set up the audio for the alarm. To do that I'll use a free alarm sound form Mixkit, feel free to use any music/sound of your choice.
We will create a new Audio object and save it to the audio variable. We'll also set the loop property of the audio object to true, as we want to play the sound, till the alarm is turned off manually. As you can see we have an alarmTime and alarmTimeout variables, that we initialise with null. We will use these variables to implement the alarm functionality.

const display = document.getElementById('clock');
const audio = new Audio('https://assets.mixkit.co/sfx/preview/mixkit-alarm-digital-clock-beep-989.mp3');
audio.loop = true;
let alarmTime = null;
let alarmTimeout = null;
Enter fullscreen mode Exit fullscreen mode

Now we'll implement the clock functionality. In the updateTime function we create a new Date object. As we didn't provide any parameter to it it will create an object with the current time. Then we create 3 variables to get the hour, minute and second values from the Date object. We can do it easily using the API of the javascript Date object.
To have a nice digital display, we'll create a function which format's the time values. It places a leading zero if the number is only one digit, otherwise it uses the number. So for example if the time value provided is 9, it returns 09 instead.

function formatTime(time) {
    if ( time < 10 ) {
        return '0' + time;
    }
    return time;
}
Enter fullscreen mode Exit fullscreen mode

Lastly we have to override the display DOM node's innerText to represent the current time. I used string template literals here, so anything between ${} will be replaced with the value of that variable.

function updateTime() {
    const date = new Date();

    const hour = formatTime(date.getHours());
    const minutes = formatTime(date.getMinutes());
    const seconds = formatTime(date.getSeconds());



    display.innerText=`${hour} : ${minutes} : ${seconds}`
}
Enter fullscreen mode Exit fullscreen mode

Now we just have to call this function every second to update the displayed time. We can do that by using the setInterval API, pass the updateTime function to it and pass 1000 (it is in ms) as it's second parameter.

setInterval(updateTime, 1000);
Enter fullscreen mode Exit fullscreen mode

Now we have a working clock. It's time to implement the alarm feature. The first thing is that we have to collect and save the date and time selected by the user. We already attached an onchange event listener in the HTMl, now we just have to implement that in javascript. We will simply get the value from the event handler and save it to the alarmTime variable.

function setAlarmTime(value) {
    alarmTime = value;
}
Enter fullscreen mode Exit fullscreen mode

Now we should implement the setAlarm function. This will be responsible for setting the alarm to the desired time and play the sound. If an alarmTime is set we create two Date objects, one with the current time (empty parameters), and one using the user selected alarm time and date. If the time of the alarm is in the future, we will set the alarm. To calculate the time left till the alarm, we convert both dates to time in ms (this will give us pack time in ms since unix epoch, more details here) and subtract the future value from the current. This ways we know, how much ms is left till the alarm shall play. We just have to set a timeout to call the play method of the audio object. We'll also save the return result of the setTimeout function into the global alarmTimeout variable. We will use this reference to clear the timeout if needed.

function setAlarm() {
    if(alarmTime) {
        const current = new Date();
        const timeToAlarm = new Date(alarmTime);

        if (timeToAlarm > current) {
            const timeout = timeToAlarm.getTime() - current.getTime();
            alarmTimeout = setTimeout(() => audio.play(), timeout);
            alert('Alarm set');
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

The last thing that we have to implement is the clear functionality of the alarm. We will stop the alarm sound if it already playing, and we will cancel the set alarm if it is in the future. So in our clearAlarm function we will call the pause method of our audio object. Then if we have a scheduled alarm (so the alarmTimeout has a value), we will use the built in clearTimeout function to cancel that future function call.

function clearAlarm() {
    audio.pause();
    if (alarmTimeout) {
        clearTimeout(alarmTimeout);
        alert('Alarm cleared');
    }
}
Enter fullscreen mode Exit fullscreen mode

The whole project is available on GitHub.

Conclusion

So this is how you can create a digital clock with alarm features in a beginner-friendly way using javascript. I think that this is an interesting project that you can build, and you also practice some fundamental javascript topics, like Dates, DOM modification and asynchronous API-s like setInterval and setTimeout.

Where you can learn more from me?

I create education content covering web-development on several platforms, feel free to 👀 check them out.

I also create a newsletter where I share the week's or 2 week's educational content that I created. No bull💩 just educational content.

🔗 Links:

Top comments (7)

Collapse
 
diosamuel profile image
diosamuel

i think we can use requestAnimationFrame instead of setInterval

Collapse
 
devkam profile image
Muhammad Kamel Umar

set time interval works perfectly. But with request animation frame you need to refresh the browser before the time updates.

Collapse
 
javascriptacademy profile image
Adam Nagy

That is mostly used for animations but can work here too. Nice suggestion. 😊

Collapse
 
mnathani profile image
Murtaza Nathani

I would second vsam.. interval api would not be accurate

Collapse
 
devkam profile image
Muhammad Kamel Umar

Set time interval works perfectly. But with request animation frame you need to refresh the browser before the time updates.

Collapse
 
valeriasouza28 profile image
valeriasouza28

The order of your project here on dev.to is a little different from github.
I'm very beginner, I made the project following the explanation, but I checked and it was the same, I saw that in the git hub it was different, I redid it, still it gave an unsatisfied error, I gave a git clone. And it gave an error, several errors

Collapse
 
javascriptacademy profile image
Adam Nagy

Hi Valeria!
The order is a little bit different here because I wanted to have a clear way of how I think and plan the project.
The project itself should 100% work, if you are a beginner I highly suggesting to check the video I attached in the beginning. I think that will be easier to follow for you.
Good luck! Feel free to reach out if you face any problems.
*Also please provide error messages so we can help you resolve those issues.