Javascript Date Function ISO8601 - javascript

I thought I had a standard ISO date and the Javascript Date() function should convert it with no parsing, but I get the following:
my date :
2015-12-08T13:42
Javascript date function result:
Tue Nov 12 2075 13:42:00 GMT+0100
Is my date in an incorrect format or have I misunderstood the Data function?
I should have added that I'm using Adobe Illustrator CS6. I've tried an examples from below and I get the same result:
My code:
var start = '2015-12-08T13:42';
var test0 = new Date(start);
var test1 = new Date(start+'Z').toString();
$.writeln(test0);
$.writeln(test1);
The result:
Tue Nov 12 2075 13:42:00 GMT+0100
Tue Nov 12 2075 13:42:00 GMT+0100

To specify UTC time as string, you need to add the Z part to it.
Quoted from Wikipedia:
If no UTC relation information is given with a time representation, the time is assumed to be in local time.
If the time is in UTC, add a Z directly after the time without a space. Z is the zone designator for the zero UTC offset.
I see that difference when running the following snippet in Firefox and in timezone GMT+01:00. But Edge and Chrome show the first output also as if the Z was there (which seems contrary to the above quotes), and so there is no difference visible:
var s = '2015-12-08T13:42';
console.log(new Date(s).toString());
console.log(new Date(s+'Z').toString());
Make sure the way you turn the Date value into string is correct. The toString() call (used in the snippet) will do this conversion into the current locale's date/time.
But if you use a custom function for that, you need to be aware of some pitfalls. For instance, if you use the getMonth or getUTCMonth methods to retrieve the month number of the given date, be aware that it is zero-based, and the month December is thus numbered 11. If your string conversion interprets this 11 as to mean November, you'll be one month off.

i think you u set the date to setUTCDate function if you pass the current date to setUTCDate function it get wrong date
<!DOCTYPE html>
<html>
<body>
<p id="demo"></p>
<script>
function myFunction() {
var d = new Date();
d.setUTCDate(2015-12-08);
document.getElementById("demo").innerHTML = d;
}
</script>
</body>
</html>
if you want get current date use Date() function
<!DOCTYPE html>
<html>
<body>
<p id="demo"></p>
<script>
document.getElementById("demo").innerHTML = Date();
</script>
</body>
</html>

I thought I had a standard ISO date and the Javascript Date() function should convert it with no parsing,
To convert a string to a Date, it must be parsed, you can't avoid that.
but I get the following:
my date :
2015-12-08T13:42
Javascript date function result:
Tue Nov 12 2075 13:42:00 GMT+0100
Is my date in an incorrect format or have I misunderstood the Data
function?
Apart from the year, that is the expected result. From ES5, ISO 8601 format date strings are parsed by the Date constructor (and Date.parse, they are equivalent for parsing).
A plain date string (e.g. 2015-12-08) should be parsed as UTC. A date and time should be parsed as either local if no timezone is provided, or using the provided timezone.
The string "2015-12-08T13:42" does not have a timezone, so it will be parsed using the host timezone settings to produce a date that is equivalent to a local date and time of 8 December, 2015 at 1:42 pm. So it will represent a different moment in time in each time zone with a different offset.
Parsing of strings with the Date constructor is strongly discouraged as it is largely implementation dependent, either write a simple function or use a library. You don't say whether you want the string parsed as local or UTC, a simple function to parse it as UTC is:
// 2015-12-08T13:42
function parseISOAsUTC(s) {
var b = s.split(/\D/);
return new Date(Date.UTC(b[0], --b[1], b[2], b[3], b[4], b[5]||0));
}
var d = parseISOAsUTC('2015-12-08T13:42');
console.log('Local: ' + d.toLocaleString() +
'\nUTC: ' + d.toISOString());
You should add some validation to deal with out of bounds values.

Related

convert a string to date object javascript returns an incorrect date

