Giter Site home page Giter Site logo

Relative time/dates about ecma402 HOT 45 CLOSED

zbraniecki avatar zbraniecki commented on June 8, 2024
Relative time/dates

from ecma402.

Comments (45)

zbraniecki avatar zbraniecki commented on June 8, 2024 7

Intl.RelativeTimeFormat achieved Stage 3 as of today!

from ecma402.

catamphetamine avatar catamphetamine commented on June 8, 2024 5

Just dropping by to say that I implemented a polyfill for the current Intl.RelativeTimeFormat spec in case anyone finds it useful.
https://github.com/catamphetamine/relative-time-format

from ecma402.

zbraniecki avatar zbraniecki commented on June 8, 2024 2

Today I submitted the patch proposal for an internal Gecko API mozIntl.RelativeTimeFormat which is based on the ECMA402 - https://bugzilla.mozilla.org/show_bug.cgi?id=1270140

I also submitted suggestions for the spec changes based on my implementation experience.
They're filed as issues at https://github.com/caridy/intl-relative-time-spec

from ecma402.

zbraniecki avatar zbraniecki commented on June 8, 2024 2

@ichernev thanks for chiming in!

The way we thought of DurationFormat is actually a pretty specific formatter intended to solve the specific UI problem of displaying durection in a codified form, the way music/video and timer/stopwatch do: "02:03.201" kind of thing or "-03:12" (see #47).

So, the way we see the difference between those three is:

let uf = new Intl.UnitFormat('en', {category: 'duration'});
uf.format(5, 'hour'); // "5 hours"
uf.format(-5, 'hour'); // "-5 hours"
uf.format(1, 'day'); // "1 day"


let rtf = new Intl.RelativeTimeFormat('en', {
  type: 'text'
});
rtf.format(5, 'hour'); // "in 5 hours"
rtf.format(-5, 'hour'); // "5 hours ago"
rtf.format(1, 'day'); // "tomorrow"

let df = new Intl.DurationFormat('en', {
  hour: 'numeric',
  minute: '2-digit',
  second: '2-digit'
});
df.format(5 * 60 * 1000); // "5:00:00"
df.format(-5 * 60 * 1000); // "-5:00:00"
df.format(1 * 24 * 60 * 1000); // "24:00:00"

Each one of them has different options and constrains. In particular, if you're interested in rtf and our conversation about how to handle discreet time vs absolute time, see tc39/proposal-intl-relative-time#14

Our conclusion is that we'll only handle the text type for integers, not floats (so, 0.8 day will not be turned into "yesterday").

you need to know where are you know, because 30 days could be 1 month, and it could be less than a month or more than a month. So at least if you care enough, you should have an anchor, and then most questions of how many days are in a month are sorted out.

Our current thinking about ReltiveTimeFormat is that we will not handle the anchor - but expect the client side lib (moment.js or others) to handle the anchor, and use RTF just to format the data after it does all the calculations).
This should make moment.js simpler, and carry less data, but at the same time leave it up to the lib to decide how exactly to implement the "bestFit" algorithm.

Does it work for you?

from ecma402.

zbraniecki avatar zbraniecki commented on June 8, 2024 1

That looks awesome! Thanks @caridy

I'll play with this against our use cases more, but first thing I miss here is pure duration. You have "X ago" and "in X", but you don't have "X". Examples:

  • "1 month" "1m"
  • "26 hours" / "26h"
  • "5 seconds", "5 sec", "5s"
    etc.

from ecma402.

ichernev avatar ichernev commented on June 8, 2024 1

moment crew here trying to help: so as far as I read the discussion you already figured that RelativeTimeFormat should be separate from UnitFormat, because one has the future/past and the other has absolute everything. I could argue that other units (like distance) also have from/to forms, but the data is not present in CLDR so it would be wishful thinking to combine the two interfaces, but I'd try to make them very similar.

About Duration vs RelativeTimeFormat, can you provide more info on the definitions of the two (I bet its not moment's duration). In general, with moment development we came to realize there are 2 kind of durations.

  1. Duration defined in terms of milliseconds (no fuzzy units as months or years)
  2. Durations defined in terms of months (or years) -- may be encountered when you diff two instants (moments :))

It might seem stupid but: 1 can be approximated by 2 and vice versa, but you can not do it twice (1 - 2 - 1) and expect consistent results.

