Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Temporal.Duration.toLocaleString() does not return a proper human-readable string #26795

Open
dahlia opened this issue Nov 9, 2024 · 4 comments
Labels
bug Something isn't working correctly temporal upstream Changes in upstream are required to solve these issues

Comments

@dahlia
Copy link

dahlia commented Nov 9, 2024

Version: Deno 2.0.5

Expected:

> Temporal.Duration.from('P1DT6H30M').toLocaleString()
"1 day 6 hours 30 minutes"

Actual:

> Temporal.Duration.from('P1DT6H30M').toLocaleString()
"P1DT6H30M"

See also:

https://tc39.es/proposal-temporal/docs/duration.html#toLocaleString

@satyarohith satyarohith added bug Something isn't working correctly temporal labels Nov 10, 2024
@MohammadSu1
Copy link
Contributor

@bartlomieju I think the toLocaleString() function is not supported in Deno because, as mentioned in the attached document, it requires Intl.DurationFormat to work properly. I attempted to address the issue using the attached code as a workaround, but I couldn't identify the exact source of the problem.

Temporal.Duration.prototype.toLocaleString = function () {
  const parts = [];
  if (this.days) parts.push(`${this.days} day${this.days > 1 ? 's' : ''}`);
  if (this.hours) parts.push(`${this.hours} hour${this.hours > 1 ? 's' : ''}`);
  if (this.minutes) parts.push(`${this.minutes} minute${this.minutes > 1 ? 's' : ''}`);
  if (this.seconds) parts.push(`${this.seconds} second${this.seconds > 1 ? 's' : ''}`);
  return parts.length ? parts.join(' ') : '0 seconds';
};

Could you provide a hint on where Temporal is used so that I know where to begin making modifications?

@0f-0b
Copy link
Contributor

0f-0b commented Nov 13, 2024

This function will be implemented in V8 in the future. For now Intl.DurationFormat can be used instead. The polyfill below also works today.

const { bind, call } = Function.prototype;
const uncurryThis = bind.bind(call);

const Duration = Temporal.Duration;
const proto = Object.getOwnPropertyDescriptors(Duration.prototype);
const assertDuration = uncurryThis(proto.toLocaleString.value);
const getYears = uncurryThis(proto.years.get);
const getMonths = uncurryThis(proto.months.get);
const getWeeks = uncurryThis(proto.weeks.get);
const getDays = uncurryThis(proto.days.get);
const getHours = uncurryThis(proto.hours.get);
const getMinutes = uncurryThis(proto.minutes.get);
const getSeconds = uncurryThis(proto.seconds.get);
const getMilliseconds = uncurryThis(proto.milliseconds.get);
const getMicroseconds = uncurryThis(proto.microseconds.get);
const getNanoseconds = uncurryThis(proto.nanoseconds.get);

const DurationFormat = Intl.DurationFormat;
const proto2 = Object.getOwnPropertyDescriptors(DurationFormat.prototype);
const formatDuration = uncurryThis(proto2.format.value);

Object.assign(Duration.prototype, {
  toLocaleString(locales = undefined, options) {
    assertDuration(this);
    const durationFormat = new DurationFormat(locales, options);
    const duration = {
      years: getYears(this),
      months: getMonths(this),
      weeks: getWeeks(this),
      days: getDays(this),
      hours: getHours(this),
      minutes: getMinutes(this),
      seconds: getSeconds(this),
      milliseconds: getMilliseconds(this),
      microseconds: getMicroseconds(this),
      nanoseconds: getNanoseconds(this),
    };
    return formatDuration(durationFormat, duration);
  },
});

@bartlomieju
Copy link
Member

@0f-0b could you open a PR with your polyfill?

@bartlomieju bartlomieju added the upstream Changes in upstream are required to solve these issues label Nov 22, 2024
@0f-0b
Copy link
Contributor

0f-0b commented Nov 22, 2024

I opened #27000.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working correctly temporal upstream Changes in upstream are required to solve these issues
Projects
None yet
Development

No branches or pull requests

5 participants