SHARE
Facebook X Pinterest WhatsApp

Build a Birthday Countdown Calculator using Moment.js

Written By
thumbnail
Rob Gravelle
Rob Gravelle
Jan 25, 2017

Build a Birthday Countdown Calculator using Moment.js

In the Formatting JavaScript Date Intervals into Years, Months, Weeks, and Days article, I described how to break down JavaScript date intervals into various units using the momentJS library. You might wonder what practical applications that this exercise might have in “real life”. There are many, but one common usage is to include them within countdown calculators, for instance, how many days remain until next Christmas. In today’s tutorial, we’ll construct an HTML5 form that provides detailed information about a person’s age and birthdays based on their date of birth. In follow-up installments, we’ll exploit momentJS’s many features to effectuate the various calculations required.

Why MomentJS?

In the Formatting JavaScript Date Intervals into Years, Months, Weeks, and Days article, I warned that calculating months and years between two dates is fraught with challenges due to the variability of month lengths and leap years. That’s why I always recommend using a well-known JS (JavaScript) date library for client-side calculation of date intervals. I personally rely on momentJS for such tasks. It’s both easy to use and yields highly accurate results.

The HTML Code

Whereas the Formatting JavaScript Date Intervals into Years, Months, Weeks, and Days demo employed the HTML5 date input type for data entry purposes, our Birthday Countdown form will use three separate number inputs for each (day, month, and year) date part. Not to say that this is superior to the alternate approach, but separating each date part does make validation a little easier. I’ve also seen dropdowns employed for this purpose.

Calculated values are displayed within read-only inputs. These are rendered borderless with a light gray background using CSS to differentiate these from input fields.

Before we get into the minutiae of the markup, let’s take a look at the form without CSS or JS, just to see what types of calculations we’ll eventually have to perform:

On what day of the week were you born?

Please Enter your birthday

(then click the “Update”button)

Numeric Month (1-12):   Day of Month (1-31):   Year (e.g. 1960):   

Today You Are:

Date of Birth:    Day of Week:

Birthday This Year:    Day of Week:

Birthday Last Year:    Day of Week:

Birthday Next Year:    Day of Week:

  Your Next Birthday will be:  

Your Age » In Years:     In Months:   In Weeks:   In Days:   In Hours:

 

To get a feel for the formatted output data, here are the results for top Canadian tennis pro Milos Raonic, who was born on December 27th, 1990:

Numeric Month (1-12):   Day of Month (1-31):   Year (e.g. 1960):   

Today You Are:

Date of Birth:    Day of Week:

Birthday This Year:    Day of Week:

Birthday Last Year:    Day of Week:

Birthday Next Year:    Day of Week:

  Your Next Birthday will be:  

Your Age » In Years:     In Months:   In Weeks:   In Days:   In Hours:

The Input Fields

The first order of business is to obtain the date parts from the user. From a UI standpoint, this is always a challenge. Text input is easiest for the user to deal with, but it places some extra burden on us with regards to validation. The number input type comes with some built-in validation, but I find it to be too simplistic for dates.

<form onreset="messagesElt.innerHTML = ' ';bDayMessage.innerText = '';">
<p>Numeric Month (1-12): <input TYPE="number" NAME="Inputmonth"> 
&nbsp;&nbsp;Day of Month (1-31): <input TYPE="number" NAME="Inputday">    
&nbsp;&nbsp;Year (e.g. 1960): <input TYPE="number" NAME="Inputyear">  
&nbsp;&nbsp;<input TYPE="button" VALUE="Update" ONCLICK="compute(this.form)">
<input TYPE="reset" VALUE="Clear"> </p>
<p id="messages">&nbsp;</p>

The button’s onclick attribute hooks right into out compute() function since we only need it to execute on the button click. The next section walks through the first part of the function code.

The compute() Function

The compute() function does three things: it validates the user input, creates moment objects for today and the user’s birth date, and then proceeds to generate the values for each output field.

function compute(form) {
   messagesElt.innerHTML = ' ';
   bDayMessage.innerText = '';
 
   var today       = moment(new Date()),
       birthday    = getBirthday(form.Inputyear, form.Inputmonth, form.Inputday);
  
   if (!birthday) return;
  
   //...

The getBirthday() function above is responsible for validation; it returns the user’s birth date as a moment object if successful, or undefined otherwise. This allows us to use a JS truthy test on it. Another noteworthy point is that momentJS offers its own function for checking a date’s validity. That allows you to create your date from just about anything without worrying about exceptions. Once instantiated, you can invoke isValid() on the moment object to confirm that the internal date is a valid one. How to validate dates using momentJS will be the subject of the next article.

Generating the Formatted Age String

The “Today You Are:” field displays the user’s age, broken down into years, months, weeks, and days. It’s what the getFormattedDateDiff() function that I presented in the Formatting JavaScript Date Intervals into Years, Months, Weeks, and Days article was designed for.

form.AgeYMD.value = Date.getFormattedDateDiff(birthday, today);

I made a couple of minor modifications to the getFormattedDateDiff(), so I’m including the source code here.

  1. I added the optional intervals argument, in case someone using my function wanted to supply different intervals from the ones I’m using.
  2. I replaced the for loop with the newer Array.forEach(). It’s cleaner.
Date.getFormattedDateDiff = function(date1, date2, intervals) {
  var b = moment(date1),
      a = moment(date2),
      intervals = intervals || ['years','months','weeks','days'],
      out = [];
 
  intervals.forEach(function(interval) {
      var diff = a.diff(b, interval);
      b.add(diff, interval);
      out.push(diff + ' ' + interval.singularize(diff));
  });

The function produces the values for each of the supplied time intervals, such as “26 years, 0 months, 1 week, 3 days”.

Here‘s a demo with today’s code (and validation) for you to play with.

Conclusion

The next article will be dedicated to the validation of dates using momentJS. In it, I will present a way to validate date parts individually without having to reference the data input components. That allows us to decouple the validation code from the UI.

Recommended for you...

The Revolutionary ES6 Rest and Spread Operators
Rob Gravelle
Aug 23, 2022
Ahead of Time (AOT) Compilation in Angular
Tariq Siddiqui
Aug 16, 2022
Converting a JavaScript Object to a String
Rob Gravelle
Aug 14, 2022
Understanding Primitive Type Coercion in JavaScript
Rob Gravelle
Jul 28, 2022
HTML Goodies Logo

The original home of HTML tutorials. HTMLGoodies is a website dedicated to publishing tutorials that cover every aspect of being a web developer. We cover programming and web development tutorials on languages and technologies such as HTML, JavaScript, and CSS. In addition, our articles cover web frameworks like Angular and React.JS, as well as popular Content Management Systems (CMS) that include WordPress, Drupal, and Joomla. Website development platforms like Shopify, Squarespace, and Wix are also featured. Topics related to solid web design and Internet Marketing also find a home on HTMLGoodies, as we discuss UX/UI Design, Search Engine Optimization (SEO), and web dev best practices.

Property of TechnologyAdvice. © 2025 TechnologyAdvice. All Rights Reserved

Advertiser Disclosure: Some of the products that appear on this site are from companies from which TechnologyAdvice receives compensation. This compensation may impact how and where products appear on this site including, for example, the order in which they appear. TechnologyAdvice does not include all companies or all types of products available in the marketplace.