Search code examples
javascriptmongodbvue.jstimestampdate-fns

Date-fns RangeError: Invalid time value


Hi I want to convert the mongo db created_at timestamp to when It says ... minutes/hours ago using the date-fns library. The function is called formatDistanceToNow which returns time since the date time provided. I'm using Vue for front end but can't seem to get it working.

<template>
    <div class="feed">
      <div v-for="post in feed" :key="post.id" class="post">
        <h3>{{ post.name }}</h3>
        <p>{{ post.timestamp }}</p> // return 2021-06-12T12:59:57.337Z
        <p>{{ Date(post.timestamp) }}</p> // return Mon Jun 14 2021 16:02:22 GMT+0100 (British Summer Time)
        <!-- <p>{{ formatDate(post.timestamp) }}</p> -->
        <!-- <p>{{ formatDate(Date(post.timestamp)) }}</p> -->
      </div>
    </div>
</template>

<script>
import { mapState } from 'vuex'
import { formatDistanceToNow } from 'date-fns'

export default {
  computed: {
    ...mapState(['feed']),
    formatDate(timestamp){
      return formatDistanceToNow(timestamp)
    }
  }
}
</script>

The 2 commented lines of code is what I've tried, but keep getting the following error

Uncaught (in promise) RangeError: Invalid time value


Solution

  • You cannot pass an argument to a computed function, so here you'll need to use a method. Also, the time format is indeed not okay as shown in the documentation page: https://date-fns.org/v2.22.1/docs/formatDistanceToNow

    2021-06-12T12:59:57.337Z is not the same as Sat Jun 12 2021 14:59:57 GMT+0200 (Central European Summer Time) (in my timezone).
    To go from one to another, use new Date("2021-06-12T12:59:57.337Z")

    The final code is looking something like this

    <template>
      <div>
        format: {{ formatDate(test) }}
      </div>
    </template>
    
    <script>
    export default {
      data() {
        test: '2021-06-12T12:59:57.337Z',
      },
      methods: {
        formatDate(timestamp) {
          return formatDistanceToNow(new Date(timestamp))
        },
      }
    }
    </script>