So one extreme we considered is having two classes to represent those, and remember "where you came from", so 1 - 2 - 1 will result in the first 1.

Back to your thread: #35 (comment) pointed out a few issues, and these get magnified when you start dealing with months/years.

A great API that will sort most of it, is to provide anchor points for durations so they can be accurate, for example -- if you want to know how many months are 30 days (in an API like duration.display({months: true})), you need to know where are you know, because 30 days could be 1 month, and it could be less than a month or more than a month. So at least if you care enough, you should have an anchor, and then most questions of how many days are in a month are sorted out.

So the API should be able to accept duration.display({months: true, now: new Date()}). What to do if the user doesn't pass now? You can anchor in unix 0 or year 0. If you anchor on something like now or this year jan 1, then the code becomes hard to reproduce.

The point is correct duration handling can't work unless you have an anchor. So functions that deal with durations should be able to accept it. Or (maybe) even better -- durations should store the anchor themselves, when possible.

I have no idea if I solved some of your issues or created new ones :)

from ecma402.

zbraniecki avatar zbraniecki commented on June 8, 2024 1

Intl.RelativeTimeFormat proposal has reached Stage 3 at today's TC39 meeting!

from ecma402.

zbraniecki avatar zbraniecki commented on June 8, 2024 1

In other news, RTF landed behind the flag in SpiderMonkey - https://bugzilla.mozilla.org/show_bug.cgi?id=1270140

from ecma402.

jungshik avatar jungshik commented on June 8, 2024 1

As with unit format, I wonder what the plan is for 'more than one units'.

3 days and 5 hours ago
5 hours and 25 minutes ago
In 3 minutes and 40 seconds

from ecma402.

sffc avatar sffc commented on June 8, 2024 1

Thanks @anba; this proposal is now Stage 4 and merged. Closing as Fixed

from ecma402.

caridy avatar caridy commented on June 8, 2024

@zbraniecki, now that we are ready to start working on the 3rd edition (using this repo), I plan to champion the relative time feature based on the initial work that we did on https://github.com/yahoo/intl-relativeformat. Do you want to help?

from ecma402.

zbraniecki avatar zbraniecki commented on June 8, 2024

absolutely. We're currently using a very nasty hack for that[1] and I'd love to see some better, possibly CLDR based, API for that.
I'll be definitely interested in shimming whatever we come up with for Firefox and Firefox OS which should give us some ability to test how it works early on.

[1] https://github.com/mozilla-b2g/gaia/blob/19696d5db8e7e078204b15597b9d01c788e5f04f/shared/js/l10n_date.js#L132

from ecma402.

caridy avatar caridy commented on June 8, 2024

I could not find "a few minutes ago" data in CLDR, nor the "one", "less than", etc...

Here is the initial spec: https://github.com/caridy/intl-relative-time-spec, and here is the HTML version https://rawgit.com/caridy/intl-relative-time-spec/master/index.html

from ecma402.

zbraniecki avatar zbraniecki commented on June 8, 2024

Hmm, the more I think about this the more I feel like there's a direct overlap area between three proposals:

  • this one
  • #37 - abbreviate numbers
  • #32 - Unit formatting
  • NumberFormat

First of all, there are three modes - future (in 5 minutes), past (5 minutes ago) and "neutral" (5 minutes).

Second, there may be specific maximum unit to show - "50000" meters is "50km", and "5000000" meters is "5000km". Same for "12000000" minutes being "50000h".
Third, on top of maximum number, there should be an option what to do with the modulo - 125 minutes may be "2 hours" or "2 hours and 5 minutes".
The maximum number may actually be a float - "160" minutes may be "2.5 hours" or "2 hours and 30 minutes", same for "2.5 miles", "2.5 GB" etc.
And lastly, all of that should be formatter by the NumberFormat.

I think that however incremental we want to take it, we should design the API to be forward compatible to allow ourselves to add the next bits later.

from ecma402.

caridy avatar caridy commented on June 8, 2024
  1. I haven't see the data for the neutral form of time in cldr, did you?
  2. best fit vs specific unit should provide the flexibility to select the right form. If we have the concrete data in cldr I can look into expanding this proposal to cover other scales.
  3. if you look into the draft, I did use %NumberFormat% to format the numeric value before replacing the cldr {0} value in the pluralization forms.

from ecma402.

srl295 avatar srl295 commented on June 8, 2024