I am trying to convert string to a date object in javascript, however what i day that is minus 1 from day in string. I don't know what is wrong. Here is the method
function formatDate(date_str)
{
console.log(date_str); //input : 2020-03-11
let new_date = new Date(date_str);
console.log(new_date); //output : Tue Mar 10 2020 20:00:00 GMT-0400 (Eastern Daylight Time)
return new_date;
}
The most likely explanation is that parsing the input string "2020-03-11" with no other information equates it to a date of March 11, 2020 at midnight UTC. When you are in a different time zone, then it calculates your time zone offset and gives you a time four hours earlier which would be the day before in local time.
Why such behavior:
The date string(2020-03-11) did not specify any time zone, when you attempt to create a Date object with this string, JavaScript would assume the time zone to be UTC so the date is internally dealt with like as: 2020-03-11T00:00:00Z.
console.log(new_date) would internally call .toString() method on the new_date object and doing that would trigger a date conversion to your local time zone. From the question I believe you(the time on your machine actually) are in GMT-4, this is why 4 hrs is being subtracted from the output of the logs. More details about the date conversion due to time zone here
Possible Fix:
Firstly, we should understand that this is not a bug or an error, it is just how the JavaScript Date object works.
For the scenario described in your question, I'm guessing what you want is to avoid this time zone conversion on the date string. What you can do is add timezone information to the date string before using it to instantiate a date object, with this, javascript wouldn't assume that the date string you are passing into the Date() constructor is in UTC, and when you call Date.toString() or any other similar methods, there won't be any surprises. An implementation for this can be something like this:
// Sorry for the super long function name :)
function add_local_time_zone_to_date_string (date_string) {
// Getting your local time zone
let local_time_zone = (new Date().getTimezoneOffset() * -1) / 60;
// local_time_zone is a number, convert it to a string
local_time_zone = (local_time_zone.toString())
// Padding with 0s if needed to ensure it is of length 2
local_time_zone = local_time_zone.padStart(2, '0');
return `${date_string}T00:00:00+${local_time_zone}`
}
function formatDate(date_str) {
console.log(date_str); //input : 2020-03-11
const date_with_time_zone = add_local_time_zone_to_date_string(date_str);
let new_date = new Date(date_with_time_zone);
console.log(new_date); //output : There should be no surprises here
return new_date;
}

JavaScript Date formatting and conversion issue

I'm located in PST timezone and I want to be able to take the string "2014-01-01" and convert it into Unix time without "2014-01-01" getting converted to PST.
Here's what I'm doing:
Date.parse(new Date("2014-01-01"))
I'm getting the value 1388534400000 which is equivalent to Tue Dec 31 2013 16:00:00 GMT-0800 (Pacific Standard Time)
I want to take the date as "2014-01-01" and not convert it into PST before converting it into Unix time.
A few things:
The Date constructor returns a Date object, not a string. You shouldn't wrap it in a call to Date.parse.
If you want a unix timestamp, just call getTime().
var ts = new Date("2014-01-01").getTime();
Alternatively, you can parse the date string without creating a Date object at all.
var ts = Date.parse("2014-01-01");
The behavior of date parsing in JavaScript is implementation dependent. Most browsers will already interpret a yyyy-mm-dd string to be in UTC, due to the dashes (-). If you replace with with slashes (/), you'll see the string get interpreted as local time instead.
I think you're confused about the output. You said the timestamp was equivalent to PST, but that's just one representation. It's also equivalent to the UTC value you passed in. It's not getting converted in the input, it's being converted when you are converting the timestamp back to local time.
You can use a library like moment.js, which gives you full control of the input and output. This is usually the best option, but has the overhead of including a library in your application.
Another way to convert the specified date string to Unix time is as follows:
var str = "2014-01-01";
var parts = str.split('-');
parts[1] -= 1; // js numeric mos are 0-11
var ms = Date.UTC( parts[0], parts[1], parts[2] ); // parts: YYYY, MM, DD
var unix_time = ms/1000; // Unix time uses seconds
console.log("Unix time: " + unix_time);
Date.UTC() returns the number of milliseconds occurring since January 1, 1970 midnight up to the instant of the specified date, irrespective of any timezone. The script transforms the result into Unix time, i.e. seconds, by dividing the number of milliseconds by 1000.
After splitting the string into an array, the code adjusts the element containing the month, lest JavaScript mistake its value for March; JavaScript comprehends numeric months as ranging from 0-11, not 1-12. Next, the script passes the elements sequentially in accordance with the year, month, day parameters that Date.UTC requires. Although UTC() expects numbers for parameters, it accepts the numerical strings.
Note: if you first create a new date object and expect to use a UTC method -- that results in an error because it is a static method of JavaScript's Date Object.
You may check the validity of the UTC() return value, using the aforementioned variables ms and str, as follows:
console.log( new Date( str ).toUTCString( ms ));
The output: Wed, 01 Jan 2014 00:00:00 GMT
See live demo here)
Passing a date string to the Date constructor instead of the numerical parameters it expects affords an unexpected benefit; the date string is treated as if it's timezone is UTC, i.e. zero by the local date object. Once created, the local date object executes its toUTCString() method to attain the above-indicated result. The toString() method would also yield the same output, but it appends local timezone information.

