# A vanilla JS alternative to the moment.js timeFromNow() method

My friend Andrew Borstein challenged me to come up with a vanilla JS alternative to the moment.js `timeFromNow()`

method.

Challenged accepted!

## What the `moment().timeFromNow()`

method does

The `moment().timeFromNow()`

method returns a formatted string with how long ago something happened.

You pass in a date from the past, and it returns things like `a few seconds ago`

or `2 years ago`

.

```
// 4 years ago
moment([2007, 0, 29]).fromNow();
```

It only gives you dates in the past. There’s another function, `moment.timeToNow()`

, for future dates.

## What our `timeFromNow()`

helper function will do

Our helper function is going to work a *little* bit differently.

One of the things I like about vanilla JS is the increased control you have. Rather than getting a preformatted string, I’d rather have the difference in time and the time units (years, months, etc.) that I can work with however I want.

I’d also prefer a function that works for both past *and* future events.

Instead of returning a string, our helper function will return an object with the difference in time, the time units, and whether the time is in the past or future.

## Building a `timeFromNow()`

helper function

First, let’s set up a helper function that accepts `time`

as an argument.

```
var timeFromNow = function (time) {
// Code goes here...
};
```

The `time`

value can be a string, a `Date()`

object, or a unix timestamp in milliseconds.

```
// These are all valid
timeFromNow('December 31, 1999');
timeFromNow('1999/12/31');
timeFromNow(new Date('1999-12-31T10:30:00-04:00'));
timeFromNow(946650600000);
```

## Calculating the difference in time

To find the difference between the `time`

and now, we first need to get a timestamp value for our `time`

.

We’ll pass it into a `new Date()`

object, and then call the `getTime()`

method on it. We’ll also create another `new Date()`

object to get the time right now, and get a timestamp for that, too.

If there’s no valid `unixTime`

(if the user passed in a bad date, for example), we’ll return `null`

.

```
var timeFromNow = function (time) {
// Get timestamps
var unixTime = new Date(time).getTime();
if (!unixTime) return;
var now = new Date().getTime();
};
```

Next, we’ll subtract the time `now`

from our `unixTime`

to get the difference between the `time`

and now.

Both timestamps are in milliseconds, and the smallest unit we want to work with is seconds, so we’ll divide both numbers by `1000`

first to convert them to seconds.

```
var timeFromNow = function (time) {
// Get timestamps
var unixTime = new Date(time).getTime();
if (!unixTime) return;
var now = new Date().getTime();
// Calculate difference
var difference = (unixTime / 1000) - (now / 1000);
};
```

## Creating our time from now data

Next, let’s setup an object called `tfn`

that will hold our *time from now* data.

The first piece of data we’ll add is `when`

the `time`

happens: in the past, right now, or in the future. If the `difference`

is greater than `0`

, it happened in the `future`

. If it’s less than `-1`

, it happens in the `past`

. Otherwise, it’s happening right `now`

.

(*We use -1 instead of 0 to account for slight fractions that can happen with timestamps.*)

```
var timeFromNow = function (time) {
// Get timestamps
var unixTime = new Date(time).getTime();
if (!unixTime) return;
var now = new Date().getTime();
// Calculate difference
var difference = (unixTime / 1000) - (now / 1000);
// Setup return object
var tfn = {};
// Check if time is in the past, present, or future
tfn.when = 'now';
if (difference > 0) {
tfn.when = 'future';
} else if (difference < -1) {
tfn.when = 'past';
}
};
```

## Calculating time units

Next, we need to figure out if our `difference`

is `years`

, `months`

, `days`

, `hours`

, or `seconds`

long.

First, we’ll use the `Math.abs()`

method to convert any negative numbers into positive ones. Then, we can check out `unitOfTime`

.

For this, we’ll divide the `difference`

by the number of seconds in a year, month, day, and hour. If that value is greater than `1`

, that’s our unit. Otherwise, we keep going. Because the length of months can vary, we’ll use `45`

for the number of days there.

We’ll also set the `tfn.time`

, and use the `Math.floor()`

method to round down to nearest whole integer.

```
var timeFromNow = function (time) {
// ...
// Convert difference to absolute
difference = Math.abs(difference);
// Calculate time unit
if (difference / (60 * 60 * 24 * 365) > 1) {
// Years
tfn.unitOfTime = 'years';
tfn.time = Math.floor(difference / (60 * 60 * 24 * 365));
} else if (difference / (60 * 60 * 24 * 45) > 1) {
// Months
tfn.unitOfTime = 'months';
tfn.time = Math.floor(difference / (60 * 60 * 24 * 45));
} else if (difference / (60 * 60 * 24) > 1) {
// Days
tfn.unitOfTime = 'days';
tfn.time = Math.floor(difference / (60 * 60 * 24));
} else if (difference / (60 * 60) > 1) {
// Hours
tfn.unitOfTime = 'hours';
tfn.time = Math.floor(difference / (60 * 60));
} else {
// Seconds
tfn.unitOfTime = 'seconds';
tfn.time = Math.floor(difference);
}
};
```

If those numbers are confusing, let’s break it down a bit.

There are 60 seconds in a minute, 60 minutes in an hour, and 24 hours in a day. There are 365 days in a year. To calculate the number of seconds in a year, we multiply all of those numbers together.

```
// The number of seconds in a year
var year = 60 * 60 * 24 * 365;
```

For days, we would multiply 60 seconds by 60 minutes to get an hour of seconds, then multiply by 24 (the number of hours in a day).

```
// The number of seconds in a day
var day = 60 * 60 * 24;
```

## Returning our `tfn`

object

Now that we’ve done all of our calculations, the last thing to do is return our `tfn`

object.

```
var timeFromNow = function (time) {
// ...
// Return time from now data
return tfn;
};
```

## Putting it all together

Here’s a demo you can play with on CodePen. You can grab the completed helper function over on the Vanilla JS Toolkit.

This will work in all modern browsers, and at least back to IE 9.