4

Are there a robust and crutch-less way to print Date inside the ICU-message string, using ISO-8601 format - YYYY-MM-DDThh:mm:ss?

Subquestion 1: are other custom format string supported?

Subquestion 2: why Intl.DateTimeFormat doesn't support custom formatting?

Details and observations

I want to use ICU-messages for i18n features for the javascript application. There are at least two packages on NPM, allowing to format message-strings:

Each has some kind of formatMessageFunction, accepting the raw ICU-message, the name of locale and data for applying. But both uses Intl.DateTimeFormat (looks, like it is the industry standard):

and it can't format dates using custom format.

Despite the described limitations of mentioned implementations, the ICU describes a way of custom formatting for dates

Example

My ICU-string:

var icu_string = `Hello,
    <strong>{username}</strong>,
    it is
    <time datetime="{ts, date, ???}">{ts, date}</time>
    `;

Sample code:

var IntlMessageFormat = require('intl-messageformat'); // no matter, which NPM package to use
var formatter = new IntlMessageFormat(icu_string, 'en');
var output = formatter.format({
    username: 'Barack Obama',
    ts: new Date()
});
console.log(output);

The desirable output is Hello, <strong>Barack Obama</strong>, it is <time datetime="2016-10-25T01:01:15Z">Oct 25, 2016</time>

You could test current behavior here: format-message.github.io

Similar questions

  • question about ISO and ICU. But I don't want to play with locale parameter (the code will use the selected locale for translation).
maxkoryukov
  • 4,205
  • 5
  • 33
  • 54

2 Answers2

2

A simple workaround is to pass in the timestamp pre-formatted. At least for ISO timestamps, you can pass date.toISOString() as a separate parameter to the message.

var IntlMessageFormat = require('intl-messageformat'); // no matter, which NPM package to use
var icu_string = 'Hello, {username}, it is {ts, date} (ISO-timestamp  is {tsiso})'
var formatter = new IntlMessageFormat(icu_string, 'en');
var date = new Date();
var output = formatter.format({
    username: 'Barack Obama',
    ts: date,
    tsiso: date.toISOString()
});
console.log(output);

Both intl-messageformat and format-message have a way to define a custom format, based however on Intl.DateTimeFormat options, instead of ICU's SimpleDateFormat.

Andy VanWagoner
  • 541
  • 5
  • 5
  • 1
    Thank you for your answer (and for `format-message` too)! But the main flaw of `a custom format, based however on Intl.DateTimeFormat` is a restricted set of customizations. Intl.DateTimeFormat has really limited set of options: `two or one decimals in the month`.. Seriously, it has a deep base (thanks CLDR), but **it is not enough for real applications**, IMO – maxkoryukov Oct 25 '16 at 18:34
0

Take a look at closure, goog.i18n.DateTimeFormat: https://google.github.io/closure-library/api/goog.i18n.DateTimeFormat.html

It uses a subset of the ICU patterns (in the above link click "VIEW SOURCE", and see doc from line 33)

Warning: using your own pattern means you become responsible to "get it right", as you throw away the stuff that the library "knows" about the proper locale formatting.

What are you trying to achieve that the intl stuff doesn't support?

Mihai Nita
  • 5,547
  • 27
  • 27
  • Thanks for an answer! Looks, like with this date-functionality I should take the entire Closure toolchain into my project. It is the first flaw (for me). The other issue: _subset_ of ICU string is not a full ICU-engine. I really like [format-message](https://www.npmjs.com/package/format-message) and [messageformat](https://www.npmjs.com/package/messageformat) just because ICU fully supported. And I don't know how to convert string from my example with *Closure*.. – maxkoryukov Feb 15 '17 at 17:43
  • About use cases: html tag `` - the same date is written twice in different formats – maxkoryukov Feb 15 '17 at 17:44