Momentjs is not converting certain Spanish months to UTC - javascript

I am working on a React Native application which is available on two languages (English & Spanish). Getting date in English is fine but for Spanish, Momentjs is not able to convert it to moment object for certain months(in spanish) like Abril, It throws Invalid date as output, while other month like Septiembre is working fine and it is getting converted to moment object.
const aprilDateES = moment("09 Abril, 2021") // Invalid date
const septeDateEs = moment("09 Septiembre, 2021") // Thu Sep 09 2021 00:00:00 GMT+0530
It is also throwing warning for Abril month -
My goal is to convert all Spanish date/month to moment object so that it can be converted to other format like DD/MM/YYYY and can also be validated using momentJS.
Here's the link to playground - https://replit.com/#DevAk1/MomentJSSpanishDate#src/App.jsx

Change import to -
import moment from 'moment/min/moment-with-locales'
Then use this -
const date = moment('09 Abril, 2021', 'DD MMMM, YYYY', 'es').locale('en')
// Fri Apr 09 2021 00:00:00 GMT+0530
Note - This is specific to format and language. Please change the source/target language and the date format according to the requirement.

Related

How to convert new Date() to UTC date using moment JS

I want to convert the returned value of new Date to UTC format using moment js.
I tried using moment.utc but
moment.utc(moment(new Date())).format();
output -> 2020-01-01T04:00:00Z
but I want output in this format
Thu Jun 04 2020 00:00:15 GMT+0530 (India Standard Time)
just like what new Date returns but it should be in UTC.
and the other problem is that the return type of format is of
TYPE : STRING I want that the format should be the same but its type should be of date object.
Any help would be appreciated.

DateTimeFormatter for Javascript Date.toString output