How to convert UTC time to normal time format using Moment js

I am trying to convert UTC time formate to local time format:
Here is the example:
I got the UTC format time from the server side, which looks like: 2014-09-17T11:09:58+1100. My requirement is to convert it to 17 Sep 2014.
However, I tried all the following method, but still get 03 Sep 2014. why this happened?
what I tried:
function dateFormatter(UTC) {
var dateFormat = 'd MMM YYYY';
console.log(moment(UTC).zone('+1100').format(dateFormat));
return moment(UTC).format(dateFormat).toLocaleString();
}
Those two method still get the same result: 03 Sep 2014
A few things:
UTC refers to Coordinated Universal Time, which is a system of timekeeping - not a format.
A value that is "in UTC" would have an offset of zero. Since you said the value has an offset of +1100, it doesn't make any sense to call it "UTC".
You should not call the zone function. That is for converting an input value to a particular time zone offset. Since your input value already contains an offset, calling it makes little sense.
If you're just trying to preserve the offset that you were given, then use moment.parseZone instead.
The format string characters are case sensitive. Lower-case d is for the day of the week as a number 0 through 6. You should use an upper-case D to specify the day of the month.
toLocaleString is not required. Note that you were calling that function from a string, not a date or a moment.
Putting it all together:
function dateFormatter(s) {
return moment.parseZone(s).format('D MMM YYYY');
}

Any way to parse a time string using Moment.js but ignore timezone info?

