Why is iPhone iOS showing invalid date for momentjs - javascript

I have a datepicker which was returning a moment object that was always in UTC timezone. I needed to do some logic on this date, but always wanted it in the users local timezone so I did the following:
//strip submission date of timezone offset
let submission_date = moment(this.state.startDate).format('YYYY-MM-DD hh:mm:ss a');
submission_date = moment(submission_date);
let last_date = this.last_date.diff(submission_date, 'days');
However, when I do this my iPhone complains that submission_date is not a valid date. Desktop is fine so I'm guessing this is a safari issue. When I inspect this.state.startDate just prior to being momentized it's a string like 2018-11-01T17:52:44-00:00
Shouldn't moment accept that as a valid date?

I had figured out that it's the a flag in the format string. I changed it to YYYY-MM-DDTHH:mm:ss and it worked perfectly. Safari must not like am/pm data.

Try wrapping up with String function
//strip submission date of timezone offset
let submission_date = moment(String(this.state.startDate),'YYYY-MM-DD hh:mm:ss a');
let last_date = moment(String(this.last_date),'YYYY-MM-DD hh:mm:ss a').diff(submission_date, 'days');
Safari engine has some unique way of processing/parsing the date object

follow this format. year should be at the beginning. have to use "/" instead of "-".
cannot use "MMM" for month
YYYY/MM/DD hh:mm A

I solved this problem by ensuring all the letters in my ISO8601 formatted date-time (such as T and Z) were upper case. When they were lower case, moment failed to parse the date-time string.

Related

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>

Reading UTC time strings

Hi I'm trying to read some UTC data strings using moments.js.
e.g.
date1 = moment.utc("160114224512Z").format('YYYY-MM-DD HH:mm:ss');
console.log(date1)
However, this always throws an invalid date error
Moment will accept unix timestamps in both seconds and milliseconds as strings, if you specify the x or X token. You actually don't even need to strip the Z - the regular expression related to the x and X tokens is looking for a number, so it will ignore the Z by default.
I think you have milliseconds there, so you would use the small x token, as follows:
moment.utc("160114224512Z", 'x').format('YYYY-MM-DD HH:mm:ss');
"1975-01-28 04:10:24"
That look right?
As an additional note, it might be good to strip the Z for purposes of clarity, even if you don't have to.
I'm going to assume you have quotes you haven't shown, e.g.:
date1 = moment.utc("160114224512Z").format('YYYY-MM-DD HH:mm:ss');
// Note -----------^-------------^
console.log(date1)
The problem is simple: That isn't a valid date/time string, in any format I've ever seen. It's certainly not ISO-8601, for instance.
It looks like a seconds-since-the-Epoch value for Jan 28th, 1975, since it's just a number and it's too big to be milliseconds-since-the-Epoch (unless you really have a date in the year 7043).
If it's seconds-since-the-epoch, ditch the Z and use it as a number:
date1 = moment.utc(160114224512).format('YYYY-MM-DD HH:mm:ss');
The string 160114224512Z is not a valid UTC moment format, nor a valid moment format.
I would advise you to specify your input format, I'd do:
moment.utc(160114224512, 'x').format('YYYY-MM-DD HH:mm:ss')

Converting date from string with offset to different timezone

