How to format dates in Vue
Tags: vue, javascript, webdev
Published: 2019-07-19 14:25:30

If you've used Vue for any length of time, you soon find that it doesn't have a lot of the fancy formatting options that some of the other frameworks seem to have out of the box. I get the feeling that Vue is very focused on minimalism and adding features that aren't core to the framework is not something they want to do. One of those features, however, is formatting dates.

Have you ever had an ugly date from your data source formatted like `"2019-07-16T20:32:21"` and thought, "What's the most straightforward way to make this not unreadable?"

My first thought was to use a computed property, but I quickly found that doesn't work very well. If I have a date nested down in an array of objects, I can't really format that using a computed property.

My next thought was to use a method in the component. But date formatting is a very common issue. I don't want to solve it in one component, I want to solve it in all of my components.

I could loop through the data and create a new property on the object to hold the `formattedCreateDate` and the `formattedUpdateDate`, but then I have to recalculate all of those every time I get a new set of data. That sounds like crying to me. Why am I saving new data in order to change the *view* of that data? Nope, that goes against all the computery sciencey stuff I've ever learned.

Arg.

So I looked around. What was the "right" answer? Something that was easy and straightforward and, more importantly, reusable and maintainable in one place.

## Vue Filters

This is when I found out that [Vue has filters](https://vuejs.org/v2/guide/filters.html). Filters are little UI helper methods that allow you to quickly format data right in the view. Filters look something like this:

```html
{{ name | capitalize }}
```

Where `name` is the variable name and capitalize is a filter that takes the value in name and formats it. Then the mustache expression will show the result of the capitalize filter.

I didn't know Vue even supported these. Every other view framework I've ever used has this feature so it's really not something I'm surprised about, but Vue does not really tout them very much. They are hidden far down in the Vue documentation, but supported they are.

This is the kind of set up I want for dates. I have the data and just want to format it differently for *this* view.

## A Simple Date Filter for Vue

So the simple answer is, use a filter that handles dates. Here's one: https://github.com/eduardnikolenko/vue-filter-date-format

This filter will take your date and spit it out in a specified format. First, you'll need a Date object. If you aren't storing your dates in your data properties as Date object, you can use https://github.com/eduardnikolenko/vue-filter-date-parse to convert a date string in an object.

```HTML
{{ '2019-07-16' | dateParse('YYYY-MM-DD') }}
```

And then use the `dateFormat` filter to show the date in a more user friendly way:

```html
{{ '2019-07-16' | dateParse('YYYY-MM-DD') | dateFormat('MMMM D, YYYY') }}
```

The nice thing about these filters is that they don't pull in any extra libraries. They are extremely light weight, just holding the filter functions that use the standard JavaScript Date object functions. [^1]

[^1]: You can take a look at the [filter function here](https://github.com/eduardnikolenko/vue-filter-date-format/blob/master/src/filters/dateFormat.ts).

This covers about 90% of my date needs and doesn't bloat my code. But what if you need something a little more beefy?

## A More Complex Date Filter in Vue

The big woohoo of date libraries in JavaScript is [Moment.js](https://momentjs.com/). Moment.js can do *anything*. If you're looking for date formats like `2 hours ago` or `Last Saturday at 9:00 PM`, then you'll need something like Moment.js. Luckily, there is a [handy filter that uses Moment.js](https://github.com/brockpetrie/vue-moment) too and will give you all of that amazing functionality:

```html
{{ '2019-07-16' | moment('from', 'now') }}
```

I wouldn't use this filter unless you absolutely need this kind of advanced functionality. Moment.js is not a small library and loading it in to your web page just to do simple date manipulations just isn't worth it.

All of these install from NPM and import right in your `main.js` file. They also have excellent documentation, so check them out and solve all of your Vue date problems for good.