To create Date object in UTC, we would write
new Date(Date.UTC(2012,02,30));
Without Date.UTC, it takes the locale and creates the Date object. If I have to create a Date object for CET running the program in some part of the world, how would I do it?
You don't create a JavaScript Date object "in" any specific timezone. JavaScript Date objects always work from a milliseconds-since-the-Epoch UTC value. They have methods that apply the local timezone offset and rules (getHours as opposed to getUTCHours), but only the local timezone. You can't set the timezone the Date object uses for its "local" methods.
What you're doing with Date.UTC (correctly, other than the leading 0 on 02) is just initializing the object with the appropriate milliseconds-since-the-Epoch value for that date/time (March 30th at midnight) in UTC, whereas new Date(2012, 2, 30) would have interpreted it as March 30th at midnight local time. There is no difference in the Date object other than the datetime it was initialized with.
If you need a timezone other than local, all you can do is use the UTC version of Date's functions and apply your own offset and rules for the timezone you want to use, which is non-trivial. (The offset is trivial; the rules tend not to be.)
If you go looking, you can find Node modules that handle timezones for you. A quick search for "node timezone" just now gave me timezone as the first hit. It also gave me links to this SO question, this SO question, and this list of timezone modules for Node.
function getCETorCESTDate() {
var localDate = new Date();
var utcOffset = localDate.getTimezoneOffset();
var cetOffset = utcOffset + 60;
var cestOffset = utcOffset + 120;
var cetOffsetInMilliseconds = cetOffset * 60 * 1000;
var cestOffsetInMilliseconds = cestOffset * 60 * 1000;
var cestDateStart = new Date();
var cestDateFinish = new Date();
var localDateTime = localDate.getTime();
var cestDateStartTime;
var cestDateFinishTime;
var result;
cestDateStart.setTime(Date.parse('29 March ' + localDate.getFullYear() + ' 02:00:00 GMT+0100'));
cestDateFinish.setTime(Date.parse('25 October ' + localDate.getFullYear() + ' 03:00:00 GMT+0200'));
cestDateStartTime = cestDateStart.getTime();
cestDateFinishTime = cestDateFinish.getTime();
if(localDateTime >= cestDateStartTime && localDateTime <= cestDateFinishTime) {
result = new Date(localDateTime + cestOffsetInMilliseconds);
} else {
result = new Date(localDateTime + cetOffsetInMilliseconds);
}
return result;
}
Related
I got the following string: "2022/05/01 03:10:00" and I need to create a Date object forcing it to use Chile's UTC offset.
The problem is that because of Daylight saving time (DST) the offset changes twice a year.
How can get that Date object, for example, using the "America/Santiago" TZ db name?
Something like:
new Date("2022/05/01 03:10:00" + getUtcOffset("America/Santiago")).
function getUtcOffset(tzDbName) {
..
}
Returns -3 or -4, depending the time in the year.
EDIT:
I ended using a nice trick for determining if DST was on or off.
reference
const dst = hasDST(new Date(strDate));
function hasDST(date = new Date()) {
const january = new Date(date.getFullYear(), 0, 1).getTimezoneOffset();
const july = new Date(date.getFullYear(), 6, 1).getTimezoneOffset();
return Math.max(january, july) !== date.getTimezoneOffset();
}
Then I could create the date with the correct timezone depending on that variable.
if (dst) {
let d = new Date(strDate + " GMT-0300");
return d;
} else {
let d = new Date(strDate + " GMT-0400");
return d;
}
Thanks everyone!
EDIT2:
I finally found a very nice library that does exactly what I was looking for:
https://date-fns.org/v2.28.0/docs/Time-Zones#date-fns-tz
const { zonedTimeToUtc, utcToZonedTime, format } = require('date-fns-tz')
const utcDate = zonedTimeToUtc('2022-05-05 18:05', 'America/Santiago')
This has been discussed before here.
Haven't tested it, but it appears that the simplest solution is:
// Example for Indian time
let indianTime = new Date().toLocaleTimeString("en-US",
{timeZone:'Asia/Kolkata',timestyle:'full',hourCycle:'h24'})
console.log(indianTime)
You can check the link for more complex answers and libraries
Generals notes
To get the time zone name use:
console.log(Intl.DateTimeFormat().resolvedOptions().timeZone)
To get the difference from UTC (in minutes) use:
var offset = new Date().getTimezoneOffset();
console.log(offset);
// if offset equals -60 then the time zone offset is UTC+01
I am trying to convert a UTC date to local time on my node server and finally return the localized time in the format of hh:mm:ss (not using Moment JS). I'm passing in the timezone offset from the client to Node, which is GMT-6.
My original time is: 2017-05-05T00:25:11.378Z
// ISOTimeString = `2017-05-05T00:25:11.378Z`
// offsetInMinutes = 360; (GMT - 6)
function isoDateToLocalDate(ISOTimeString, offsetInMinutes) {
var newTime = new Date(ISOTimeString);
return new Date(newTime.getTime() - (offsetInMinutes * 60000));
}
The localized time is 2017-05-04T18:25:11.378Z, which is correct (2017-05-05T00:25:11 - 6 hours = 2017-05-04T18:25:11).
// localIsoDate: 2017-05-04T18:25:11.378Z Date object
function formatTime(localIsoDate) {
var hh = localIsoDate.getHours();
var mm = localIsoDate.getMinutes();
var ss = localIsoDate.getSeconds();
return [hh, mm, ss].join(':');
}
// formatted: 12:25:11
The problem is, while still on the server, when I try to format into hh:mm:ss, it subtracts another 6 hours, giving me 12:25:11. I don't want to convert again, I simply want to format and display 18:25:11 from the already localized time.
How can I do this?
Note: Keep in mind I do not have the option to convert timezones after it's passed back to the client in my case.
The isoDateToLocalDate seems to be OK, however in the formatTime you need to use UTC methods, otherwise you are getting the host local values, not the adjusted UTC values.
Also, in ISO 8601 terms (and general convention outside computer programming), an offset of 360 represents a timezone of +0600, not -0600. See note below.
// ISOTimeString = 2017-05-05T00:25:11.378Z
// ECMAScript offsetInMinutes = 360; (GMT-0600)
function isoDateToLocalDate(ISOTimeString, offsetInMinutes) {
var newTime = new Date(ISOTimeString);
return new Date(newTime.getTime() - (offsetInMinutes * 60000));
}
// localIsoDate: 2017-05-04T18:25:11.378Z Date object
function formatTime(localIsoDate) {
function z(n){return (n<10?'0':'')+n}
var hh = localIsoDate.getUTCHours();
var mm = localIsoDate.getUTCMinutes();
var ss = localIsoDate.getUTCSeconds();
return z(hh)+':'+z(mm)+':'+z(ss);
}
var timeString = '2017-05-05T00:25:11.378Z';
var offset = 360;
console.log(formatTime(isoDateToLocalDate(timeString, offset)))
ECMAScript timezone signs are the reverse of the usual convention. If the client timezone offset is +0600 then their host will show -360.
Date calculation issue in JavaScript on Browser. There are 3 parameters -
From Date, No. of days & To Date
From Date selected using calendar component in JavaScript = 30/10/2016
No. of days entered = 2
Based on no. of days entered "To Date" should be calculated, so as per above input of From date & No. of days calculated "To Date" value should be 01/11/2016 but due to some wrong calculation it's showing 31/10/2016.
Time Zone - Istanbul, Turkey
Please refer below image for code snipped -
As it is clear from code snipped that prototype JavaScript library being used.
dateUtil.prototype.addDays=function(date,noofDays)
{
var _dateData=date.split("/");
var _date=eval(_dateData[0]);
var _month=eval(_dateData[1]);
var _year=eval(_dateData[2]);
var newFormatedDate = new Date(""+_month+"/"+_date+"/"+_year);
var newAddedDate=newFormatedDate.getTime() + noofDays*24*60*60*1000;
var theDate = new Date(newAddedDate);
var dd = theDate.getDate();
var mm = theDate.getMonth()+1; // 0 based
if(mm<10)
mm="0"+mm;
var yy = theDate.getYear();
if (yy < 1000)
yy +=1900; // Y2K fix
var addedDate=""+dd+"/"+mm+"/"+yy;
return addedDate;
}
It seems noofDays*24*60*60*1000 logic is problem where DST is not being considered.
There are 2 timezone showing with the same code but with different date format.
Please could you advise any guidance or read-up on this.
Edit :
JavaScript code added.
Probably not worth posting the code since it has some fundamental errors that should not have survived the new millennium.
var _date = eval(_dateDate[0]);
Don't use eval. There are a small number of cases where it is appropriate, but in general, just don't use it. Ever. The above is the same as:
var _date = _dateDate[0];
Then there is:
var newFormatedDate = new Date('' + _month + '/' + _date + '/' + _year)
You started on the right track by avoiding parsing strings with the Date constructor by splitting the date string into it's parts. But then you undid that good work by creating a new string and parsing it with Date. Just use parts directly:
var newFormatedDate = new Date(_year, _month-1, _date)
which removes all the vagaries of Date parsing and is less to type as well. Also, Date objects don't have a format, so a name like date is fine.
To add n days, just add them to the date:
var date = new Date(_year, _month-1, _date)
date.setDate(date.getDate() + 2);
So your function can be:
function dateUtil(){}
/* Add days to a date
** #param {string} date - date string in dd/mm/yyyy format
** #param {number} noofDays - number of days to add
** #returns {Date}
*/
dateUtil.prototype.addDays = function(date, noofDays) {
var dateData = date.split('/');
var date = new Date(dateData[2], dateData[1] - 1, dateData[0]);
date.setDate(date.getDate() + +noofDays);
return date;
}
var d = new dateUtil();
console.log(d.addDays('23/09/2016',3).toLocaleString());
I've use +noofDays to ensure it's a number. Also, the SO console seems to always write dates as ISO 8601 strings in Z time zone so I've used toLocaleString to keep it in the host time zone.
How can I convert a UTC time into proper date - time format using Javascript?
This is what I want to do
var d = new Date("2014-01-01");
var new_d = d.toUTC(); // 1388534400000
var old_d = function(new_d){
// return "2014-01-01" // how can i get this?
}
Now How, can i get orignal date - 2014-01-01 from 1388534400000?
****Also, Please note that when i do this --- new Date(1388534400000); it gives date 1 day less.
That is, instead of giving Jan 01 2014, it gives Dec 31 2013. But, I want Jan 01 2014.****
Is there any method to do the opposite of toUTC() method?
// _________ For those whose toUTC() doesnt work
"toUTC" method works in console of my chrome
See screen shot below
When you pass a string containing hyphens to the Date constructor, it will treat that as UTC. And if you don't pass a time, it will consider it to be midnight. If you are in a time zone that is behind UTC (such as in most of the Americas), you will see the wrong local time conversion.
Here's a screenshot of my chrome dev console, so you can see what I mean
If I pass slashes instead:
Consider using moment.js - which will accept a format parameter that will help you avoid this issue.
Try using the following:
new Date(new_d);
The problem lies with the way you instantiate the Date.
Javascript interpretes the hyphens as an utc date, and slashes as local dates.
Giving the results that mark Explains.
var utcDate = new Date('2014-01-01') // returns a UTC date
var localDate = new Date('2014/01/01'); // Returns local date
But to translate a date back to your starting point string, you can do the following.
function toDateString(utcMillis){
var date = new Date(utcMillis);
d = date.getDate();
m = date.getMonth() +1;
y = date.getFullYear();
return y + '-' + addLeadingZero(m, 2) + '-' + addLeadingZero(d,2);
}
function addLeadingZero(n, length){
n = n+'';
if(n.length<length)
return addLeadingZero('0'+n, length--);
else
return n;
}
If you find yourself with a UTC date, you can still do this:
function toUTCDateString(utcMillis){
var date = new Date(utcMillis);
d = date.getUTCDate();
m = date.getUTCMonth() +1;
y = date.getUTCFullYear();
return y + '-' + addLeadingZero(m, 2) + '-' + addLeadingZero(d,2);
}
To play around with it, and see it for yourself, see this Fiddle:
I am trying to get the current UTC date to store in my database. My local time is 9:11 p.m. This equates to 1:11 a.m. UTC. When I look in my database, I notice that 1:11 p.m. is getting written to. I'm confused. In order to get the UTC time in JavaScript, I'm using the following code:
var currentDate = new Date();
var utcDate = Date.UTC(currentDate.getFullYear(), currentDate.getMonth(), currentDate.getDate(), currentDate.getHours(), currentDate.getMinutes(), currentDate.getSeconds(), currentDate.getMilliseconds());
var result = new Date(utcDate);
What am I doing wrong?
A lttle searching turned out you can do this:
var now = new Date(),
utcDate = new Date(
now.getUTCFullYear(),
now.getUTCMonth(),
now.getUTCDate(),
now.getUTCHours(),
now.getUTCMinutes(),
now.getUTCSeconds()
);
Even shorter:
var utcDate = new Date(new Date().toUTCString().substr(0, 25));
How do you convert a JavaScript date to UTC?
It is a commonly used way, instead of creating a ISO8601 string, to get date and time of UTC out. Because if you use a string, then you'll not be able to use every single native methods of Date(), and some people might use regex for that, which is slower than native ways.
But if you are storing it in some kind of database like localstorage, a ISO8601 string is recommended because it can also save timezone offsets, but in your case every date is turned into UTC, so timezone really does not matter.
If you want the UTC time of a local date object, use the UTC methods to get it. All javascript date objects are local dates.
var date = new Date(); // date object in local timezone
If you want the UTC time, you can try the implementation dependent toUTCString method:
var UTCstring = date.toUTCString();
but I wouldn't trust that. If you want an ISO8601 string (which most databases want) in UTC time then:
var isoDate = date.getUTCFullYear() + '-' +
addZ((date.getUTCMonth()) + 1) + '-' +
addZ(date.getUTCDate()) + 'T' +
addZ(date.getUTCHours()) + ':' +
addZ(date.getUTCMinutes()) + ':' +
addZ(date.getUTCSeconds()) + 'Z';
where the addZ function is:
function addZ(n) {
return (n<10? '0' : '') + n;
}
Modify to suit.
Edit
To adjust a local date object to display the same time as UTC, just add the timezone offset:
function adjustToUTC(d) {
d.setMinutes(d.getMinutes() + d.getTimezoneOffset());
return d;
}
alert(adjustToUTC(new Date())); // shows UTC time but will display local offset
Take care with the above. If you are say UTC+5hrs, then it will return a date object 5 hours earlier but still show "UTC+5"
A function to convert a UTC ISO8601 string to a local date object:
function fromUTCISOString(s) {
var b = s.split(/[-T:\.Z]/i);
var n= new Date(Date.UTC(b[0],b[1]-1,b[2],b[3],b[4],b[5]));
return n;
}
alert(fromUTCISOString('2012-05-21T14:32:12Z')); // local time displayed
var now = new Date();
var utc = new Date(now.getTime() + now.getTimezoneOffset() * 60000);