I'm wondering on the correct way to convert a string date in a non-ISO format to a different offset/timezone.
I am currently given 3 values:
the date in format MM/DD/YYYY (23/11/2016)
the time in 24h format (23:13)
timezone offset (-07:00)
I would like to convert said date to the user's timezone.
I am trying to convert the format to the format accepted by moment timezone's moment.tz() function ('2016-11-23T23:13-07:00') but I am not sure how to do that without splitting the date array and converting it to said date.
Moment's timezone has the tools I need to convert the date afterwards to the local timezone. For example:
moment.tz('2016-11-23T23:13-07:00', moment.tz.guess());
Any thoughts on how to convert 23/11/2016 23:13 with offset -07:00 to the local date preferably using momentJS?
Why not just format as an ISO 8601 string with offset and give that to moment.js?
function customToISOString(date, time, offset){
return date.split(/\D/).reverse().join('-') + 'T' + time + offset;
}
document.write(customToISOString('23/11/2016','23:13','-07:00')); // 2016-11-23T23:13-07:00
Most modern browsers will also parse that, but don't do it as there are still plenty of older browsers around where it will fail.
I like Rob's answer, but I'll also give you it in moment.js.
First, you don't need moment-timezone, and you definitely don't need to guess the time zone id just to convert to that zone. In ISO format, it would just be like this:
var m = moment('2016-11-23T23:13-07:00');
This will read in the offset during parsing, apply it, then convert to the local time zone, returning a moment object in "local mode". This is the default mode, so it just works.
With the requirements you described it would be like this:
// your inputs
var d = "23/11/2016";
var t = "23:13";
var o = "-07:00";
var m = moment(d + ' ' + t + o, 'MM/DD/YYYY HH:mmZ');
Note that I add the space between the date and time just for safety, so there's no risk of mixing the year and the hour components.
Again it will automatically apply the offset and convert to the local time zone, since that's the default behavior. If you want some other behavior, there are ways to do that as well.

Convert UTC time to local time zone in IE in javascript

I have a date time string in format ("2015-10-07 15:20:00 UTC") and i want to convert it to local time zone of client. i am using the following statements for this:
var UTC_Time = new Date ("2015-10-07 15:20:00 UTC");
var localTime = UTC_Time.toString();
in Google Chrome it works fine and return the converted time as 2015-10-07 20:20:00 PST which is fine. But in internet explorer (i am concerned with IE10) it is returning the same UTC date i.e. 2015-10-07 15:20:00. how can i get the converted time in IE. Any help would be greatly appreciated.
When you display a date in javascript, it converts it to the client time. Since you are specifying UTC in your date string, it will assume that it's a UTC date. There are a couple ways you can solve this.
If you just need a string, you can do localTime = UTC_Time.toUTCString().
If you need a js Date object, you can create a new date object by getting the values from the previous object.
new Date(UTC_Time.getUTCFullYear(), UTC_Time.getUTCMonth(),
UTC_Time.getUTCDate(), UTC_Time.getUTCHours(), UTC_Time.getUTCMinutes(),
UTC_Time.getUTCSeconds(), UTC_Time.getUTCMilliseconds());
Or you can simply replace the UTC part of the string.
var dtStr = "2015-10-07 15:20:00 UTC";
dtStr = dtStr.replace(" UTC", "");
var localTime = new Date(dtStr);
Only use this option if you know your string will always be in the same format.

Date (dateString) returning invalid date in Firefox

The page works fine in Chrome, but I have this one minor error in Firefox and a different problem in IE. Assistance with either of these issues is greatly appreciated. Since I've been stumped in the Firefox error the longest, I'll start with that one:
Here's the code: http://truxmapper.appspot.com/sched.html
The date picker selects a date using the format "07-08-2010 23:28". Now, I need to pass this time as a parameter to my servlet, which is expecting the time represented as a long. This is not a problem in Chrome. The Date object accepts a string in the format given above, but when I try to use getTime() on a date instantiated with a string in Firefox, it returns NaN. So what I've done in the on the page I linked to is a little handling asking the user to re-enter the dates if its read as NaN. This obviously isn't even a band-aid solution since even if you re-enter the date its still going to read NaN. I need to know why the Date function wont instantiate using the string you see in the input text field in Firefox.
In IE, for some reason its telling me that sTime is undefined.
That date format is ambiguous. Try it as yyyy-mm-dd instead of mm-dd-yyyy or dd-mm-yyyy.
Try
new Date(Date(dateString)).getTime()
(feels like an ugly workaround...)
Edit: This will produce wrong result.
The date format used in Javascript should be of the form YYYY MM DD HH:mm:ss. You can convert the format into this form with
// dateString = "07-08-2010 23:28";
dateString = dateString.replace(/(\d+) (\d+) (\d+)/, '$3-$1-$2');
But as mentioned in the comment, there is no standard Date format used by Javascript before the ECMAScript 5 standard. It is better to parse the dateString directly:
m = dateString.match(/(\d+)-(\d+)-(\d+) (\d+):(\d+)/)
date = new Date(+m[3], m[1]-1, +m[2], +m[4], +m[5]); // Note: January = 0.

Categories