Moment and new Date() not displaying local time - javascript

I want to display the local date of the user, but nothing is working for me. It always returns the UTC time.
I have tried:
This returns UTC - also in here offset comes as zero.
let visitDate = moment.utc().format();
let offset = moment().utcOffset();
let visitDate1 = moment.utc(visitDate).utcOffset(offset)
This returns UTC
let visitDate = new Date()
let visitDate1 = moment(visitDate).local().format('MM-DD-YYYY hh:mm:ss');
This returns UTC
let visitDate = new Date()
let visitDate1 = visitDate.toLocaleDateString()
I have tried several methods, but it doesn't matter what I do, I always get UTC time. If I try on localhost then it displays the correct time, but once I host the page it displays UTC.
How can I transform to local?

moment().local() uses the timezone of the local machine, that's why it works in localhost
if you know it, I would specify the timezone:
moment.tz("America/Los_Angeles").format()

There seem to be several possible points of failure. I'll list the ones I think of below, and you can assess whether they're relevant to your setup.
1) The code that manipulates the date is executed on the server, not locally
Most of our Javascript code is written to execute in the user's browser, so that's the default assumption. If that assumption is wrong in this case, and the code is being executed on the server, then "local" means "on the server." Your server should be running with UTC time, which could produce the results you're seeing.
2) The user is running a browser set to UTC
If the browser you're using for testing is set to consider UTC as local time, it'd produce the results you're seeing. Since you're probably using the same machine for localhost and for testing, it's an unlikely source of the problem...but worth noting nonetheless.
3) Changing how the date is displayed does not change how the date is stored
Many of the tools we have for setting/changing the time zone affect how the date is displayed. However, Date objects in Javascript are stored using Unix Time (in milliseconds), which is UTC. When you create a Date object--even with a time zone specified--the behind-the-scenes representation will still be an integer (representing a number of milliseconds) and based on UTC. If you're checking the stored value rather than the displayed value, when you're testing, then there's a good chance you'll always see UTC. However, the work you're doing with the moment library should have the date formatted correctly. If you're checking the moment object, you should be seeing the time zone you expect to see.
If none of these three possible failure points applies to your context, then perhaps they spark an idea for you. (The third one, especially, feels like it might be on the right track even if it's not what's happening in your case.)

Related

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.

PHP dates and timezones

I have an admin panel where items entered will have a time_posted and an expiration time. These times use a timestamp (time()) upon being entered.
I want the entering of the expiration time to use a fancy date/time selector, but the selector uses JavaScript client time rather than server time.
A way to fix this would be to save the timezone a user is in, then use that as offset for the data entered, but it's something that has to be 100% correct.
Is there any 'proper' way to approach this? I saw that some PHP functions do use the timezone setting but others do not, for instance the actual time() function doesn't and even if I create a DateTime object, output the current timestamp, change the timezone and output the timestamp again it just returns the same timestamp twice.
Any pointers would be lovely
I assume that the actual timestamp value would still be correct (independent) regardless of what settings/timezone the end user has.
Problems may apper when/if you want to generate date strings server-side and thus return times with offsets.
Either
1. dont generate date strings server side, if you are not sure about the timezone offsets or
2. warn users and make sure that they specify their timezone and then force that timezone whenever you output date string from timestamps
A few things:
You probably don't need to identify the user's time zone for the scenario you describe, but if you did then please recognize that a time zone and an offset are two different things. See "time zone != offset" in the timezone tag wiki. If you actually think you need the user's time zone (such as "America/Los_Angeles"), then refer to this answer.
If you want the entered date to be relative to the client's local time zone, then you need to use either a Date object, or a library like moment.js in JavaScript. Use the individual date/time components from the date picker to get either a unix timestamp, or an ISO8601 formatted date/time string at UTC. For example, "2016-09-02T01:23:45Z"
If you want the entered date to be relative to some other time zone, then you need to transmit the actual values the client entered without modification. The best way is in ISO8601 format without offset. For example, "2016-09-02T08:00:00". On the server side, parse that value and apply whatever time zone is applicable.
If you are only selecting a date, and not a time, then you should really think about whether any time is applicable or not. Is 00:00 really applicable? Or should it be 24:00 or 23:59:59.999? If you don't care about the user's time zone, then really you shouldn't assign any time value at all. Just pass the date. For example: "2016-09-02"
Don't rely on the server's time zone setting to be anything in particular. Though PHP has functionality for setting a "default" time zone, you should try to avoid using it. It is much safer to be explicit about time zones on a per-operation basis. Use the DateTime class in PHP, not time().
Be sure to read Daylight saving time and time zone best practices, and to search thoroughly for other questions on StackOverflow, as much of this has been answered already in various other questions.

