The Old County
The Old County

Reputation: 89

Moment js - displaying days and hours away from a date

I am working on a project that requires this kind of text response on a date object.

"1 day 7 hours away" --- it needs to be this way - not "31 hours away" or "1 day away" -- also I am using moment js - as I am doing language switching between English and German - so I've tapped into the moment.js language locale

moment.locale('de')

I am using moment js - currently I've created a fake date object

  var futureDate = new Date()
  futureDate.setDate(futureDate.getDate() + 1)// add a day
  futureDate.setHours(7)// add 7 hours

when I try and render the moment js

moment(futureDate).endOf('day').fromNow()

it just says "in a day"

How do I modify the moment function to handle 1 day 7 hours -- and maybe re-jig the sentence?

--- code snippet attempt

moment.locale('de') // switch between en and de -- english and german

var futureDate = new Date()
futureDate.setDate(futureDate.getDate() + 1)// add a day
futureDate.setHours(7)// add 4 hours

// Results in hours
console.log(moment(futureDate).endOf('day').fromNow()); 
<script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.17.1/moment.min.js"></script>

code test 2 using difference

moment.locale('de') // switch between en and de -- english and german

var a = moment();
var b = moment(a).add(31, 'hours');

// Results in days
console.log(b.diff(a, 'days'));
console.log(b.diff(a, 'days', true)); 
<script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.17.1/moment.min.js"></script>

Upvotes: 4

Views: 3309

Answers (3)

kano
kano

Reputation: 5920

Edit: Since you mentioned you'd like to stick with Moment.js, they have moment#diff available:

var a = moment([2007, 0, 29]);
var b = moment([2007, 0, 28]);
a.diff(b, 'days') // 1

Found from: https://stackoverflow.com/a/42187373/2803743


I'd use countdown.js for this.

var futureDate = new Date()
futureDate.setDate(futureDate.getDate() + 1)// add a day
futureDate.setHours(7)// add 7 hours
var timePassed = countdown(Date.now().toString(), futureDate, countdown.DAYS|countdown.HOURS);

console.log(timePassed);

timePassed is a lovely object; in this example:

  days: 0
  end: Tue Jul 04 2017 07:17:41 GMT+0300 (EEST)
  hours: 12
  start: Mon Jul 03 2017 19:17:41 GMT+0300 (EEST)
  units: 18
  value: 43200000

Which you can then concat to your desired string.

It's not really documented well, but the lib also has a CDN https://cdnjs.com/libraries/countdown

Upvotes: 1

VincenzoC
VincenzoC

Reputation: 31482

You can use relativeTimeThreshold and relativeTime (key of moment.updateLocale) to customize how moment shows relative time (e.g. the fromNow() output).

In your case, you can:

Here a live sample:

var momEn = moment().add({d:1, h:7});
var momDe = moment().locale('de').add({d:1, h:7});

console.log(momEn.fromNow()); // in a day
console.log(momDe.fromNow()); // in einem Tag

// Change relativeTimeThreshold
moment.relativeTimeThreshold('s', 60*60*24*30*12);

// Update relative time
moment.updateLocale('en', {
  relativeTime : {
    s: function (number, withoutSuffix, key, isFuture){
      return moment.duration(number, 's').format('d [day] h [hour]');
    },
  }
});

moment.updateLocale('de', {
  relativeTime : {
    s: function (number, withoutSuffix, key, isFuture){
      return moment.duration(number, 's').format('d [Tag] h [Uhr]');
    },
  }
});

console.log(momEn.fromNow()); // in 1 day 7 hour
console.log(momDe.fromNow()); // in 1 Tag 7 Uhr
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment-with-locales.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-duration-format/1.3.0/moment-duration-format.min.js"></script>

Unfortunately you have to manually update each locale you need to support.

Upvotes: 2

Igor Kroitor
Igor Kroitor

Reputation: 1646

You can do it with moment-duration-format or with moment.diff like so:

let futureDate = new Date ()
futureDate.setDate (futureDate.getDate () + 1)// add a day
futureDate.setHours (7)
let start = moment ()
let end = moment (futureDate)

// 1st solution: with moment-duration-format

console.log (moment.duration (end.diff (start)).format ('d [days] hh [hours]', { trim: false }))

// 2nd solution: diff without moment-duration-format

let hoursDuration = end.diff (start, 'hours')
console.log (Math.floor (hoursDuration / 24) + ' days ' + (hoursDuration % 24) + ' hours')
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-duration-format/1.3.0/moment-duration-format.min.js"></script>

The first solution requires the additional moment-duration-format module, whereas the second does everything using moment.js only. Also, don't forget to npm install moment-duration-format before requiring it.

Upvotes: 1

Related Questions