momentjs

Javascript

Using Moment.js to format dates for APIs

9 Jan , 2014  

DEMO »

My friend Billy and I were building an app that took the latest football (soccer!) fixtures and gave the weather forecast for during the match.

To get the fixtures we had to send dates formatted a certain way and we received the fixture dates formatted slightly differently. The forecast data used yet another time format. We were getting ourselves in a bit of a muddle! Trying to make sense of it all I found myself immersed in this very interesting stackoverflow thread. I spent some time here and drew 2 conclusions;

  1. I still have a lot more to learn about native javascript.
  2. If I have to use and manipulate dates and times in a completely cross-browser friendly way then I should use a library.

So use a library then!

Moment.js

Google led me to Moment.js and it is brilliant! The documentation is also excellent so I won’t spend time describing all it’s features but the TL;DR is that a moment() is a wrapper of the javascript date object with all kinds of extra wonderful goodies. Here’s how we used it.

Getting the fixtures

We are getting the fixtures from statsfc.com. Their API needed a start and end date formatted YYYY-MM-DD. We needed it from today to in a weeks time.

var today = moment();
var inOneWeek = moment().add('days', 7);

var startDate = today.format("YYYY-MM-DD");
var endDate = inOneWeek.format("YYYY-MM-DD");

var premierAPI = "http://api.statsfc.com/premier-league/fixtures.json?key=free&from="
+ startDate
+ "&to="
+ endDate
+ "&timezone=Europe/London&callback=JSON_CALLBACK";

Going through this –

  • we have created today which is a moment with no parameters. This defaults to now!
  • we have used the add(string, number) function to create a moment 7 days from now.
  • we used the format(string) function to create startDate and endDate which are correctly formatted strings.
  • we then dropped these into the API URL. This example is for Premier League fixtures.

How many hours away

To start building our weather API query we need to know how many hours away a fixture is. Before we can work that out, let’s turn our fixture time and date into a moment.

var fixtureMoment = moment(fixtureDate);
var howManyHours = fixtureMoment.diff(today, 'hours');
  • Firstly, fixtureDate is the string that we pulled directly from the JSON callback from statsfc.com. However this is formatted, moment() can take it as an argument and create a moment. I love that I don’t have to worry about this! In this case we’ve called it fixtureMoment.
  • To find out how many hours from now the fixture is we’ve used the .diff(Moment, String) function to compare today with fixtureMoment in hours.

Getting the forecast back

Now we know how many hours away the match is we can create the right API call to openweathermap.org. If its 3 hours or less we use the current weather. If its 24 hours or less we use the detailed forecast and if it’s more we use the daily forecast. The JSON that gets returned is sorted by blocks of UNIX time which we have to loop through to see if our fixture time belongs in that group. Moment.js can come to our rescue again!

for(var i=0; i<data.list.length; i++){ //loop through forecast
  var thisTime = data.list[i].dt; //get time of forecast in unix timestamp
  var thisMoment = moment.unix(thisTime); // create moment from timestamp

  if (thisMoment.isAfter(fixtureMoment)){ // becomes true on first forecast that is not before the kickoff

    $scope.weather.temp.current = data.list[i].main.temp;
    $scope.weather.description = data.list[i].weather[0].description;

    break;// then we break out of loop
  }

};
  • data is what we’ve read the JSON into and we start looping through it.
  • we read the UNIX timestamp for that block into thisTime
  • Then we create thisMoment by using the moment.unix(Number) function.
  • we then use .isAfter(Moment) to compare this with our fixtureMoment.
  • If it’s the right one we plop the info into our AngularJS $scope and break out of the loop.

Displaying it

The way that we received the fixture times from statsfc.com wasn’t really formatted in a way we thought users would like to read. football weather screenshot Luckily for us Moment.js has the .calendar() function which outputs the moment in a human friendly way (e.g., instead of showing tomorrows date it will show,’tomorrow’). Lovely!

In Summary

However your API requires the time to be formatted it’s very easy to do it with moment().format(String). However your API returns the time you can just use it as an argument to create a moment without worrying how it is formatted. There are all kinds of functions for manipulating, displaying and querying these moment objects – do check out http://momentjs.com/docs/ they are very well written and organized. To be honest I’ve been blown away by how good and useful it is! Does it show?


Leave a Reply

Your email address will not be published. Required fields are marked *