How to tell JavaScript Date where to take TimezoneOffset from?

I am using new Date(<date-string>) and then .getTime() to pass date strings to milliseconds from 1970.
The problem is that the date strings does not contain the timezone on them. They are British, so the timezone will be GMT or GMT+1 depending on the date...
When I use this technique in the front-end (Chrome), or in the back-end (Node.js). The time zone taken is the British one (GMT or GMT+1 depending on the date). I assume that is taken from the OS.
However, when using a Node.js server which I have been told is configured to be in UTC... the timezone is always going to be GMT, leading to errors during the British Summer Time.
Is there any way to tell Date to take the timezone from the OS without changing the server configuration?
Example:
var aDate = new Date('2016-06-23 10:15:0');
var timestamp = aDate.getTime();
Just in case my explanation is not clear:
// Executed on 28-06-2016
// In the browser (in London)
new Date().getTimezoneOffset(); // -60
new Date('28-06-2016 11:11:11').getTimezoneOffset(); // -60
new Date('28-01-2016 11:11:11').getTimezoneOffset(); // 0
// In the Node.js server I am forced to use, which is configured to use UTC
new Date().getTimezoneOffset(); // 0
new Date('28-06-2016 11:11:11').getTimezoneOffset(); // 0
new Date('28-01-2016 11:11:11').getTimezoneOffset(); // 0
// Ideally, I would like to have the output I get in the browser when I run the code in the UTC Node.js server
I recommend using Moment Timezone for this, since this would be needlessly complicated to implement without a library. To get UTC in milliseconds from a given date in a given timezone, you can do this:
const moment = require('moment-timezone');
function londonTimeToUTC(dateString) {
return moment.tz(dateString, 'DD-MM-YYYY HH:mm:ss', 'Europe/London').valueOf();
}
console.log(londonTimeToUTC('28-06-2016 11:11:11')); // 1467108671000
console.log(londonTimeToUTC('28-01-2016 11:11:11')); // 1453979471000
The second argument passed to moment.tz() is a format string, which is necessary if the date string is not in ISO format. The third argument is any valid timezone identifier.
Is there any way to tell Date to take the timezone from the OS without changing the server configuration?
The time zone from the OS is what the Date object uses. If you're asking if you can change that time zone without changing the configuration, then no - there is not a way to do that. The Date object always takes on the behavior of the local time zone. Even if you supply an offset in the input string, it just uses that to determine the internal UTC timestamp. Output via most of the properties (including toString and getTimezoneOffset) will always use the local time zone.
Even in your examples, you cannot count on the browser behavior always returning the values you showed, simply because each user visiting your web site may have a different time zone setting.
The recommended way to deal with this is by using the moment.js library, which can handle UTC and local time by itself, but may require use of the moment-timezone extension if you are wanting to work with a specific time zone, such as Europe/London.
Now, with that said, if you're certain that your entire node.js application will run in a single time zone, and you're running on Linux or OSX (not Windows), then you can indeed change which time zone that node.js considers to be "local". Simply set the TZ environment variable before you launch node, like this:
env TZ='Europe/London' node server.js
There is no equivalent for the browser, or for Windows. And you still have to contend with possible non-UK users on your web site - so this doesn't guaranteed a match between client and server time. But it does address your question.
See also:
How to initialize javascript date to a particular timezone
How to make the timezone of date to UTC
How to set default timezone in Node.js

JS Timezones not current

