Change the timezone from windows on the fly using protractor - javascript

I am facing some challenges to find a better way to test timezones, what is happening now is:
I have a report with some links (for detailed data), when the user access this report comes the transaction date as one of the columns (lets say its today 11th)
When the user clicks at one of these links to have more details about the transaction, the user is transferred to the detail page.
The bug is, when the timezone is UTC-04 the user gets the date of 10th instead of 11th, it only works properly with the UTC+2
I have tried to mock the change of timezone using this:
https://www.npmjs.com/package/timezone-mock
But didn't work as I wanted, the date is changed but the bug doesn't happen.
It is possible to reproduce this only when I change manually the timezone from windows.
I also found the possibility of using powershell commands to do this
Setting timezone in Protractor e2e tests
https://www.npmjs.com/package/node-powershell
So far I could not make it work.
The question is, is it possible to automate the change of window's (system) timezone somehow?
Ty!

So, after some time trying and failing.. found this:
https://support.microsoft.com/en-us/help/2556308/tzutil-command-line-tool-is-added-to-windows-vista-and-to-windows-serv
tzutil.exe works for windows 10 and windows server as well, it is really simple to execute, the function needs to be like this:
browser.controlFlow().execute(() => {
var child_process = require('child_process');
console.log(String(child_process.exec('tzutil /s "Eastern Standard Time')));
});
This changes automatically the timezone from the system.

Related

Is there a way to get the actual time in UST (ignoring user settings) in React Native?

I'm currently working on a bug where the user manually sets their timezone and then manually sets the time within that timezone (say, 3 hours behind). This causes the system to use the user's time (which is 3 hours behind UST). Due to this, any calls to a Javascript or React Native library will return a time that is 3 hours behind the actual time. This causes issues when dealing with API calls to my server which returns the actual time in UST
I've tried using Date objects, the I18n library, and just about everything in between. I'm trying to find a universal fix for both Android and iOS since this is a part of my cross-platform codebase.
Any help would be greatly appreciated!
The libraries get the time from the client, how about getting the time from an external source? You can use this API: https://timezonedb.com/api
Another possibility is storing and updating a time offset, so you can calculate the actual time from the current time that is set.

how to get clients actual time and timezone to perform system time check

This might be a very vague question but please bear with me.
I am working on an application that requires me to perform a system time check on clients machine. The issue I am trying to address is, when clients travel across timezones and change their system time instead of changing the timezone it creates problems during the oauth negotiation. How should I go about addressing this problem in such a way that this issue can be self-detected when a client tries to login to the app rather than having to manually detect this kind of issue?
You can call toUtc() on a new DateTime.now() to convert it to UTC. It shouldn't be affected by time zones if it's in UTC, and the string representation will look like "2013-10-18 08:52:16.861Z" (the Z at the end means UTC).
You should be able to use a DateTime in UTC for OAuth negotiation. If not, please share more details; it's probably a bug in either Dart or your OAuth client.
It sounds like your timezones are pretty important so you shouldn't trust JavaScript system time with a 10 foot stick.
If I were you I would use PHP to geo-locate them and apply the timezone based on their location.
You will want to check out Get PHP Timezone Name from Latitude and Longitude?

Enforce timezone for angular.js application

I'd like to use one single timezone for an angular.js application. I'm aware that angular.js currently uses browsers timezone settings for date formatting, but I'd like to override this setting so that I can enforce a specific timezone for a user so that it doesn't depend on a browser settings.
It is a business application in question so there is no need for user specific timezones. Everything happens in a company's specified timezone and this is why I'd like to enforce it for every user. Data is saved in UTC, but it needs to be shown in company timezone for every user without depending on user location/locale/browser settings.
Is there any way I can accomplish this that anyone is aware of? And if there is, it'd be greatly appreciated to point me to correct way to do it :) So far I've had zero luck with it.
You can use a library such as timezone.js, or moment.js. I've used timezone successfully, and I've heard moment.js works pretty well. You'll likely want to make an injectable factory..
angular.module('date', [])
.config(function () {
timezoneJS.timezone.zoneFileBasePath = '/tz';
timezoneJS.timezone.init();
})
.service('dateConverter', function () {
return {
toDisplayDate: function (utcDateIn) {
return new timezoneJS.Date(utcDateIn, 'America/Los_Angeles')
}
}
});
That's just off the top of my head, but it's an example of what you'll probably have to do - convert dates from native JS to the library dates.
Sorry, but it's not possible to change the time zone behavior of the JavaScript Date object. It will always use the time zone of the computer that it's running on.
The best you can do is work around it with one of the libraries listed here. Stephen's answer shows how you can integrate one of them in to Angular.
Also, I'd consider very carefully when you say "there is no need for user specific timezones". Sometimes, that is the case, but very rarely. Often, companies have locations in multiple time zones, or they have employees that travel, or they interact with customers or partners that are in different time zones.
Besides, if what you say is true - that users are always in the single time zone of the company, then wouldn't that already be the local time zone for their computer? If so, then there's not much to do.
If you have users in other time zones, but you wish them to use the company's primary time zone, then that would be a case that would require one of these libraries. But consider carefully the impact of that. Depending on how far away a user is, even their current date might be different than the company's date.

