4

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>
The Old County
  • 89
  • 13
  • 59
  • 129

3 Answers3

2

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.

VincenzoC
  • 30,117
  • 12
  • 90
  • 112
  • ok - so -- you first convert the time into seconds? -- then use this to format the date moment.duration(number, 's').format('d [day] h [hour]') – The Old County Jul 04 '17 at 00:07
  • yes. the first step I used is to adjust `relativeTimeThreshold` to get time difference in seconds in the `relativeTime` section, then I created a duration and formatted it using moment-duration-format. Moment relative time functions show give output for a single unit, the solution given in my answer is a sort of workaround. – VincenzoC Jul 04 '17 at 07:20
1

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

kano
  • 5,626
  • 3
  • 33
  • 48
  • and the language handling for countdown? I already got momentjs used on another module - not sure it would be welcome shoveling in another date handling tool - still can't handle the language switching – The Old County Jul 03 '17 at 16:25
  • Sorry, could you elaborate on `language handling`? What do you mean by this? Do you need translation/localization capabilities? – kano Jul 03 '17 at 16:28
  • @TheOldCounty Edited my answer to show you usage of Moment's Difference module. – kano Jul 03 '17 at 16:32
1

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.

Igor Kroitor
  • 1,548
  • 13
  • 16
  • also how will this work with the language switch -- I was dipping into moment.locale('de') – The Old County Jul 03 '17 at 17:04
  • @TheOldCounty, I edited the answer and converted it to a code snippet. Also, if you are concerned of locales, there's a locale-supporting version of moment.js at https://momentjs.com/downloads/moment-with-locales.js – Igor Kroitor Jul 03 '17 at 17:30
  • but the momentjs that is already installed is working with moment.local -- but you example you've hardcoded English -- days in your console – The Old County Jul 03 '17 at 18:13