Trying to support Javascript's new Date().toString() output format with Java's DateTimeFormatter but can't seem to make it work.
Js output is of the following nature:
Wed Apr 04 2018 09:56:16 GMT-0500 (SA Pacific Standard Time)
Wed Apr 04 2018 16:12:41 GMT+0200 (CEST)
My current formatter:
int defaultOffset = ZonedDateTime.now().getOffset().getTotalSeconds();
DateTimeFormatter dtfJs = new DateTimeFormatterBuilder()
.appendPattern("EE MMM dd yyyy HH:mm:ss [OOOO (zzzz)]")
.parseDefaulting(ChronoField.OFFSET_SECONDS,defaultOffset
.toFormatter();
If i .parse() those date strings from js, I get the following error:
[date] could not be parse at index 25
Index 25 for both the dates mentioned is:
GMT-0500 (SA Pacific Standard Time)
GMT+0200 (CEST)
I know the problem is with the : (colon) because if I print the current date with dtfJs, I get:
Wed Apr 04 2018 10:25:10 GMT-05:00 (Colombia Time)
So the part of the GMT-05:00 is exected as GMT-0500 in the string recieved but I can't find a reserved pattern letter which matches this.
The docs say:
Offset O: This formats the localized offset based on the number of
pattern letters. One letter outputs the short form of the localized
offset, which is localized offset text, such as 'GMT', with hour
without leading zero, optional 2-digit minute and second if non-zero,
and colon, for example 'GMT+8'. Four letters outputs the full form,
which is localized offset text, such as 'GMT, with 2-digit hour and
minute field, optional second field if non-zero, and colon, for
example 'GMT+08:00'. Any other count of letters throws
IllegalArgumentException.
Offset Z: This formats the offset based on the number of pattern
letters. One, two or three letters outputs
the hour and minute, without a colon, such as '+0130'. The output will
be '+0000' when the offset is zero. Four letters outputs the full form
of localized offset, equivalent to four letters of Offset-O. The
output will be the corresponding localized offset text if the offset
is zero. Five letters outputs the hour, minute, with optional second
if non-zero, with colon. It outputs 'Z' if the offset is zero. Six or
more letters throws IllegalArgumentException.
Which means that the four letter will output always with colon ":", thus throwing DateTimeParseException
Help greatly appreciated, thanks
Edit
Thanks to #mszymborski I managed to pass on to validate the parenthesis part "(CEST)", what would be useful here ?
I tried with EE MMM dd yyyy HH:mm:ss 'GMT'Z (zz) but this only works with the second date in the list, not the first
GMT-0500 (SA Pacific Standard Time) ERROR
GMT+0200 (CEST) PASS
Dates in JavaScript is a big mess. toString() is not only browser/implementation dependent, but also locale sensitive. I'm in Brazil, so my browser is set to Portuguese, and new Date().toString() gives this result:
Wed Apr 04 2018 14:14:04 GMT-0300 (Hora oficial do Brasil)
Month and day-of-week names are in English, but the timezone name is in Portuguese. What a mess!
Anyway, to parse those strings, you have to make some decisions.
Do you need to get the timezone or just the offset?
The offset GMT+0200 is used by more than one country (hence, more than one timezone uses it). Although the offset is enough to have a non-ambiguous point in time, it's not enough to know the timezone.
Even short names such as CEST are not enough, because this is also used by more than 1 country.
If you want to parse just the offset, the best way is to simply remove everything after the ( and parse it to an OffsetDateTime:
DateTimeFormatter parser = DateTimeFormatter.ofPattern("EEE MMM dd yyyy HH:mm:ss 'GMT'Z", Locale.US);
// 2018-04-04T16:12:41+02:00
OffsetDateTime.parse("Wed Apr 04 2018 16:12:41 GMT+0200", parser);
Also note that I used a java.util.Locale. That's because the month and day of week are in English, and if you don't set a locale, it'll use the JVM default - and you can't guarantee that it'll always be English. It's better to set a locale if you know in what language the inputs are.
If you need to get the timezones, though, it's more complicated.
Names like "CEST" are ambiguous, and you need to make arbitrary choices for them. With java.time is possible to build a set of preferred timezones to be used in case of ambiguities:
Set<ZoneId> zones = new HashSet<>();
zones.add(ZoneId.of("Europe/Berlin"));
zones.add(ZoneId.of("America/Bogota"));
DateTimeFormatter fmt = new DateTimeFormatterBuilder()
.appendPattern("EEE MMM dd yyyy HH:mm:ss 'GMT'Z (")
// optional long timezone name (such as "Colombia Time" or "Pacific Standard Time")
.optionalStart().appendZoneText(TextStyle.FULL, zones).optionalEnd()
// optional short timezone name (such as CET or CEST)
.optionalStart().appendZoneText(TextStyle.SHORT, zones).optionalEnd()
// close parenthesis
.appendLiteral(')')
// use English locale, for month, timezones and day-of-week names
.toFormatter(Locale.US);
With this, you can parse your inputs to a ZonedDateTime:
// 2018-04-04T16:12:41+02:00[Europe/Berlin]
ZonedDateTime.parse("Wed Apr 04 2018 16:12:41 GMT+0200 (CEST)", fmt);
// 2018-04-04T10:25:10-05:00[America/Bogota]
ZonedDateTime.parse("Wed Apr 04 2018 10:25:10 GMT-0500 (Colombia Time)", fmt);
But unfortunately, this doesn't parse the "SA Pacific Standard Time" case. That's because the timezones names are built-in in the JVM and "SA Pacific Standard Time" is not one of the predefined strings.
A good alternative is to use the mapping suggested by M.Prokhorov in the comments: https://github.com/nfergu/Java-Time-Zone-List/blob/master/TimeZones/src/TimeZoneList.java
Then you manually replace the name in the string and parse it with VV pattern (instead of z), because the mapping uses IANA's names (such as Europe/Berlin, which are parsed by VV).
But the best alternative is to use toISOString(), which produces strings in ISO8601 format, such as 2018-04-04T17:39:17.623Z. The big advantage is that java.time classes can parse it directly (you don't need to create a custom formatter):
OffsetDateTime.parse("2018-04-04T17:39:17.623Z");

How to parse a date with momentjs?

I'm trying to parse a date in momentjs, in particular this is my goal:
Ven Nov 13 2015 09:00:00
Now I'm using FullCalendar and when I get the .start date it's returned this:
Fri Nov 13 2015 00:00:00
how you can see in my bottom code, I'm format the calendarDateStartTemp to utc for remove the GMT. In the next step, I transform the object in italian timezone, but this seems not working. Anyway, I've in workingPlan[selDayName].start the hour to edit, in particular this is the value: 09:00:00, see the code:
var calendarDateStartTemp = $calendar.fullCalendar('getView').start;
var calendarDateStart = moment(calendarDateStartTemp).utc().format("ddd MMM DD YYYY HH:mm:ss");
var calendarDateEnd = moment.lang('it');
calendarDateEnd = moment(moment(calendarDateStart).format("YYYY-MM-DD") + ' '
+ workingPlan[selDayName].start).format('ddd, D MMM YYYY HH:mm:ss');
now the problem's that I get this result:
Fri, 13 Nov 2015 09:00:00
instead of this:
Ven Nov 13 2015 09:00:00
how you can see the date returned is in english language, but I don't know why moment.lang now working. I say that it's deprecated so I've also tried with moment.locale but I've the same problem. How I can fix this?
NB: the language is italian
var data = moment().locale('it').format('llll');
alert(data);
By default, Moment.js comes with English locale strings. If you need other locales, you can load them into Moment.js.
I'm assuming you have both moment.js and monement+locales.js included, the scripts are found here. http://momentjs.com/

Unable to Handle js date - Moment

moment('Sat Sep 12 2015 15:00:00 GMT+0100 (GMT Daylight Time)').format()
// Error: core-test.js:52920 Uncaught Error: input not handled by moment(…)
I am miffed as to why moment cannot handle this date, even when stripping it down I still can't get it to work it out.
var date = 'Sat Sep 12 2015 15:00:00 GMT+0100 (GMT Daylight Time)'.split(' GMT')[0];
moment(date).format()
//The same error
You can provide moment a format to use to parse your string: http://momentjs.com/docs/#/parsing/string-format/
But your date format isn't possible with the options available so you have to strip out some of the information. Namely the reference the timezone name for the offset "GMT" and the "GMT Daylight Time". Since the timezone is encoded in the "+0100" part I'm going to assume that it's fine to remove those references.
First create a function to "clean" the string date:
function cleanDateString(formattedDate) {
return formattedDate.replace(/(.*?)(\w{3})(((\+|-)\d{4}).*)/g,"$1$4");
}
If you invoke the function on the string you provided cleanDateString('Sat Sep 12 2015 15:00:00 GMT+0100 (GMT Daylight Time)') the output will be
"Sat Sep 12 2015 15:00:00 +0100"
Now this is something that can be parsed by moment using the right format.
If you look at http://momentjs.com/docs/#/displaying/format/ then the format that you would need for this string is
'ddd MMM DD YYYY mm:hh:ss ZZ'
If you combine the two things from above, then you can get your date like this
function parseCustomDate(formattedDate) {
return moment(cleanDateString(formattedDate),'ddd MMM DD YYYY mm:hh:ss ZZ');
}
And that will work with your given string
parseCustomDate('Sat Sep 12 2015 15:00:00 GMT+0100 (GMT Daylight Time)')
Note on the Regex
If you want details on how exactly the regex works, you can look at the "Explanation" and the "Match Information" sections at this link: https://regex101.com/r/tH6hM9/1. I used that to tweak the groupings and the rules
Your Date Format should look like this:
var date2 = '2015-09-12T15:00:00+00:00'; // UTC

Javascript date object automatically add one day when creating from date string

In my javascript i want to convert date from date string.
i have string like
date = "Thu Sep 03 2015 19:30:00 GMT+0000"
Now i convert string using Date object.
var d = new Date(date);
But this gives me,
Fri Sep 04 2015 01:00:00 GMT+0530 (IST)
It automatically add one day into day. What is wrong?
It automatically add one day into day. What is wrong?
Nothing. The time you input is 19:30 GMT and the timezone on the device you're using is set to GMT+0530. Add 5 hours 30 minutes to 7:30pm and you get 01:00am the following day.
You should not use the Date constructor to parse strings, as it is inconsistent across browsers and until recently, entirely implementation dependent. Manually parse strings, or use a Date library.

Categories

Resources