Need workaround for Firefox Date() bug

I'm working on a canvas graph that's updated in real time with information we're displaying to a customer, and were in the process of preparing for the DST change on the clocks. One of our requirements is for the graph to carry on functioning as usual without the need for the customer to refresh the page when the clocks switch over.
While working on this problem, I found out about this bug with Firefox:
https://bugzilla.mozilla.org/show_bug.cgi?id=127246
Basically the Date() object in JavaScript doesn't update in Firefox if the system time is changed without having to close the browser/tab, and as we're querying an API using the system clock, this is a pretty major problem.
I'm assuming it's not fixed as the ticket is still marked as 'NEW', and I'm also pretty sure it's this that's causing the problem rather than another part of my code, so how can i get the current time of the system clock after it changes in Firefox without having to refresh the page?
FYI the version of Firefox I'm using is 19.0.2
Thanks in advance
Example
Set system clock to 12:00 and open web app...
var currentHour = new Date().getHours() //returns 12
Set system clock to 13:00 without reopening web app..
var currentHour = new Date().getHours() //returns 12
You can't ever rely on the client-side to have the correct date/time set anyway. The only workaround I can think of is to request the current time from another source, e.g. the server.
If you don't want to bug your own server you could find a public API that returns a timestamp, like some kind of Time API, or a service with reliable uptime such as eBay's Client Alerts API for instance:
http://clientalerts.ebay.com/ws/ecasvc/ClientAlerts?callbackname=hello&callname=GetPublicAlerts
hello({"Timestamp":"2013-03-22T14:43:21.757Z","Ack":"Failure","Errors":[{"ShortMessage":"Missing required input element.","LongMessage":"Required input element is missing from the request.","ErrorCode":"1.19","SeverityCode":"Error","ErrorParameters":[{"Value":"ChannelDescriptor","ParamID":"0"}],"ErrorClassification":"RequestError"}],"Build":"E809_CORE_BUNDLED_15739296_R1","Version":"809"});
Ignore everything and just get the UTC timestamp. Just make sure you're not bashing the hell out of some server for data you don't really need!
Use Web Workers
Instead of creating a new window as in Sergiu Toarca's answer, create a new web worker every time you need an update. Firefox would update the Date() object whenever a new web worker is generated.
function currDate() {
var blob = new Blob([""]),
blobURL = window.URL ? window.URL.createObjectURL(blob) : window.webkitURL.createObjectURL(blob),
worker = new Worker(blobURL);
worker.terminate();
return new Date();
}
You can use it like a normal Date() object:
currDate().getHours(); // Gives you an updated hour
See DEMO (Works on Firefox 19).
There is a simple (but very hacky) workaround for this problem. You can create a new window (which for some reason resets the cache of the current window), get the date from there, and then immediately close the window.
var getRealDate = function() {
var w = window.open();
var ret = new Date();
w.close();
return ret;
};
See it work on jsfiddle. Click the button, then change your timezone, then click the button again, and you will get an updated value.
Note: Only tested in Firefox 19
As you are talking about real-time updates of the canvas I assume that you are using some kind of push technology, such as making use of web sockets, or some fake push technology such as AJAX long polling.
However, as you can not rely on the client-side time anyway (as was mentioned in the other answer), why not just use your real-time push data packages to include the current time?
This way you can kill two birds with one stone (sorry for the martial expression, but that's how they say ;-)):
You have one central clock you can rely on: Your server.
You make use of your existing data update infrastructure and do not need something else on top.
Clients can set their clocks to whatever they want, they will always the correct data.
All your clients need to do is to get the timezone they are in initially, and then add or subtract the difference to the timezone that is being delivered by the server. E.g., if your client is on UTC+1 and your server is UTC+4, then simply subtract 3 hours from each timestamp your server delivers.
As DST changes only appear twice a year, you can even hard-code this into your client and use two different addition / subtraction algorithms. Which one you have to use you can decide depending on the date part of the time stamp the server sends to you.
This way you should have solved all your problems, it works in every browser, and is independent of any time settings of the client.
Hope this helps :-)
Here's a super-simple solution for the OP's specific situation, given that the following assumptions I've made (based on what's written in his question and comments) are correct:
the graph is only for one customer
the graph will be loaded primarily on Firefox (versions that have the same referenced bug)
the customer's machine(s) is/are all based in GMT (which becomes BST when the clocks change)
the machine clock(s) is/are reasonably accurate
the customer doesn't go changing the machines' clocks will-nilly.
If the above are true (possibly not even all of them), this becomes pretty simple. Because you'd really only be worried about two time zones, GMT and BST, you can adapt your example as follows:
Add this bit of code at load time / graph initialization:
// given a date object, returns the actual hour (works for GMT/BST only)
var getDisplayHour = (function() {
var initiallyGMT = (new Date().toString().indexOf('BST') === -1);
return function ( date ) {
var isGMT = (date.toString().indexOf('BST') === -1);
var offset = initiallyGMT - isGMT;
return date.getHours() + offset;
}
})();
Set system clock to 12:00 and open web app...
var currentDisplayHour = getDisplayHour( new Date() ); // returns 12
Set system clock to 13:00 without reopening web app..
// the referenced bug keeps the same time, but it successfully changes the time zone, so:
var currentDisplayHour = getDisplayHour( new Date() ); // returns 13
Tested on FF 19.0.0.2 on Mac and Windows 7.
Note: Since I wasn't really able to reproduce the OP's issue, and considering the cited use case, I'm not even sure there's a need for any of these workarounds at all. One might expect a more accurate test for the OP's use case to involve changing both the time AND the zone. E.g. not just 12:00 -> 13:00, but 12:00 GMT -> 13:00 BST. An even more accurate simulation of the DST changeover would be to set the clock to 2013-03-31 00:59:00 GMT, check the new Date().getHours(), wait a couple minutes, and then to check the hour again.
But, as I said, I haven't been able to reproduce the cited bug this myself, so I could definitely be wrong (in which case I'll amend or remove this answer).
Hope this helps, anyway!

