Localized short time string using moment.js - javascript

How do I get time string from moment.js object with respect to current locale?
moment().format('HH:mm')
always get the same result regardless of localization.
I want similar result as I would use in angular using shortTime:
formatDate(new Date(), 'shortTime'): // HH:mm, resp hh:mm a

You can simply use Localized formats listed in format() docs
Because preferred formatting differs based on locale, there are a few tokens that can be used to format a moment based on its locale.
There are upper and lower case variations on the same formats. The lowercase version is intended to be the shortened version of its uppercase counterpart.
Here a live sample:
console.log( moment().format('LT') );
moment.locale('it');
console.log( moment().format('LT') );
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment-with-locales.min.js"></script>

Related

Parsing date from DD/MM/YYYY with Luxon javascript

I have a date in this format "DD/MM/YYYY" and I want to convert it to a DateTime object with Luxon library. How can I do it?
I know we can use methods like .fromISO(), .fromHTTP(), .fromSQL(), .fromJSDate(), and .fromFormat() and none of them accepts the format I have, for example: "31/12/2022"
I was trying with fromFormat( date, 'D' ) but it's invalid because "D" format is equal to "MM/DD/YYYY".
You can use fromFormat :
Create a DateTime from an input string and format string. Defaults to en-US if no locale has been specified, regardless of the system's locale. For a table of tokens and their interpretations, see here.
passing "d/M/yyyy" as second argument. Example:
const DateTime = luxon.DateTime;
console.log(DateTime.fromFormat("31/12/2022", "d/M/yyyy").toISO());
<script src="https://cdn.jsdelivr.net/npm/luxon#3.1.1/build/global/luxon.min.js"></script>
Please have a look at Parsing section of the docs and Table of tokens to see the list of available tokens. As docs states:
Note that many tokens supported by the formatter are not supported by the parser.
in your case "D" is a format token you can use standalone tokens to parse your input string.

moment.js formatting date wrong

I'm trying to get upcoming date using moment.js. The date is obtained, but it's formatted wrongly. According to docs, format('l') formats the date in dd/mm/yyyy format and format('L') formats date in mm/dd/yyyy. but I'm getting the same output for both. Here is my code.
let next = moment().add(30, 'days').format('l'); // Output 10/16/2019
let next = moment().add(30, 'days').format('L'); // Output 10/16/2019
let next = moment().add(30, 'days').format('DD/MM/YYYY'); // Works fine
I tried i with moment.js v2.24.0 what's wrong in here? am I missing something or doing it wrong way?
According to docs, format('l') formats the date in dd/mm/yyyy format and format('L') formats date in mm/dd/yyyy.
No, that isn't what the documentation says:
Localized formats
Because preferred formatting differs based on locale, there are a few tokens that can be used to format a moment based on its locale.
There are upper and lower case variations on the same formats. The lowercase version is intended to be the shortened version of its uppercase counterpart.
Month numeral, day of month, year: L 09/04/1986
l 9/4/1986
There's nothing there saying L will use one field order and l another.
It's using your current Moment locale to format the date. See the i18n section for how to set locales, globally or per instance.
According to docs
moment().format('L'); // 09/16/2019
moment().format('l'); // 9/16/2019
https://momentjs.com/

What are the differences between the way we construct moment timezone?

moment("2014-06-01T12:00:00Z").tz("America/Los_Angeles") vs moment.tz("2014-06-01T12:00:00Z", "America/Los_Angeles")
According to https://momentjs.com/timezone/ the example show both but it didnt explain which way is preferred.
I agree that moment-timezone examples are a bit misleading, please note that moment.tz is for parsing input using given zone:
The moment.tz constructor takes all the same arguments as the moment constructor, but uses the last argument as a time zone identifier.
while tz() is to convert a moment object to a given timezone.
For "2014-06-01T12:00:00Z" both moment("2014-06-01T12:00:00Z").tz("America/Los_Angeles") and moment.tz("2014-06-01T12:00:00Z", "America/Los_Angeles") give the same result because the input contains the Z that stands for +00:00 offset.
Note that as stated by Matt Johnson (momentjs team member and date/timezone guru) in this comment:
because the input contains the Z, it will indeed be treated as UTC and converted with just moment.tz(input, zone). It's slightly bad form though, as just dropping the Z will change the behavior
So my suggestions is to use moment.utc to parse UTC inputs and then convert to desired timezone using tz(). See this related question.
Here a couple of examples of using different approaches for parsing different inputs:
// UTC input
console.log( moment("2014-06-01T12:00:00Z").tz("America/Los_Angeles").format() );
console.log( moment.tz("2014-06-01T12:00:00Z", "America/Los_Angeles").format() );
// No Z in the input (no UTC)
console.log( moment("2014-06-01T12:00:00").tz("America/Los_Angeles").format() );
console.log( moment.tz("2014-06-01T12:00:00", "America/Los_Angeles").format() );
// My suggested way
console.log( moment.utc("2014-06-01T12:00:00Z").tz("America/Los_Angeles").format() );
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.23/moment-timezone-with-data-2012-2022.min.js"></script>

