Javascript Date.toLocaleString() ignored in Apigee API Platform - javascript

I'm developing a API Proxy in Apigee API Platform. I'm using a Javascript script to convert a Date to a User-Friendly representation.
So I have this code:
var endDate = new Date(2014, 01, 01, 00, 00, 00);
var options = {
localeMatcher: 'best fit',
weekDay: 'short',
year: 'numeric',
month: 'short',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
timezone: 'America/El_Salvador',
timeZoneName: 'short'
};
var friendly_endDate = endDate.toLocaleDateString('es-SV', options);
And I always end up with a en-US formatted date like the following:
February 1, 2014 12:00:00 UTC
Timezone, options and locale is ignored. is this normal? Am I missing something?

The latest version of Rhino (1.7R4) was released on 6/18/2012. According to the Mozilla docs on Date.toLocaleDateString, the locales and options arguments were added with the ECMAScript Internalization API, which looks like it came out in December 2012.
I think your best bet is to find a JavaScript library that can be included for your policy, and use that. See the Apigee JavaScript policy documentation for instructions on including JavaScript libraries.

I use moment JS libray. Very nicely design simple library for JS base Date manipulations. Give it a try.

We also have a working sample that shows you how to work with JavaScript libraries as includes in an API proxy:
https://github.com/apigee/api-platform-samples/tree/master/sample-proxies/base64encoder

Related

UTC Date Time to Full Date in ES6

How can i convert this 2021-01-10 12:47:29 UTC to January 10, 2021?
I'm using this below using moment.js but this works browsers but not in Safari
{moment(video?.createdAt).format('MMMM D, YYYY')}
Moment.js is deprecated. Here's an alternative using native JS features.
First we need to convert the date string into a Date object. Calling new Date(video?.createdAt) is not reliable as mentioned on the Date() constructor page on MDN:
Parsing of date strings with the Date constructor
(and Date.parse(), which works the same way)
is strongly discouraged due to browser differences and inconsistencies.
See Date Time String Format on MDN for reference of the correct format. For example:
// This expects inputs in the form of
// `2021-01-10 12:47:29 UTC`
function parseDate(dateString) {
const [date, time] = dateString.split(' ')
return new Date(`${date}T${time}.000Z`) // Z = UTC
}
Then we can use Date.prototype.toLocaleString() to format the Date object:
// This expects inputs in the form of
// `2021-01-10 12:47:29 UTC`
function parseDate(dateString) {
const [date, time] = dateString.split(' ')
return new Date(`${date}T${time}.000Z`) // Z = UTC
}
function format(dateString) {
if (!dateString) return 'some fallback value'
const date = parseDate(dateString)
return date.toLocaleString('en', {
year: 'numeric',
month: 'long',
day: 'numeric',
hour: 'numeric',
minute: 'numeric',
})
}
console.log(format('2021-01-10 12:47:29 UTC'))
//=> January 10, 2021, 2:47 PM
console.log(format(undefined))
//=> some fallback value
See Intl.DateTimeFormat() for all possible options. For example, these options produce slightly different results:
return date.toLocaleString('en', {
dateStyle: 'long',
timeStyle: 'short',
})
format('2021-01-10 12:47:29 UTC')
//=> January 10, 2021 at 2:47 PM
If the date strings can be in various formats, you probably need more robust date parsing. Or if you need exotic formattings, toLocaleString() might not meet your needs. In those cases, it might be useful to use one of the recommended Moment.js alternatives.
The new Intl DateTimeFormat API is gaining more support natively in many browsers, so it is a more future proof solution. As suggested in the doc, you can use polyfills for browsers which lack full support of this feature. Unfortunately, Safari is one of the browser which is yet to catch up.
A short snippet to achieve what you are looking for would be
new Intl.DateTimeFormat('en-US', { dateStyle: 'long'}).format(new Date("2021-01-10 12:47:29Z")) // outputs January 10, 2021
Keep in mind that date time string without Z at the end would be parsed as local time. Z means the date time supplied is UTC.
If you're searching for moment.js alternative, I would suggest date-fns. Here is a blog post that compares the 2 of them.
Here is the format documentation for date-fns.
So to answer your question using date-fns:
format(new Date(video?.createdAt), 'MMMM D, YYYY')

Formatted JavaScript Date is one day behind [duplicate]