Client Timezone in ASP.NET

I have a table that needs to display a date/time in the client's timezone. However, I am having a hard time finding a way to do this effectively. I know I can use client side javascript to get the timezone (and that this method is a little flaky), but I need it in the Page_Load event, so I can't call javascript beforehand.
I can get it from a separate page (at login for example), but that doesn't always work, because sometimes people use bookmarks directly into internal pages, and bypass logon with a cookie.
So I am left a few choices:
1. Have a cache per user for the last timezone that I fill up at every opportunity from a postback with no guarantee it will be right)
Try some weird IP geolocation hack
Have a user profile that allows the user to set their timezone (again, if they travel this won't always be right either)
Try some funkly page redirect to force the postback, (but some browsers disable page redirects)
Have the user explicitly set the TZ
Do the tz formatting in Javascript
None of these are ideal, it seems to me to be info the Browser should be providing the server. Does anyone have any other suggestions?
If possible, display times relatively. Rather than showing a particular time, use prose like, "5 minutes ago," or "Last week."
If you must display an absolute time in the client's time zone, based on your comments I'd go with option #5, sending UTC time down to the browser and then displaying local time using JavaScript. From your description it sounds like users can visit the page(s) that need to display the time in their time zone without having logged in, so storing it in the user profile seems inadequate.
I discuss the relative time display concept in more detail in Advice for Storing and Displaying Dates and Times Across Different Time Zones, as well as provide a simple extension method on the DateTime structure for adding a ToRelativeDateString method so that you can write code like:
string relativeTime = myDateTimeVariable.ToRelativeDateString();
Hope this helps...
I would use a mixed strategy:
Users can set the timezone in their profiles
Default is "auto" which means: format with JavaScript
Keep the timezone in the user profile however on each page that you display it (or in the master page) give the user the ability to adjust it. Once its adjusted allow it to persist for the remainder of the session and if they want it set then they will need to set it in their profile.
5, 2, 3, 4, 1 is probably the best order of your options.
Just output all times in UTC and then transform to local time at client side.
I would have to agree with Scott Michael. Display relative time, if you need absolute times your browser already knows how to localise them from UTC.
But if you're looking for detecting timezones robustly with javascript (for use server side); check out jsTimezoneDetect. It will give you an Olsen timezone key that you can use with server side normalizations of datetimes.
I thought I'd give you an update. I did take up the various suggestions of formatting the date on the client side (or more specifically reformatting it.) As google fodder I have put a full explanation of this at the end of this post.
However, the problem is that Date.toLocaleString takes no parameters to control the formatting, and so, in my US locale anyway, I get a big bulky string "Saturday, November 27, 2010 3:58:38 PM" This is way too bulky, I want a compact format like Sat 11/27/10 3:58PM" but there is not way to control it AFAIK.
So I am going to modify to try to cache the time zone in the session based on input from the various key pages posting back the timezone offset, and include the ability to modify the tz in the user's profile. It is not nice, but it is the best I can come up with. Like I say, this really should be included in the browser's http headers.
----- Formatting on the client side ------------
So I have labels like this (in a ListView FWIW):
<asp:Label ID="TimeLabel" runat="server" class="UTCTimeCell Hidden">
<%# Eval("when") %> UTC
</asp:Label>
Note you have to include UTC for the timezone since the default ASP.NET formatter does not include it. (Here I am assuming you are storing your dates as UTC, which in nearly all cases you should.) Note Hidden is a standard css class I used with display:none.
Then I define the following functions in my utilties javascript (obviously I use jQuery...)
function timeFormatLocal(timeStr) {
var dt = new Date(timeStr);
return dt.toLocaleString();
}
function timeReformatLocal(selector) {
$(selector).each(function () {
$(this).html(timeFormatLocal($(this).html()));
});
}
then in my page ready event I use something like this:
timeReformatLocal(".UTCTimeCell");
$(".UTCTimeCell").removeClass("Hidden");
This reformats those label cells to the locale based format.

Categories