I'm inserting a date in a database in two different format.
this is inserting as Datetime
var mydate;
mydate = new Date();
document.getElementById('clockinhour').value = mydate.toISOString().slice(0, 19).replace('T', ' ');
Output A
2017-06-21 20:14:31
this is inserting as varchar :
document.getElementById('clocked_in_time').value = Date();
Output B
Wed Jun 21 2017 16:14:31 GMT-0400 (Eastern Standard Time)
Output B is the correct time but I need to display output A. What causes the time to change when converted toISOString? How can I fix this?
In your this is inserting as Datetime block your slice are stripping of the timezone part (the Z at the end of toISOString output):
document.getElementById('clockinhour').value = mydate.toISOString().slice(0, 19).replace('T', ' ');
As pointed out by #RobG in the comments section, toISOString should always return the date in UTC (Z or +00:00).
RTFM:
"The time zone [offset] is always UTC, denoted by the suffix Z",
The time "changes" because it is converted to UTC when you calls toISOString.
If you want to get ISO date in your timezone, you should take a look in these two questions: How to ISO 8601 format a Date with Timezone Offset in JavaScript? and How to format a JavaScript date
ISO time is time zone free. You'll notice with b you have time zone GMT-04:00 if you add those four hours to the 16 hours in the Date, you get 20
Related
I'm getting a date as a string, in the following format (for example):
"11/10/2015 10:00:00"
This is UTC time.
When I create Date from this string, it consider it as local time:
let time = "11/10/2015 10:00:00";
let date = new Date(time);
console.log(date);
it prints:
"Tue Nov 10 2015 10:00:00 GMT+0200"
(instead of considering it as UTC: "Tue Nov 10 2015 10:00:00")
I also tried moment.js for that.
is there a good way to make Date() consider the string a UTC, without adding "Z"/"UTC"/"+000" in the end of the string?
You can use the built-in Date.UTC() function to do this. Here's a little function that will take the format you gave in your original post and converts it to a UTC date string
let time = "11/10/2015 10:00:00";
function getUTCDate(dateString) {
// dateString format will be "MM/DD/YYYY HH:mm:ss"
var [date, time] = dateString.split(" ");
var [month, day, year] = date.split("/");
var [hours, minutes, seconds] = time.split(":");
// month is 0 indexed in Date operations, subtract 1 when converting string to Date object
return new Date(Date.UTC(year, month - 1, day, hours, minutes, seconds)).toUTCString();
}
console.log(getUTCDate(time));
Your date is parsed by the date constructor, in MM/DD/YYYY format, applying the local timezone offset (so the output represents local midnight at the start of the day in question). If your date really is MM/DD/YYYY, all you need to do is subtract the timezone offset and you'll have the UTC date...
var myDate = new Date("11/10/2015 10:00:00");
myDate = new Date( myDate.getTime() - (myDate.getTimezoneOffset()*60*1000));
console.log(myDate.toLocaleString([],{timeZone:'UTC'}))
Here's everything I know about managing timezone when serializing and deserializing dates. All the timezone handling is static! JS dates have no intrinsic timezone.
You can use Date.UTC for this but you will have to parse your string and put every part of it as args by yourself as it can't parse such string. Also you could use moment.js to parse it: Convert date to another timezone in JavaScript
Also, seems like new Date("11/10/2015 10:00:00 GMT") parses date as a GMT and only after that converts it to PC local time
Easy answer is to append a "Z" at the end without changing the variable:
let time = "11/10/2015 10:00:00";
let date = new Date(time + "Z");
console.log(date);
const dt = new Date('2017-12-12');
console.log(format(dt, 'YYYY-MM-DD'));
The above code logs 2017-12-11 in the US, but 2017-12-12 in India.
I followed this github thread here and tried out things but am not getting the desired results.
My expectation is to print the same date irrespective of time zone
Why I need this :
Consider a scenario involving birthdates. If i am giving some input date, it has to be displayed as same date in all regions irrespective of their timezones.
You will need to subtract the time zone offset of your local time zone from the Date instance, before you pass it to format from date-fns. For example:
const dt = new Date('2017-12-12');
const dtDateOnly = new Date(dt.valueOf() + dt.getTimezoneOffset() * 60 * 1000);
console.log(format(dtDateOnly, 'YYYY-MM-DD')); // Always "2017-12-12"
Problem
You want to handle only the date part of the Date instance, because the time part does not make sense for birthdates. However, the Date object does not offer any "date-only" mode. You can access both its date and time parts in the local time zone or UTC. The problem is, that format from date-fns prints the output always in the local time zone.
When you executed the constructor only with the date part:
const dt = new Date('2017-12-12');
The JavaScript engine actually assumed a string in the incomplete ISO 8601 format and perfomed this:
const dt = new Date('2017-12-12T00:00:00.000Z');
It may still look "harmless" to you, but the date instance exposes the value not only in UTC, but also in the local time zone. If you construct the Date instance on the East Coast of the US, you will see the following output:
> const dt = new Date('2017-12-12');
> dt.toISOString()
'2017-12-12T00:00:00.000Z'
> dt.toString()
'Tue Dec 11 2017 19:00:00 GMT-0500 (EST)'
> d.toLocaleString()
'12/11/2017 7:00:00 PM'
Solution
If you know, that format from date-fns reads date and time parts from the date instance in the local time zone, you will need to make your date "looking like" the midnight in your local time zone and not in UTC, which you passed to the Date constructor. Then you will see the year, month and date numbers preserved. It means, that you need to subtract the time zone offset of your local time zone for the specified day. Date.prototype.getTimezoneOffset returns the offset, but with an inverted sign and in minutes.
const dt = new Date('2017-12-12');
// Tue Dec 11 2017 19:00:00 GMT-0500 (EST)
const dtDateOnly = new Date(dt.valueOf() + dt.getTimezoneOffset() * 60 * 1000);
// Tue Dec 12 2017 00:00:00 GMT-0500 (EST)
console.log(format(dtDateOnly, 'YYYY-MM-DD'));
// Prints always "2017-12-12", regardless the time zone it executed in
However, such Date instance can be used only to format the date-only value. You cannot use it for computing date differences, for example, which would need the original and correct UTC value.
Alternative
If you need always the same date-only format and not the format specific to the current locale, you do not need date-fns. You can format the string by the concatenation of padded numbers:
const dt = new Date('2017-12-12');
const year = dt.getUTCFullYear()
const month = dt.getUTCMonth() + 1 // Date provides month index; not month number
const day = dt.getUTCDate()
// Print always "2017-12-12", regardless the time zone it executed in
console.log(year + '-' + padToTwo(month) + '-', padToTwo(day));
// Or use a template literal
console.log(`${year}-${padToTwo(month)}-${padToTwo(day)}`);
function padToTwo (number) {
return number > 9 ? number : '0' + number
}
Only adding the #ferdinand-prantl answer. If you are using the date-fns, you can parse the string date ('2017-12-12') using the parseISO(here) fn from date-fns, which will complete the missing ISO 8601 format with your local time zone. When you use the format fn, you are going to keep the date.
const strDate = '2017-12-12';
const isoDate = parseISO(strDate);
const formattedDate = format(isoDate, 'YYYY-MM-DD');
console.log({strDate, isoDate, formattedDate})
//{
// strDate: '2017-12-12',
// isoDate: 2017-12-12T02:00:00.000Z,
// formattedDate: '2017-12-12'
//}
I am trying to convert milliseconds into UTC date object as below -
var tempDate = new Date(1465171200000);
// --> tempDate = Mon Jun 06 2016 05:30:00 **GMT+0530 (India Standard Time)** {}
var _utcDate = new Date(tempDate.getUTCFullYear(), tempDate.getUTCMonth(), tempDate.getUTCDate(), tempDate.getUTCHours(), tempDate.getUTCMinutes(), tempDate.getUTCSeconds());
//--> _utcDate = Mon Jun 06 2016 00:00:00 **GMT+0530 (India Standard Time)** {}
Time is resetting to UTC time but Time Zone is still coming as GMT+0530 (India Standard Time).
Is there any sure shot approach to convert milliseconds into UTC date object with UTC Time Zone?
Quoting from this answer (that I suggest you to read completely):
There is no time zone or string format stored in the Date object itself. When various functions of the Date object are used, the computer's local time zone is applied to the internal representation.
As time zone is not stored in the Date object there is no way to set it.
I see two options:
the first is to make use of a library (as suggested in the answer above). Quite popular now is Moment.js
the second (pure JavaScript - if it's a viable solution in your context):
Do the "time math" in your local timezone.
When you're ready to switch to UTC use toUTCString() method.
Of course you'll end up with a string as this let you store the time zone as long as the date time value.
As you won't be able to manipulate the date time as a Date object from now on this must be the last step.
var tempDate = new Date(1465171200000);
// Mon Jun 06 2016 05:30:00 GMT+0530
// Do your date time math here
// using the Date object's methods
var utcDateAsString = tempDate.toUTCString();
// Mon Jun 06 2016 00:00:00 GMT
You say:
Time is resetting to UTC time but Time Zone is still coming as GMT+0530 (India Standard Time). Is there any sure shot approach to convert milliseconds into UTC date object with UTC Time Zone?
But I think you misunderstand what is occurring. When you pass a number to the Date constructor as in:
new Date(1465171200000)
is it assumed to be milliseconds since the ECMAScript epoch (1970-01-01T00:00:00Z), so a Date object is created with that value as its internal time value. So Date objects are inherently UTC.
When you write that to a string, internally a human readable date string is generated based on the host timezone setting, which is why you see a date for GMT+0530 (that is your host system timezone setting). The Date object itself does not have a timezone, it's always UTC.
When you then use UTC values to create a "local" Date using:
new Date(tempDate.getUTCFullYear(), tempDate.getUTCMonth(), ...)
then the host timezone is used to generate a UTC time value equivalent to a "local" date for the associated values. You've effectively subtracted your timezone offset from the original time value so it now represents a different moment in time. You can get exactly the same result doing:
var d = new Date(1465171200000);
d.setMinutes(d.getMintues() + d.getTimezoneOffset());
which just shows a bit more clearly what's going on. Note that ECMAScript timezone offsets are in minutes and have the opposite sense to UTC, that is, they are negative (-) for east and positive (+) for west. So an offset of UTC+05:30 it is represented as -330 and you need to add it to "shift" a Date rather than subtract it.
var tempDate = new Date(1465171200000);
var _utcDate = new Date(tempDate.getUTCFullYear(), tempDate.getUTCMonth(), tempDate.getUTCDate(), tempDate.getUTCHours(), tempDate.getUTCMinutes(), tempDate.getUTCSeconds());
console.log('Direct conversion to Date\ntempDate: ' + tempDate.toString());
console.log('Adjusted using UTC methods\n_utcDate: ' + _utcDate.toString());
tempDate.setMinutes(tempDate.getMinutes() + tempDate.getTimezoneOffset());
console.log('Adjusted using timezoneOffset\ntempDate: ' + tempDate.toString());
However, I can't understand why you want to do the above. 1465171200000 represents a specific moment in time (2016-06-06T00:00:00Z), adjusting it for every client timezone means it represents a different moment in time for each client with a different timezone offset.
If you create a Date from a Number, the local timezone is the one considered. But if you want to see what a timestamp would mean with the hours corrected for UTC, you could use a helper as such:
Number.prototype.toUTCDate = function () {
var value = new Date(this);
value.setHours(value.getHours() - (value.getTimezoneOffset() / 60));
return value;
};
The usage would be:
var date = (1465171200000).toUTCDate();
I'm creating dates like this:
var StartDate = new Date(data.feed.entry[i].gd$when[j].startTime);
When a date string is received specifying date and time in the form:
"2014-04-12T20:00:00.000-05:00"
Date() interprets this perfectly fine returning:
Sat Apr 12 2014 19:00:00 GMT-0500 (CDT)
However, when the date string is received with no time information in the form:
"2014-04-07"
then Date() is interpreting it as:
Sat Apr 05 2014 19:00:00 GMT-0500 (CDT)
Looks like Date() is taking the -07 as the time and I have no clue where is it getting the date as 05. Any idea what might be the problem?
Could it be, somehow, Date() is interpreting a different time zone because in the first string the time zone is determined at the very end but in the "all day" event there is no indication of the time zone.
Has anybody found this issue? If yes, how did you solve it?
UPDATE: After researching a little bit more this parsing issue I noticed something very weird:
The following statement:
new Date("2014-4-07")
would return Mon Apr 07 2014 00:00:00 GMT-0500 (CDT) which is correct, but the following one:
new Date("2014-04-07")
returns Sun Apr 06 2014 19:00:00 GMT-0500 (CDT) which is the wrong one. So, for whatever reason, seems like the padding zeros affect the way the date is parsed!
You're using the Date() function wrong.
It only accepts parameters in the following formats.
//No parameters
var today = new Date();
//Date and time, no time-zone
var birthday = new Date("December 17, 1995 03:24:00");
//Date and time, no time-zone
var birthday = new Date("1995-12-17T03:24:00");
//Only date as integer values
var birthday = new Date(1995,11,17);
//Date and time as integer values, no time-zone
var birthday = new Date(1995,11,17,3,24,0);
Source: MDN.
The Date() function does not accept timezone as a parameter. The reason why you think the time-zone parameter works is because its showing the same time-zone that you entered, but that's because you're in the same time-zone.
The reason why you get Sat Apr 05 2014 19:00:00 GMT-0500 (CDT) as your output for Date("2014-04-07" ) is simply because you used it in a different way.
new Date(parameters) will give the output according to the parameters passed in it.
Date(parameters) will give the output as the current date and time no matter what parameter you pass in it.
Prior to ES5, parsing of date strings was entirely implementation dependent. ES5 specifies a version of ISO 8601 that is supported by may browsers, but not all. The specified format only supports the Z timezone (UTC) and assumes UTC if the timezone is missing. Support where the timezone is missing is inconsistent, some implementations will treat the string as UTC and some as local.
To be certain, you should parse the string yourself, e.g.
/* Parse an ISO string with or without an offset
** e.g. '2014-04-02T20:00:00-0600'
** '2014-04-02T20:00:00Z'
**
** Allows decimal seconds if supplied
** e.g. '2014-04-02T20:00:00.123-0600'
**
** If no offset is supplied (or it's Z), treat as UTC (per ECMA-262)
**
** If date only, e.g. '2014-04-02', treat as UTC date (per ECMA-262)
*/
function parseISOString(s) {
var t = s.split(/\D+/g);
var hasOffset = /\d{2}[-+]\d{4}$/.test(s);
// Whether decimal seconds are present changes the offset field and ms value
var hasDecimalSeconds = /T\d{2}:\d{2}:\d{2}\.\d+/i.test(s);
var offset = hasDecimalSeconds? t[7] : t[6];
var ms = hasDecimalSeconds? t[6] : 0;
var offMin, offSign, min;
// If there's an offset, apply it to minutes to get a UTC time value
if (hasOffset) {
offMin = 60 * offset / 100 + offset % 100;
offSign = /-\d{4}$/.test(s)? -1 : 1;
}
min = hasOffset? +t[4] - offMin * offSign : (t[4] || 0);
// Return a date object based on UTC values
return new Date(Date.UTC(t[0], --t[1], t[2], t[3]||0, min, t[5]||0, ms));
}
An ISO 8601 date string should be treated as UTC (per ECMA-262), so if you are UTC-0500, then:
new Date('2014-04-07'); // 2014-04-06T19:00:00-0500
The behaviour described in the OP shows the host is not compliant with ECMA-262. Further encouragement to parse the string yourself. If you want the date to be treated as local, then:
// Expect string in ISO 8601 format
// Offset is ignored, Date is created as local time
function parseLocalISODate(s) {
s = s.split(/\D+/g);
return new Date(s[0], --s[1], s[2],0,0,0,0);
}
In your function you can do something like:
var ds = data.feed.entry[i].gd$when[j].startTime;
var startDate = ds.length == 10? parseLocalISODate(ds) : parseISOString(ds);
Also note that variables starting with a capital letter are, by convention, reserved for constructors, hence startDate, not StartDate.
(I would add a comment but i don't have 50 rep yet)
See what
new Date().getTimezoneOffset()
returns, I would expect a big negative value, that would be the only reasonable explanation to your problem.
I have had some trouble with date conversions in the past, in particular with daytime saving timezones, and as work around i always set the time explicitly to midday (12:00am). Since I think you were using knockout, you could just make a computed observable that appends a "T20:00:00.000-05:00" or the appropiate time zone to all "day only" dates
I've created a date in JS like so:
var myDate = new Date('2013-01-01 00:00:00');
I assume JS reads this in as UTC time. But when I do something like myDate.getTime() the timestamp returned was something like 4AM GMT time.
Why is this? And how do I get the date as midnight in UTC time?
At least in Chrome, this works:
var myDate = new Date('2013-01-01 00:00:00 UTC');
It also works if you put GMT instead of UTC. But I don't know if this is cross-browser enough.
I live in India. Hence my timezone is the Indian Standard Time (IST) which is listed in the tz database as Asia/Kolkata. India is 5 hours 30 minutes ahead of GMT. Hence when I execute new Date("2013-01-01 00:00:00") the actual time at GMT is "2012-12-31 18:30:00".
I believe you live in America because you're in the EST timezone (GMT-04:00)? Am I right?
If you want to parse the time at GMT instead of your local timezone then do this:
new Date("2013-01-01T00:00:00+00:00");
Notice the capital T between the date and the time, and the +00:00 at the end. This is the format used to parse a given time in a specific timezone.
Given the date string "2013-01-01 00:00:00" you can convert it to the required format using the following function:
function formatDateString(string, timezone) {
return string.replace(" ", "T") + timezone;
}
Then you can create the date as follows:
new Date(formatDateString("2013-01-01 00:00:00", "+00:00"));
Another way to convert local time to GMT is as follows:
var timezone = new Date("1970-01-01 00:00:00"); // this is the start of unix time
Now that you have your own local timezone as a date object you can do:
new Date(new Date("2013-01-01 00:00:00") - timezone);
All the above methods produce the same date at GMT.
JS reads this with time zone that your computer uses.
You can try use myDate.toUTCString() for get date in UTC time.
If you want get timestamp use myDate.getTime()
Mine works simply by doing this
var datetime= new Date()
However the month is 1 low so you have to add one