# How to calculate reading time, like Medium Published on20 August 2017 5 minute read

Recently, I took a leaf out of Medium's book and decided to add the estimated reading time to my blog posts. This was so that people could decide whether they had enough time to commit to the post before reading it.

The task was pretty simple. It was only 7 lines of Javascript. I wrote it and implemented it in a single train journey to Leeds.

When I tweeted about it, I got a request to write an explanation of the code. So here it goes!

Below is the function. I'll go through each line of code and explain in detail what it does, so even if you're not using Node or Javascript, you can reverse engineer it for your language of choice.

``````function readingTime(text) {
const wordsPerMinute = 200;
const noOfWords = text.split(/\s/g).length;
const minutes = noOfWords / wordsPerMinute;
}``````

## Step 1 - Declaring the function

The first line sets up the function, giving it the name `readingTime`. It also tells it to expect an input which it can refer to as `text`.

`text` will be your article or blog post that you want to calculate the reading time on.

``function readingTime(text) {}``

## Step 2 - Setting the number of words per minute

The next step is to create a variable called `wordsPerMinute`, and set it to 200. The value is 200, because according to Google, that's the average number of words per minute a person can read.

I've used `const` to declare my variables as I'm using ES6 syntax, but you can also use `var` if you prefer.

``````function readingTime(text) {
const wordsPerMinute = 200;
}``````

## Step 3 - Calculating the number of words

The next step is the most complex. It's where we take the text and then calculate how many words it contains. There's actually 3 separate steps all chained together.

First, we call the `.split()` method. We can call this on any string. It works by breaking the string up on a specific character you pass in, and it returns an array. For example, `'I-am-Craig'.split('-')` would return an array of `['I', 'am', 'Craig']`. This is because I told it to split on a hyphen, so it went through and used the hypens as the marker to create the array.

The problem is, article text isn't joined by hyphens. It will be joined by spaces, tabs, new lines, returns etc. So we're going to need to tell it to split on more than one thing. To do this, we use a regular expression, also known as regex.

A regex will match a pattern rather than a single character. To define a regex, we put a pattern inside of two forward slashes. The pattern I used was `\s`. This stands for whitespace, and it will match spaces, tabs, returns and newlines.

However, `/\s/` would actually stop after finding the first whitespace character. So, we put a `g` after the closing slash, which stands for global. This tells the regex to keep going to the end even if it has found a match.

Once we have our regex pattern, we pass that into the `split()` method from earlier. This will use any whitespace characters to break up the text, and return an array of all the words.

Now, the last step is to count all the words in the array. To do that, we use the `.length` property. This can be called on any array and will return a number. For example, our array from earlier `['I', 'am, 'Craig'].length` would return 3.

Chain them all together and it will give you the number of words in your text.

``````function readingTime(text) {
const wordsPerMinute = 200;
const noOfWords = text.split(/\s/g).length;
}``````

## Step 4 - Calculate the read time in minutes

In this step, create another new variable called minutes. Set it to be the number of words divided by the words per minute. This will calculate the average read time based on our 200 word per minute estimate from Google. For example, 400 words / 200 words per minute would equal 2 minutes.

``````function readingTime(text) {
const wordsPerMinute = 200;
const noOfWords = text.split(/\s/g).length;
const minutes = noOfWords / wordsPerMinute;
}``````

## Step 5 - Rounding up the read time

Whenever you're doing division, it's likely you won't get nice round numbers. You will usually end up with a decimal. We don't want to tell somebody it will take them 3.34 minutes to read an article, so we round the number.

I've used the `.ceil()` method to do this. This stands for ceiling, and it will round any decimals up to the nearest whole number. Because we're using ceiling it will only round up.

For example:

``````Math.ceil(1)   // 1
Math.ceil(1.1) // 2
Math.ceil(1.9) // 2
Math.ceil(2)   // 2``````

I chose to round up, as I thought it was better to over estimate than to under estimate. If you want to round down you can use `.floor()` instead of `.ceil()`.

I guess a downside of using ceiling, is that passing in one word would still return a read time of 1 minute. However, I don't plan on doing any 1 word blog posts, so it shouldn't affect me.

``````function readingTime(text) {
const wordsPerMinute = 200;
const noOfWords = text.split(/\s/g).length;
const minutes = noOfWords / wordsPerMinute;
}``````

## Step 6 - Return and finish

Now that you have your rounded time in minutes, the last step is to return it from your function. To make it more readable, I've added some words so if our read time was 2, the function would return `2 minute read`.

I've used backticks to declare my string, but you can do it using `readTime + ' minute read'` if you prefer.

``````function readingTime(text) {
const wordsPerMinute = 200;
const noOfWords = text.split(/\s/g).length;
const minutes = noOfWords / wordsPerMinute;
``````const post = 'This is a test post';