Given the volume of Timezone questions, I would have thought to be able to find the answer to this issue, but haven't had any success.
Is there a way using moment.js to parse an ISO-8601 string but have it parsed in my local timzeone? Essentially I want to ignore the timezone information that is supplied in the ISO string.
For example, if I am in EDT timezone:
var x = moment( "2012-12-31T00:00:00+0000" );
will give me:
"2012-12-30T19:00:00-5000"
I'm looking to ignore the timezone info and just have it give me a moment equivalent of "2012-12-31T00:00:00-5000" local time (EDT).
I don't think you really want to ignore the offset. That would ultimately just be replacing the offset you provided with one from your local time zone - and that would result in a completely different moment in time.
Perhaps you are just looking for a way to have a moment retain the time zone it was given? If so, then use the moment.parseZone function. For example:
var m = moment.parseZone("2012-12-31T00:00:00+0000");
var s = m.format(); // "2012-12-31T00:00:00+00:00"
You could also achieve this with moment.utc. The difference is that moment.parseZone will retain whatever offset you give it, while moment.utc will adjust to UTC if you give it a non-zero offset.
I solved this by supplying a format as the second argument, and using Moment's method of escaping characters, and wrapped square brackets around the timezone.
moment("2016-01-01T05:00:00-05:00", "YYYY-MM-DDTHH:mm:ss[Z]").startOf("hour").format()
This will still create moment objects using your local time zone, but it won't do any sort of auto-timezone calculation. So the above example will give you 5am regardless of timezone supplied.
I know I'm late to the party, I had the same question and my searches didn't bring me any closer. I broke down and read the documentation and there is an option in moment for a String + Format:
String + Format docs
moment(String, String);
moment(String, String, String);
moment(String, String, Boolean);
moment(String, String, String, Boolean);
and more words, then this:
Unless you specify a time zone offset, parsing a string will create a date in the current time zone.
moment("2010-10-20 4:30", "YYYY-MM-DD HH:mm"); // parsed as 4:30 local time
moment("2010-10-20 4:30 +0000", "YYYY-MM-DD HH:mm Z"); // parsed as 4:30 UTC
The part that gave me pause was the example that was used to parse local time omitted the +0000, which lead me to think the input string needed to have that removed, but it doesn't.
example:
var time = "2012-12-31T00:00:00+0000";
var x = moment(time); // Sun Dec 30 2012 19:00:00 GMT-0500
var y = moment(time,'YYYY-MM-DD'); //Mon Dec 31 2012 00:00:00 GMT-0500
You can ignore the browser's timezone completely by creating a new moment using moment.utc() instead of moment().
For example, if you are trying to work purely with a UTC date/time of the browser's current time but want to discard its timezone data, you can recreate the browser's current time into a UTC format using the following:
let nowWithTimezone = moment();
let nowInUtc = moment.utc(nowWithTimezone.format('MM/DD/YYYY HH:mm'), 'MM/DD/YYYY HH:mm');
Further documentation on moment.utc(): https://momentjs.com/docs/#/parsing/utc/
If you know for sure your input string is in the ISO-8601 format, you could just strip off the last 5 digits and use that in the Moment constructor.
var input = "2012-12-31T00:00:00+0000"
input = input.substring(0, input.length-5)
moment(input).toString()
> "Mon Dec 31 2012 00:00:00 GMT-0600"
There are valid reasons to do what the OP is asking for. The easiest way to do this with Moment is using its parseZone(date) method. No futzing around with string manipulation or multiple calls. It effectively parses the date string as though it were in the browser's local time zone.
This is difficult task to do with MomentJS, it will basically depend as well on your current timezone.
Documentation as well is vague for this specific task, the way I solved the issue on my side was by adding hours to the date before converting it to JSON format.
var dt = moment("Sun Sep 13 2015 00:00:00 GMT-0400", "ddd MMM DD YYYY HH:mm:ss GMT-0400", false);
var date = dt.add(2, 'hour').toJSON();
console.log(date); //2015-09-13T00:00:00.000Z
Momentjs default logic will format the given time with local timezone. To format original date, I wrote a function:
https://github.com/moment/moment/issues/2788#issuecomment-321950638
Use moment.parseZone to convert without taking into account the timezone.
const moment = require('moment')
const dateStr = '2020-07-21T10:00:00-09'
const date = moment.parseZone(dateStr)
console.log(date.format('MM-DD-YY HH:mm A')) // 07-21-20 10:00 AM
Try here link to docs
The best way is to use:
dt = moment("Wed Sep 16 2015 18:31:00 GMT-0400", "ddd MMM DD YYYY HH:mm:ss GMT-0400",true);
And to display convert again to desired timezone:
dt.utcOffset("-04:00").toString()
output > Wed Sep 16 2015 18:31:00 GMT-0400

How to assume local time zone when parsing ISO 8601 date string?

