Compare time without knowing timezone of machine - javascript

This code compares 2 time - present time and a deadline time.
// Get current date/time
var now = new Date();
// Set up deadline date/time
var deadline = new Date(); //deadline is 1830hrs;
deadline.setHours(18);
deadline.setMinutes(30);
// Check if the current time is after the deadline
if( now > deadline ) {
console.log('after deadline');
}
else {
console.log('before deadline');
}
It works on my local machine where now and deadline are in the same timezone. What if the code is run on a server where the now timezone can be different from the deadline timezone to be compared? How to handle the situation when now can be any timezone and deadline is in, say, the Asia/HongKong timezone?
EDIT: Is there some way to specify the timezone when creating deadline? I think this is a possible solution.

As you creating both time in JS which the client side there will be no such case. because both time will read time from the same client.
But if in any case any of the time comes from server (in form of string of course )which located in another time zone and client is in another time zone then there is a possibility to this case happen.
Now you approach will be to convert both date to a specific time zone (any).
Then make the comparison.
You can use This Library to convert time zone in JS.
And take help from This Thread.

deadline and now are always in the same timezone because you new Date() there.

You are missing the information in what timezone the client is. This is partially solvable by just comparing it with the times form all the timezones.
In my example I will use moment.js because it is a nice library with a lot of features just for timezones.
You can use this code to find matching timezones, but sometimes they have different rules about DST and such so they will divert over the year.
However if that's fine you can now use moment.js to specify the timezone of deadline and calculate how much time you have left.

Related

Changing Timezone across the application

I’m currently working on Timezone related options across my application. I want to change the user’s default timezone which the browser picks during
let date = new Date()
the function returns the date and time with respect to browser zone.
Is there any setting which I can edit such that across the application, different zone is used?
Using moment-timezone, I can work on this dynamically. But I am using few packages that are using Javascript Dates.
Therefore, is there a setting or a parameter through which we can change the zone of the browser and whenever the new Date() function is called, the time fetched is in that timezone?
A Date object does not actually store a time zone. It simply stores the number of milliseconds since since Jan 1, 1970 00:00 UTC, otherwise known as the "UNIX Epoch".
The methods of Date give the illusion of having a stored time zone because, when you call a method like getHours(), the system reports the time in minutes in the time zone of the user.
But what's happening under the hood is something like this:
// Stores the number of milliseconds since 1970-01-01T00:00:00 UTC.
// Does NOT store the current time zone.
const date = new Date();
// This returns the number stored above
const msecsSinceEpoch = date.getTime();
// This returns the current UTC offset of the user's time zone.
// For example, if the user's OS settings use the time zone in
// California in December 2022, then this method will return 480.
// If you subtract that number of minutes from the current UTC time,
// then it will equal the local time in California in December 2022.
const offsetMinutes = date.getTimezoneOffset();
// When you call methods like .hours(), the browser uses the two
// values above to calculate the result. Like this:
const MSECS_PER_MINUTE = 60*1000;
const MSECS_PER_HOUR = MSECS_PER_MINUTE * 60;
const offsetMsecs = offsetMinutes * MSECS_PER_MINUTE;
const totalHours = Math.trunc ((msecsSinceEpoch - offsetMsecs) / MSECS_PER_HOUR);
const hours = totalHours % 24;
// The code above will return the same result as this:
const hours2 = date.getHours();
The code above should make it clear why you cannot change the time zone of a Date object: because the Date object doesn't store a time zone at all! There's no time zone to change. And, for security reasons, code running in the browser can't change the user's OS settings to change the time zone.
So your first idea (to change the time zone of Date) won't work. But many web apps allow viewing date and time information in different time zones.
Soon (likely sometime in 2023) JavaScript will be adding a new built-in object called Temporal that will make it easier to work with time zones. In the meantime, it's straightforward to use different time zones using libraries like moment-timezone, or you can use one of the Temporal polyfills.
But that won't help you in the specific case you're asking about: how can you change the time zone of a library that only accepts a Date parameter. Some libraries provide a way to change the time zone of data displayed. Others do not, and those that don't provide a way to change the time zone come in two types:
Libraries that don't care about time zone at all. For example, a library that schedules a reminder text message in 60 minutes doesn't care about the time zone. It only cares about the exact time: the value stored in a Date and returned by .getTime(). If your library is like this, then you should be fine passing a Date and don't need to worry about time zones.
Libraries that show data to users in a specific time zone. For example, a date picker or a calendar. These libraries typically use the time zone in the user's OS settings. However, many libraries provide a way to override that time zone. You'll need to check your libraries' documentation or search questions about how to set the time zone for the output of those libraries. Or you can switch libraries!

Dealing with js localized date in C#

My app (back-end in C# & front-end in Angular Materials) has a search screen allowing user to specify the date period using datepickers. The problem is that some of the users are not in UK while all the data they view has been created with GMT date. So if someone in Germany selects date 01/01/2017 in datepicker, my back-end reads it as 31/12/2016 23:00:00 resulting in incorrect search results.
Can someone advise me how to deal with this? I'd like to still use the Angular Material datepicker but be sure that I'm passing the date selected by the user. I know I can transform the date before posting it like this:
moment(myDate).format('MM/DD/YYYY'))
but I have a lot of cases like this and would prefer some generic solution.
For transmission and storage, I advise using UTC for everything. Only at the point of display should the time be converted to whatever locale the user has selected. Despite this being an old problem, running into time conversion issues is still quite common. Most places I've worked at will store everything as UTC timestamps or Unix epoch time with respect to UTC, that way there is no question what the meaning is anywhere in the system. If/when it needs to be rendered to something local, we do it on the client side.
For example, to get the local time converted to UTC as a string:
var noTimeZone = new Date().toUTCString();
-or-
var noTimeZone = new Date().toISOString();
Or, if you want a numeric value so you don't have to deal with funky format parsing between client/server, you can get the Unix epoch:
var unixEpochMS = new Date().getTime();
Mind you, Date.getTime() will return milliseconds rather than seconds. Also note that the Unix epoch is defined in terms of UTC. That is, any numeric value that is a timestamp is expected to be UTC. If you want a different timezone, you need to parse the value and then set the timezone to what you want.
Solution 1:
I think the solution is to get your user's timezone. You can use Javascript to get timezone from user's computer and send it to server with the request.
var d = new Date();
var tz = d.getTimezoneOffset()/-60;
tz will be 2 if user's timezone is GM+2
Soution 2:
You send and receive Unix timestamp. But then you need to convert the timestamp to readable date/time based on user's timezone.