one day ago see CLDR UTS #35: Part 4 (Dates), #3 Calendar Fields

from ecma402.

rxaviers avatar rxaviers commented on June 8, 2024

"neutral" (5 minutes).
I haven't see the data for the neutral form of time in cldr, did you?

@caridy @zbraniecki the "neutral form" (or sometimes referred to as absolute time) you are talking about is called "unit" - #37 :) as you may already figured out.

from ecma402.

zbraniecki avatar zbraniecki commented on June 8, 2024

@rxaviers - So #37 is about abbreviation, but #32 is about units. Did you mean #32? Should we keep it separate from this API? I feel like they overlap a lot and I feel tempted to try to address future/past/absolute in one API, but I don't have much experience designing APIs like that so I can imagine that there may be an obvious reason not to.

from ecma402.

zbraniecki avatar zbraniecki commented on June 8, 2024

@caridy - in CLDR the "absolute time" is part of Duration Patterns - http://unicode.org/repos/cldr/trunk/specs/ldml/tr35-general.html#durationUnit

I'm talking about things like:
2000s -> "00:33:20.00" (0 hours, 33 minutes and 20 sec)

Is it part of your plan for this API?

from ecma402.

caridy avatar caridy commented on June 8, 2024

@zbraniecki that's a good question, we need some bikeshedding on this topic I guess. Obviously that fits into the relative time paradigm since you have to use %Date.now% to compute the lapse. The other part of the equation is to figure whether or not %Date.now% is a default value of a configuration option, allowing users to provide the pivot, just like we do in intl-relativeformat, that probably makes more sense for the absolute, but it is proven to be useful for past and future as well.

from ecma402.

zbraniecki avatar zbraniecki commented on June 8, 2024

Yeah, I mocked it today for our code in Clock/Timer/Stopwatch app and I used something like that:

var formatter = mozIntl.DurationFormat(navigator.languages, {
  hour: true,
  minute: true,
  second: true
  //millisecond: true
});
formatter.format(milliseconds);

I can see it becoming a separate formatter or becoming part of RelativeFormat.

from ecma402.

rxaviers avatar rxaviers commented on June 8, 2024

@rxaviers - So #37 is about abbreviation, but #32 is about units. Did you mean #32?

Whoops, yeap I meant #32 you're correct.

Should we keep it separate from this API? I feel like they overlap a lot and I feel tempted to try to address future/past/absolute in one API, but I don't have much experience designing APIs like that so I can imagine that there may be an obvious reason not to.

I agree with you that these three forms overlap. But, I'm not too convinced RelativeTimeFormat should include an absolute form. Because, FormatUnit can be used for that purpose.

  • 2000s could be formatted as "00:33:20.00" (0 hours, 33 minutes and 20 sec) as you have mentioned. Similarly, other units too, e.g.:
  • 65in or 5.5 feet could be formatted as 5'6", or 5 feet and 6 inches.
  • 168oz or 10.5lb could be formatted as 10 pounds and 8 ounces.
  • 182cm could be formatted as 1m and 82 cm.

I see the above as FormatUnit plus an abbreviation modifier. It just happens that it's easier to think of abbreviating 1000 into 1K, or $1,000,000 into $1M because they are powers of 10. The above unit abbreviations require that the abbreviation logic know how to convert units that are not powers of 10, including time.

PS: Eventually, there might be an API that gracefully unifies all the three (relative time formatting, unit formatting, and abbreviation). So far, I think FormatUnit is a foundation similar to what FormatPlural is for MessageFormat (or possible a different more sophisticated API for formatting messages).

from ecma402.

zbraniecki avatar zbraniecki commented on June 8, 2024

sounds great!

from ecma402.

caridy avatar caridy commented on June 8, 2024

@rxaviers that's the same conclusion we arrived yesterday when discussing this issue. RelativeTimeFormat should focus on the timeline, producing past and future, relying on %Date.now% (or a provided time frame), and we can get absolute time as part of the unit api.

from ecma402.

rxaviers avatar rxaviers commented on June 8, 2024

;)

from ecma402.

zbraniecki avatar zbraniecki commented on June 8, 2024

I separated discussion about DurationFormat to #47 since I'm not sure how it may fit into this API.

from ecma402.

caridy avatar caridy commented on June 8, 2024

update: we are cooking the proposal for the next meeting in two weeks.

from ecma402.