I have a ISO date string as below
var startTimeISOString = "2013-03-10T02:00:00Z";
when I convert it to date object in javascript using below code, it returns
var startTimeDate = new Date(startTimeISOString);
output is
Date {Sun Mar 10 2013 07:30:00 GMT+0530 (India Standard Time)}
It sure converts the ISOString to date but it converts to local time since new Date() is client dependent. How to just convert iso date time string to date and time but not to local date-time..?
Thanks
According to MDN:
Differences in assumed time zone
Given a date string of "March 7, 2014", parse() assumes a local time
zone, but given an ISO format such as "2014-03-07" it will assume a
time zone of UTC. Therefore Date objects produced using those strings
will represent different moments in time unless the system is set with
a local time zone of UTC. This means that two date strings that appear
equivalent may result in two different values depending on the format
of the string that is being converted (this behavior is changed in
ECMAScript ed 6 so that both will be treated as local).
I have done like this and am now getting the exact time which is inside the ISO date string instead of the local time
var startTimeISOString = "2013-03-10T02:00:00Z";
var startTime = new Date(startTimeISOString );
startTime = new Date( startTime.getTime() + ( startTime.getTimezoneOffset() * 60000 ) );
This will give the same date time inside iso date string , the output here is
o/p
Date {Sun Mar 10 2013 02:00:00 GMT+0530 (India Standard Time)}
To sum up the conversation from tracevipin's post:
All Date objects are based on a time value that is milliseconds since 1970-01-01T00:00:00Z so they are UTC at their core. This is different to UNIX, which uses a value that is represents seconds since the same epoch.
The Date.prototype.toString method returns an implementation dependent string that represents the time based on the system settings and timezone offset of the client (aka local time).
If a UTC ISO8601 time string is required, the Date.prototype.toISOString method can be used. It's quite easy to write a "shim" for this methods if required.
Lastly, do not trust Date.parse to parse a string. Support for an ISO8601 format UTC string is specified in ES5, however it's not consistently implemented across browsers in use. It is much better to parse the string manually (it's not hard, there are examples on SO of how to do it) if wide browser support is required (e.g. typical web application).
Simple ISO8601 UTC time stamp parser:
function dateObjectFromUTC(s) {
s = s.split(/\D/);
return new Date(Date.UTC(+s[0], --s[1], +s[2], +s[3], +s[4], +s[5], 0));
}
and here's a shim for toISOString:
if (typeof Date.prototype.toISOString != 'function') {
Date.prototype.toISOString = (function() {
function z(n){return (n<10? '0' : '') + n;}
function p(n){
n = n < 10? z(n) : n;
return n < 100? z(n) : n;
}
return function() {
return this.getUTCFullYear() + '-' +
z(this.getUTCMonth() + 1) + '-' +
z(this.getUTCDate()) + 'T' +
z(this.getUTCHours()) + ':' +
z(this.getUTCMinutes()) + ':' +
z(this.getUTCSeconds()) + '.' +
p(this.getUTCMilliseconds()) + 'Z';
}
}());
}
This happens because date is printed using toString method which by default returns the date and time in local timezone. The method toUTCString will give you the string you need.
Date actually keeps the date as unix time in milliseconds and provides methods to manipulate it.
In vanilla javascript there isn't a way to create a date that assumes the local time of the ISO formatted string you give it. Here's what happens when you pass an ISO 8601 formatted string to javascript. I'm going to use a non UTC time as it illustrates the problem better than using an ISO formatted string:
var startTime = new Date("2013-03-10T02:00:00+06:00"). Note this could also be 2013-03-10T02:00:00Z or any other ISO-formatted string.
read the time, apply the offset and calculate milliseconds since 1970-01-01T00:00:00Z
You now have only milliseconds - you have lost all timezone info. In this case 1362859200000
All functions, apart from the ones that give you a UTC representation of that number, will use the timezone of the computer running the code to interpret that number as a time.
To do what the original poster wants, you need to.
parse the ISO string, interpret the offset ('Z' or '+06:00') as the timezone offset
store the timezone offset
calculate and store the ms since epoch, using the offset timezone offset
hold that offset
whenever attempting to make a calculation or print the date, apply the timezone offset.
This isn't trivial, and requires a complete interpretation of the 8601 spec. Way too much code to put here.
This is exactly what moment.js is designed to do. I strongly recommend using it. Using moment.js:
moment("2013-03-10T02:00:00Z").format()
"2013-03-10T02:00:00Z"
this will result in printing the ISO time of the original string, preserving the offset.
you can try moment js library https://momentjs.com
For my case, I had 2022-10-17T01:00:00 on my database. SO I need to format it to the 01:00:00 AM.
So here was my solution.
var date = "2022-10-17T01:00:00"
var timeFormat = moment(date ).format('HH:mm A');
output: 01:00:00 AM
it will return ISOdate
var getDate = () => {
var dt = new Date();
var off = dt.getTimezoneOffset() * 60000
var newdt = new Date(dt - off).toISOString()
return newdt.slice(0, 19)
}
Output

Categories