This question already has answers here:
Why does Date.parse give incorrect results?
(11 answers)
Closed 2 years ago.
I have a date: yyyy-mm-dd that I am formatting using the International DateTimeFormat like this:
const formatter = new Intl.DateTimeFormat("en-US", { month: '2-digit', day: '2-digit', year: 'numeric', timeZone:'America/Denver'});
// GiVES SAME RESULTS AS ABOVE
//const formatter = new Intl.DateTimeFormat("en-US", { month: '2-digit', day: '2-digit', year: 'numeric'});
//const formatter = new Intl.DateTimeFormat("default" , { month: '2-digit', day: '2-digit', year: 'numeric'});
let date = "2020-03-19"
return formatter.format(Date.parse(date));
//returns 03/18/2020 which is one day behind
I've tried this with and without the timeZone attribute. How can I fix this?
The ECMAScript Date Time String Format defines formats for both date-time forms as well as date-only forms. These are used by the Date.parse function and the Date constructor when a string is passed. Behavior for those functions is defined in the docs for the Date.parse function, which contain the following statement:
... When the UTC offset representation is absent, date-only forms are interpreted as a UTC time and date-time forms are interpreted as a local time.
Thus, when you call Date.parse('2020-03-19') the defined behavior is to treat that as UTC, not as local time. (This deviates from ISO 8601.)
To change this behavior, append a time string or a time+offset string.
For example, if you want to parse the time in the local computer's time zone:
Date.parse('2020-03-19T00:00:00.000')
Or, if you want to parse in a particular time zone and know the correct offset for the given timestamp in that time zone:
Date.parse('2020-03-19T00:00:00.000-05:00')
Often one doesn't know the offset, but does know the IANA time zone identifiers (such as 'America/Chicago'). Unfortunately, ECMAScript doesn't currently have the capability to parse in a named time zone yet. That capability will be possible if/when the TC39 Temporal proposal is adopted. Until then, you could use a library such as Luxon to perform such an action. For example:
luxon.DateTime.fromISO('2020-03-19', { zone: 'America/Chicago' }).toString()
//=> "2020-03-19T00:00:00.000-05:00"
Date.parse("2020-03-19") indicates 2020-03-19 00:00:00 GMT, so it will be 2020-03-18 for America/Denver, which will be 2020-03-18 17:00:00 America/Denver
const formatter1 = new Intl.DateTimeFormat("en-US", { month: '2-digit', day: '2-digit', year: 'numeric', timeZone:'America/Denver'});
const formatter2 = new Intl.DateTimeFormat("en-US", { month: '2-digit', day: '2-digit', year: 'numeric'});
let date = "2020-03-19"
console.log(formatter1.format(Date.parse(date)));
console.log(formatter2.format(Date.parse(date)));
You have added time zone, because of that it convert date into that time zone and because of the zone it can be 1 day behind or next day.

Any javascript library which can parse string created by Intl.DateTimeFormat?

Is there any javascript library which can parse string created by Intl.DateTimeFormat and give a Date?
For example:
options = {
year: "numeric",
month: "short",
day: "numeric",
hour: "numeric",
minute: "numeric",
weekday: "short",
}
var test_date = new Date();
console.log(new Intl.DateTimeFormat('hr', options).format(test_date));
// note that test_date is just an example.
// We need to parse text created Intl.DateTimeFormat and give a Date.
will return:
sub, 21. ožu 2020. 12:41
That is great - exactly how it should be written.
But how to parse it back to be a Date?
Something like:
Date.parse('sub, 21. ožu 2020. 12:41', options, 'hr')
// hr is locale
// options are same a options given to Intl.DateTimeFormat
We tried momentjs and format 'llll', but sadly momentjs locale are different that Intl.DateTimeFormat implementation on Google Chrome (i.e., dots are added in wrong places, abbreviations for dates are incorrect, etc.). We tested with 'hr', 'sk', and few others and no luck :(
So is there any library which any javascript library which can parse string created by Intl.DateTimeFormat?

Javascript How to convert a timezone into the actual timezone abbreviation?

I have a date and need to convert it into this format
02/27/2020 3:00PM (MST)
What is the fastest way to do that in javscript like a one liner?
I tried
var options = { weekday: 'short', year: 'numeric', month: 'short', day: 'numeric', hour: 'numeric', minute:'numeric', timeZoneName: 'short' };
this.date = new Date().toLocaleDateString("en-US", options);
This also does not work
new Date().toLocaleDateString(Intl.DateTimeFormat().resolvedOptions().timeZone, options);
as I am getting asia/caluctta invalid language tag
While this works for UnitedStates this does not work for users in russia, india, europe, china.
It will show the date as
02/28/2020 +500 GMT
I need it to show as
02/28/2020 (IST) for India
or
02/28/2020 (JST) for Japan Standard time
I can recommend you to try Moment.js. It's a javascript library made especially for easier manipulation with time. Just download the .js and add it to your index.html before your script.

toLocaleDateString returning String without caring of locale

I'm developping a Discord bot in NodeJS with Discord.js, and I wanted to parse a date in format "YYYY-MM-DD" and display in long fr-FR format.
I tried :
var dateSortie = new Date("2018-06-03");
var options = {
weekday: 'long',
year: 'numeric',
month: 'long',
day: 'numeric'
};
console.log(dateSortie.toLocaleDateString("fr-FR", options));
And no matters the locale (fr-Fr, de-De, ...), it's always returning "2018 M06 3, Sun".
Sourcing from this GitHub issue:
By default --with-intl=small-icu is used to build node, which
contains just the en-US locale [...]. You will need to either build
node with --with-intl=full-icu or --with-intl=system-icu if you
want to be able to use more locales. The reason node is built with a
smaller ICU by default is file size.
Besides building your own version of node, an alternative seems to be to install the full-icu module.

Categories