olifolkerd / tabulator

Interactive Tables and Data Grids for JavaScript
http://tabulator.info
MIT License
6.78k stars 821 forks source link

datetimediff not very pretty #3957

Closed mikeymckay closed 2 years ago

mikeymckay commented 2 years ago

I was disappointed in the output of the datetimediff formatter. Negative numbers, decimals. Ugliness in general. There seem to be issues in the human function in Luxon (https://github.com/moment/luxon/issues/1134). At any rate, I hacked together my own version. It's output looks like this:

15 hours 60 minutes ago

In case it is useful to anyone, here is the coffeescript version.

        formatter: (cell, formatterParams, onRendered) =>
          DT = window.DateTime || luxon.DateTime;
          inputFormat = formatterParams.inputFormat ?= "yyyy-MM-dd HH:mm:ss"
          invalid = formatterParams.invalidPlaceholder ?= ""
          suffix = formatterParams.suffix ?= false
          unit = formatterParams.unit ?= "days"
          humanize = formatterParams.humanize ?= false
          date = formatterParams.date ?= DT.now()
          value = cell.getValue()

          returnVal = if typeof DT != 'undefined'
            newDatetime
            if DT.isDateTime(value)
              newDatetime = value
            else if inputFormat == 'iso'
              newDatetime = DT.fromISO(String(value))
            else
              newDatetime = DT.fromFormat(String(value), inputFormat)
            if newDatetime.isValid
              newDatetime.diff(date, unit)
            else
              if invalid == true
                value
              else if typeof invalid == 'function'
                invalid(value)
              else
                invalid
          else
            console.error 'Format Error - \'datetimediff\' formatter is dependant on luxon.js'

          returnString = (for unit, value of returnVal.values
            unless value is 0
              value = Math.round(Math.abs(value))
              if value is 1
                "#{value} #{unit}".replace(/s$/,"")
              else
                "#{value} #{unit}"
          ).join(" ")

          returnString + " ago"
olifolkerd commented 2 years ago

Hey @mikeymckay

Thanks for getting in touch.

Tabulator uses Luxon's date time humanization functionality, which in turn uses the browsers own date time humanization functionality.

This is actually a very complex issue because managing this in a multi lingual and multi calendar context becomes a massive challenge and is inf act something that entire libraries have been built to manage.

While i appreciate your sample code, and it does provide a nicely formatted output for your usage case, turning this into something that handles all difference types across all calendars in all languages is a beast of a task.

As this is something that is actively being worked on in the HTML spec, i am happy to wait for browsers to catch-up, but if it is a challenge you fancy tackling then feel free to submit a PR to enhance the module.

Cheers

Oli :)

mikeymckay commented 2 years ago

Thanks for the reply! Handling time right is serious black magic, I think waiting for the standards wizards to sort it out is the right approach. My code is simply there as a reference in case it can help anybody. It's also a testimony to your excellent architecture that made it easy to hack that together. Keep up the amazing work Öli!

rraymondgh commented 1 year ago

After migrating to v5.3 from v4.7 I was very disappointed with the fact luxon does not handle seconds from EPOCH at all.... Best way I found was to continue using moment with a custom formatter for datetimediff

Possibly useful for others that encounter current lack of capability in luxon. It's docs do state it support X and x formats. It does not as at today.

formatter = function (cell, formatterParams, onRendered) {
    var dur = moment.duration(moment(cell.getValue(), formatterParams.inputFormat).diff(moment.now()));
    if (formatterParams.humanize) {
        return dur.humanize();
    } else {
        return dur;
    }
}
olifolkerd commented 1 year ago

@rraymondgh I share your pain, but it is a current limitation of luxon and browser formatting in general. It is improving, but it is a very complex area when considering all date time formats and languages, so relying on the browser is the best option in the long run to reduce software bloat.

If you have a library that works for you then that is great! But the reason most people have moved on from moment now is that it has bloated to become a huge library and for most functions is no longer the best option. Moment themselves recommend you use different alternative libraries at this point. Due to this i will not be looking to include it in Tabulator.

That being said if there are any lightweight date diff humanizing libs out there i would happily accept a PR to migrate the formatter to use one of those.

Cheers

Oli :)

KrunchMuffin commented 3 months ago

I found this because suffix was not working. I found this on MSDN and it has really good adoption.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/RelativeTimeFormat https://caniuse.com/?search=Intl.RelativeTimeFormat