Get current datetime in JS for a specific timezone

I am working on a platform that has users from all over the world, but certain settings are bound to a predefined timezone datetime.
What does this mean? If a user connects from a different timezone the app should still show him the current time in the predefined timezone regardles from where he logs in. I need to calculate this on the client side with javascript with only the timezone string.
What I would like to do is something like this:
new TimezoneDate('timezone');
and the result should be the current datetime for that timezone.
I know there are JS libs that handle this but I am asking if there is a simple JS solution without using external libs?
Depends on your definition of simple; but not really. Javascript does not have support for timezones out of the box. I would highly recommend Moment Timezone http://momentjs.com/timezone/ since it is very user friendly. I am also in the middle of a project with the same requirements and this library has made my work a lot easier.
Edit:
With the library, doing what you want is as easy as:
var timezonedDate = moment.tz('YOUR TZ STRING').toDate();
You can try:
var offset = new Date().getTimezoneOffset();
Or to get the difference in hours:
var x = new Date();
var currentTimeZoneOffsetInHours = x.getTimezoneOffset() / 60;
Mozilla Reference
The time-zone offset is the difference, in minutes, between UTC and
local time. Note that this means that the offset is positive if the
local timezone is behind UTC and negative if it is ahead. For example,
if your time zone is UTC+10 (Australian Eastern Standard Time), -600
will be returned. Daylight saving time prevents this value from being
a constant even for a given locale.

How come my javascript (node.js) is giving me the incorrect timestamp?

I typed "date" in console...and I get Tue Sep 20 01:01:49 PDT 2011 ...which is correct.
But then I do this in node.js, and I get the wrong time.
var ts = String(Math.round(new Date().getTime() / 1000));
Output is: 1316505706, which is an hour behind.
#KARASZI is absolutely correct about the root cause: Unix timestamps are always UTC unless you manipulate them. I would suggest that if you want a Unix timestamp you should leave it in UTC, and only convert to local time if you need to display a formatted time to the user.
The first benefit of doing this is that all your servers can "speak" the same time. For instance, if you've deployed servers to Amazon EC2 US East and Amazon EC2 US West and they share a common database, you can use UTC timestamps in your database and on your servers without worrying about timezone conversions every time. This is a great reason to use UTC timestamps, but it might not apply to you.
The second benefit of this is that you can measure things in terms of elapsed time without having to worry about daylight savings time (or timezones either, in case you're measuring time on a platform which is moving!). This doesn't come up very much, but if you had a situation where something took negative time because the local time "fell back" an hour while you were measuring, you'd be very confused!
The third reason I can think of is very minor, but some performance geeks would really appreciate it: you can get the raw UTC timestamp without allocating a new Date object each time, by using the Date class's "now" function.
var ts = Date.now() / 1000;
The reason is that the getTime function returns the time in the UTC timezone:
The value returned by the getTime method is the number of milliseconds since 1 January 1970 00:00:00 UTC. You can use this method to help assign a date and time to another Date object.
If you want to fetch the UNIX timestamp in you current timezone, you can use the getTimezoneOffset method:
var date = new Date();
var ts = String(Math.round(date.getTime() / 1000) + date.getTimezoneOffset() * 60);
Note you can avoid this confusion by using a node.js package like timezonecomplete or timezone-js which have an interface that is much less error-prone for date and time manipulation.
date in console will return the server time, whereas using JavaScript on a webpage will return the client's local time.

How to calculate eastern time using Javascript Date object?

I'm working on a personal project involving Javascript, and as part of that project, I want to grab the current date (including time) and display it accordingly. No big deal right? Well, the deal is that I want to return the time & date in Eastern Daylight TIme, no matter where in the world the IP is.
If this is not possible, what alternative methods do you suggest? Does php have this functionality? I could write a simple php script that takes a date and converts it, but I want to keep this in JS if at all possible.
I'm trying to think through the best way to do this, but I'd appreciate any help that you could offer.
Thanks!
I found this on the internet, and there are a lot more of these scripts:
function calcTime(offset) {
// create Date object for current location
d = new Date();
// convert to msec
// add local time zone offset
// get UTC time in msec
utc = d.getTime() + (d.getTimezoneOffset() * 60000);
return new Date(utc + (3600000*offset));
}
So, you get the current time, add the offset of the current location to get UTC time and then you return a new date where you add the offset of a certain time zone again.
JavaScript native Date objects only know two timezones, UTC and the user's locale timezone (and even then, the amount of information you can extract about the locale timezone is limited). You could work in UTC and subtract 4 hours to get EDT, but do you really always want EDT and not EST?
If you want to do timezone conversions between arbitrary regions in PHP you'll need to drag in a large library with its own timezone information, such as TimezoneJS.
It may be better to keep the JavaScript stuff all in UTC, and let the PHP side worry about formatting it for a particular locale/timezone, using eg the timezone stuff from Date/Time.

Categories