I have just created a blog script, but when I add a comment.
The timestamp in the database is 2014-07-29 18:55:00 even that the clock on my PC is 2014-07-29 20:55:00.
So I would like to change the time according to the timezone.
So I tried with this code (where timestamp is 2014-07-29 18:55:00):
var UTC = moment.tz(timestamp, "UTC");
timestamp = UTC.clone().tz(timezone).format('YYYY/MM/DD H:mm:ss');
Note: window.timezone is set using the following code:
var tz = jstz.determine();
var timezone = tz.name();
The time I want to get out is 2014/07/29 20:55:00, but I get this out: 2014/07/29 17:53:47
I am using the following libraries for this above code:
https://bitbucket.org/pellepim/jstimezonedetect
http://momentjs.com/timezone/
http://momentjs.com/
Hope that someone understands whats going on.
NOTE: I live in Europe/Denmark which have the timezone UTC/GMT +2 hours
In addition to script, moment-timezone requires data to function. If you don't have the data loaded, in version 0.1.x it will use the local time zone - as if you just called moment() without any tz specified. This has been fixed for the upcoming 0.2.0 release, such that it gives an error instead of silently doing the wrong thing.
Normally, you could use the data builder to just provide data for the time zones you were interested in. However, it is currently offline because the format of the data changed in the last release and the author has not yet had time to complete the required updates.
In the meantime, you can use one of the "data-included" versions, downloadable at the top of the main page - for example, use moment-timezone-2010-2020.js instead of just moment-timezone.js.
Also, you since you're using jsTimeZoneDetect - you should test the value returned by jstz.determine() to make sure it is indeed the time zone you are expecting. The +2 offsets are notoriously difficult to test for. See some of the known issues.
You could set the timezone
moment().tz("Europe/Denmark").format();

Javascript date object in different locale and timezone

I need to write a web application that show events of people in different locale. I almost finished it, but there're 2 problems with date:
using date javascript object, the date depends on user computer settings and it's not reliable
if there's an event in a place with dfferent timezone respect user current position, i have to print it inside (). Is it possible in javascript to build a date object with a given timezone and daylight settings?
I also find some workaround, such as jsdate and date webservices, but they don't overcome the problem of having a javascript object with the correct timezone and daylight settings (for date operation such as adding days and so on).
A couple of things to keep in mind.
Store all event datetimes in UTC time
Yes, there is no getting around this.
Find out all the timezones...
...of all the users in the system. You can use the following detection script: http://site.pageloom.com/automatic-timezone-detection-with-javascript. It will hand you a timezone key such as for example "America/Phoenix".
In your case you need to store the timezone together with the event, since a user may switch timezone - but the event will always have happened in a specific one. (argh)
Choose your display mechanism
If you want to localize your event dates with Javascript, there is a nifty library for that too (which can use the keys supplied with the previous script). Here: https://github.com/mde/timezone-js.
with that library you can for example do this:
var dt = new timezoneJS.Date(UTC_TIMESTAMP, 'America/New_York');
or
var dt = new timezoneJS.Date(2006, 9, 29, 1, 59, 'America/Los_Angeles');
where UTC_TIMESTAMP for example could be 1193855400000. And America/New_Yorkis the timezone you have detected when the event took place.
The dt object that you get from this will behave as a normal JavaScript Date object. But will automatically "correct" itself to the timezone you have specified (including DST).
If you want to, you can do all the corrections in the backend - before you serve the page. Since I don't know what programming language you are using there, I cannot give you any immediate tips. But basically it follows the same logic, if you know the timezone, and the UTC datetime -> you can localize the datetime. All programming languages have libraries for that.
You're missing the point of a Date object. It represents a particular point in time. As I speak, it is 1308150623182 all over the world. Timezone only comes into play when you want to display the time to the user. An operation like "adding a day" does not involve the time zone at all.
One possibility might be to use UTC date and time for everything. That way, there is nothing to convert.
Another is to have your server provide the time and date. Then you don't have to depend on the user to have it set correctly, and you don't have to worry about where your user's timezone is.
Use getUTCDate(), getUTCHours(), ... instead of getDate(), getHours(),...
getTimetoneOffset() could be useful, too.

Categories