Weird ISO formatted Datestring to Javascript Date

I've got a Datestring like this one: 20171010T022902.000Z and I need to create Javascript Date from this string. new Date('20171010T022902.000Z') would return Invalid Date.
I saw that it's possible to use moment.js for this purpose but I am not sure how I would specify the according format for my given example. I found this example from another thread:
var momentDate = moment('1890-09-30T23:59:59+01:16:20', 'YYYY-MM-DDTHH:mm:ss+-HH:mm:ss');
var jsDate = momentDate.toDate();
Question:
How can I create a JavaScript date from a given Datestring in this format: 20171010T022902.000Z (using moment)?
Your input (20171010T022902.000Z) matches known ISO 8601 so you can simply use moment(String) parsing method. In the Supported ISO 8601 strings section of the docs you will find:
20130208T080910.123 # Short date and time up to ms
Then you can use toDate() method
To get a copy of the native Date object that Moment.js wraps
Your code could be like the following
var m = moment('20171010T022902.000Z');
console.log( m.format() );
console.log( m.toDate() );
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>
Note that this code does not shows Deprecation Warning (cited in Bergi's comment) because you input is in ISO 8601 known format. See this guide to know more about this warning.
Moreover "By default, moment parses and displays in local time" as stated here so format() will show the local value for your UTC input (20171010T022902.000Z ends with Z). See moment.utc(), utc() and Local vs UTC vs Offset guide to learn more about moment UTC mode.
I think you can do this without moment.js,.
Basically extract the parts you need using regex's capture groups, and then re-arrange into a correct format for new Date to work with.
var dtstr = '20171010T022902.000Z';
var dt = new Date(
dtstr.replace(/^(\d{4})(\d{2})(\d{2})T(\d{2})(\d{2})(\d{2})(\.\d{3}Z)$/,
"$1-$2-$3T$4:$5:$6$7"));
console.log(dt);
console.log(dt.toString());
If you are using moment.js anyway, this should work ->
var dt = moment("20171010T022902.000Z", "YYYYMMDDTHHmmss.SSSSZ");
console.log(dt.toString());
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.19.1/moment.min.js"></script>

Moment.js : Format date according browser lang

I use this code to display a date in French format :
var dateToDisplay = moment(myDateInMS, "x").format("DD/MM/YYYY - hh:mm:ss"); // Output : "20/03/2016 - 12:35:32"
I would like to improve this display to have a better display according the browser language. How can i do that using moment ?
I do not recommend setting the locale depending on the browser language as it's not a clear signal of the actual locale of the user. E.g. a user may use an English operating system even though s/he's a French speaker.
That being said. Reading the language from the browser and setting Moment.js to the corresponding locale can be done this way:
var localeData = moment.localeData();
switch (navigator.language || navigator.userLanguage) {
case 'fr':
localeData = moment.localeData('fr');
break;
}
localeData.longDateFormat('LL'); // the example 'LL' will output date in "D MMMM YYYY format"
Notice that this is setting the locale of the entire Moment.js instance (which is probably what you want to do). Also notice that as of Moment.js 2.8.0, changing the global locale doesn't affect existing instances.
Also see
Changing locale globally
Long Date Format
Moment will actually search for substrings of the locale pulled from the browser in an attempt to pick the correct locale. Thus, there is no need to preparse or create a case statement.
As an example, moment has es as a locale, but not es-mx. If the browser is set to es-mx the locale function looks for es-mx and when it doesn't find it, falls back to es. Thus:
moment.locale('es-mx');
"es"
Meaning that for your purposes you can just do:
moment.locale(navigator.userLanguage || navigator.language);
Then when formatting your dates, use one of the locale specific formats to make them appropriate for the user:
moment().format('LL')
"1 de abril de 2016"
moment().format('L')
"01/04/2016"
For all of the localized formats and what they should produce, see the localized format section of the format documentation: http://momentjs.com/docs/#/displaying/format/

Categories