zbraniecki avatar zbraniecki commented on June 8, 2024

Heads up, this has been advanced to Stage 0 as of today.

from ecma402.

zbraniecki avatar zbraniecki commented on June 8, 2024

This proposal has been advanced to Stage 1 as of today.

from ecma402.

zbraniecki avatar zbraniecki commented on June 8, 2024

We plan to request stage 2 at the next TC39 meeting.

from ecma402.

zbraniecki avatar zbraniecki commented on June 8, 2024

This proposal has not reached the approval to promote to stage 2 just yet.

The particular requests are:

  • describe clearer relationship between UnitFormat and RelativeTimeFormat
  • identify the future compatibility between Duration type and RelativeTimeFormat

@maggiepint may help us get feedback from moment.js crew on this proposal in particular.

from ecma402.

ichernev avatar ichernev commented on June 8, 2024

Well, you didn't specify how to configure months showing but I guess if its the library responsibility it will be ok, in terms of correctness.

from ecma402.

zbraniecki avatar zbraniecki commented on June 8, 2024
let uf = new Intl.UnitFormat('en', {category: 'duration'});
uf.format(5, 'month'); // "5 months"
uf.format(-5, 'months'); // "-5 months"
uf.format(1, 'month'); // "1 month"


let rtf = new Intl.RelativeTimeFormat('en', {
  type: 'text'
});
rtf.format(5, 'month'); // "in 5 months"
rtf.format(-5, 'month'); // "5 months ago"
rtf.format(1, 'month'); // "next month"

// DurationFormat makes no sense for months. I believe hours is the upper unit.

from ecma402.

littledan avatar littledan commented on June 8, 2024

I want to help this proposal to move forward. In looking into it, I had a couple questions:

  • Am I right in understanding that the interface is to print out in the unit provided, and it will never round to a different unit--that's a job for the library on top, right? I had heard some descriptions to the contrary, so I just wanted to confirm.
  • Given this unit basis, it's hard for me to understand what we'd do with an eventual integration with a duration type. Seems like you'd still have to pass in the unit, in addition to taking a new direction argument, and then it could extract the whole number from that. Is this the direction we'd want to go? It's hard for me to see how it's useful--this would just be a convenience overloading implemented on top.
  • At the March 2017 TC39 meeting, there was some discussion about layering, whether we should somehow expose something lower level. Here, the natural thing to expose would be to expose the pattern strings directly that the specification uses. Per spec, the pattern strings here are simple--there's just the portion that comes before the number and the portion that comes after (or whether it omits the number). From this more minimal interface, it seems like it'd be around 30loc to implement the currently presented API. What would you think of that?
  • It seems like ICU is missing the equivalent formatToParts method, and it's correspondingly missing from the Mozilla implementation linked above. I understand that the idea is to add formatToParts to all formatters, for consistency, and this seems reasonable. I'm wondering, in addition to that, does anyone have any particular use cases in mind for formatToParts here? This could help motivate getting such a method in upstream ICU, which will be useful in some implementations. Or, if we go with the
  • Editorial: The spec text seems to be based on a RegExp parsing of a pattern string. Is this really necessary? It seems pretty complex. Why not have the pattern be an already-parsed record (especially when, here, the pattern is very simple).
  • It looks like this interface leaves out "absolute" forms like "last Tuesday". Is this intentional? (It also leaves out last2 and next2, but a comment in a header file says it's not supported in all locales--maybe better to leave out).

from ecma402.

rxaviers avatar rxaviers commented on June 8, 2024

Am I right in understanding that the interface is to print out in the unit provided, and it will never round to a different unit--that's a job for the library on top, right? I had heard some descriptions to the contrary, so I just wanted to confirm.

Correct. The low level approach was the preferred choice so far.

Given this unit basis, it's hard for me to understand what we'd do with an eventual integration with a duration type. Seems like you'd still have to pass in the unit, in addition to taking a new direction argument, and then it could extract the whole number from that. Is this the direction we'd want to go? It's hard for me to see how it's useful--this would just be a convenience overloading implemented on top.

Please, can you give examples? UnitFormat and a possible DurationFormat would be separate proposals.

At the March 2017 TC39 meeting, there was some discussion about layering, whether we should somehow expose something lower level. Here, the natural thing to expose would be to expose the pattern strings directly that the specification uses. Per spec, the pattern strings here are simple--there's just the portion that comes before the number and the portion that comes after (or whether it omits the number). From this more minimal interface, it seems like it'd be around 30loc to implement the currently presented API. What would you think of that?

IMOO, the current proposal is pretty low level already. Nevertheless, let's see what @caridy or @zbraniecki says here...

It looks like this interface leaves out "absolute" forms like "last Tuesday". Is this intentional? (It also leaves out last2 and next2, but a comment in a header file says it's not supported in all locales--maybe better to leave out).

Good point. Given the low level nature of the current API, it would be pretty straightforward to add that to the spec [1] and have rtf.format(-1, 'tue') === 'last Tuesday'. 1: By allowing [[Unit]] be those week day values too.

from ecma402.

littledan avatar littledan commented on June 8, 2024

Please, can you give examples? UnitFormat and a possible DurationFormat would be separate proposals.

I don't mean to get into those territories, I just mean as an addition frontend to this capability. TC39 asked about integration with a possible Duration type at the March 2017 meeting, so I want to explain fully either how we'd do that in the future, or if we'd If we're talking about time, why not use time units? For example, we could have an overloading like:

let fmt = Intl.RelativeTimeFormatter('en');
let dur = new Duration(100000);
console.log(fmt.format(dur, "minutes", "after"));

Anyway, we'd need these two extra arguments--we still need the units (because of that first question), and we'd have to indicate the direction (since durations don't have a direction). Then, all the API would do with this is calculate the appropriate number from the duration--not a big benefit. We can just expect the user to calculate this number, instead.

By allowing [[Unit]] be those week day values too.

Are we sure that the names will never overlap in the future? I guess it seems pretty unlikely, but probably best to check with the ICU/CLDR folks that they are comfortable reusing this single field for something that's represented in separate places elsewhere.

from ecma402.

littledan avatar littledan commented on June 8, 2024

About the overlap--never mind, in CLDR the units and the days of the week are held in the same place, see LDML.

Another minor spec issue: I'm not sure if keying off of the result of PluralRules is enough. For example, in German, there's no special "dual" PluralRules form; however, there is a special word for the day before yesterday and the day after tomorrow, as in this example. Should we put an extra Get for the exact number, before "falling back" to getting the plural category? I think this would match the structure of CLDR.

(And, this is so minor that I'm putting it in parentheses: editorially, was there a particular reason for modeling the locale database as JS objects, rather than Records?)

from ecma402.

littledan avatar littledan commented on June 8, 2024

I don't remember that happening... I thought we just go to Stage 2, and we had to go back and make the changes that were suggested in the previous meeting.

from ecma402.

zbraniecki avatar zbraniecki commented on June 8, 2024

My bad. The notes were confusing. I corrected the stages2 - RTF is in Stage 2.

from ecma402.

jungshik avatar jungshik commented on June 8, 2024

Another minor spec issue: I'm not sure if keying off of the result of PluralRules is enough. For example, in German, there's no special "dual" PluralRules form; however, there is a special word for the day before yesterday and the day after tomorrow, as in this example. Should we put an extra Get for the exact number, before "falling back" to getting the plural category? I think this would match the structure of CLDR.

I guess there are more languages like German. Korean also has special words for the day after tomorrow and the day before yesterday. Actually, it has special words for 3 days ago and 3 days from today.

from ecma402.

caridy avatar caridy commented on June 8, 2024

3 days and 5 hours ago
5 hours and 25 minutes ago
In 3 minutes and 40 seconds

we can support those in the future by providing an option for more accuracy.

from ecma402.

jungshik avatar jungshik commented on June 8, 2024
Perform ! CreateDataPropertyOrThrow(nfOptions, "minimumIntegerDigits", 2

The spec has the above provision. I wonder why minIntDigits is set to 2. That leads to zero-padding likes '04 days ago', 'In 05 hours' instead of '4 days ago' / 'In 5 hours'.

from ecma402.

FrankYFTang avatar FrankYFTang commented on June 8, 2024

Should we just closed this issue now since we already have Intl.RelativeTimeFormat in Stage 3?

from ecma402.

sffc avatar sffc commented on June 8, 2024

We can close this when the corresponding proposal reaches Stage 4 and is merged. This issue has the tag "active proposal".

from ecma402.

anba avatar anba commented on June 8, 2024

Intl.RelativeTimeFormat has been merged.

from ecma402.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.