Determining the day of the week for specified date in an arbitrary timezone with momentJS - javascript

Say I had an ISO date string with embedded timezone information, like "2016-08-22T13:30:00-07:00" (Here, the -07:00 specifies PST). I'm looking for an elegant way to determine what day of the week it will be in that timezone on that date and time. I've tried moment.parseZone(datestring).weekday() to no avail. How can I make moment think in terms of the timezone specified in the string, instead of wherever the server happens to be?

You can try moment(datestring).utcOffset(datestring).weekday(), check the docs for more explanation. Also there is a part of the documntation on weekday which describes it as locale aware I am not sure if it maintains the time zone of the date while converting or defaults to your local/server location, I usually uses moment.day(), if it suits your use case, you can use it instead of weekday().

Related

Get UTC offset from timezone abbreviations

Is there anyway to get utc offset from a timezone abbreviations? Such as:
"PST"
for
Pacific Standard Time (North America)
which will result in UTC−08. I found a way on moment-timezone but it did not help much.
It provides a list of timezone identifier but most of them are deprecated.
Thank you.
This is a quite tricky topic and similar questions have already been discussed.
See Detect timezone abbreviation using JavaScript or
Get timezone abbreviation using offset value
I would propose two options:
1. Hash table. Create a key-value pair of what you require based on standard information (e.g. list of timezone abbreviations and their offset). Something like
let offsetByAbbrev = {"PST" : "UTC-08", "EST" : "UTC+01", ... }
But this needs serious maintenance as it will get deprecated quickly.
2. Date manipulation. You can create a date in a specific timezone with momentjs, however, not with abbreviations. And there is a good reason for it: these abbreviations can change and can also cause ambiguity. You can check out the JSON used by momentjs-timezone: https://github.com/moment/moment-timezone/blob/develop/data/packed/latest.json which will give you a general sense of how chaotic it can be. For example do a simple ctrl+f search for PST and see the results.
So I would suggest using the timezone names - which you can actually create and use with momentjs-timezone. See How to create time in a specific time zone with moment.js where you can create a moment object based on the timezone name and that object will contain (as per the spec of moment timezone: https://momentjs.com/timezone/docs/#/zone-object/) the offset itself.
I know this does not exactly resolve your problem, though what you are trying to do is not necessarily the best approach to reach your an ideal solution.

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.

JavaScript: How to set a date so that it looks the same all over the world?

One of our programmers decided to use a DATE field in the MySQL db in order to achieve this.
Sending and saving a JS date object did work well until the daylight saving changes intervened (with nasty effects :) ).
Of course, saving the date in a DATETIME field solves it, but everybody sees the time/dates in their own timezone.
We need everybody (all over the timezones) to see the same date!
I clarify this, to get the proper answers:
I want to keep using the DATE field storage type in MySQL (vs DATETIME - ok, maybe too much of an optimization, but it's already there and I want a long term solution for when I receive such structure/code from other developers)
Sending local time (local JS in browser) 23-05-2016, will reach the server as 22-05-2016 0X:X0:00Z (UTC) and be store as such. Because it's a DATE field, the stored value will become 22-05-2016 only. And you lost a day! :)
Our solution from bellow not only fixes the DATE field trimming, but also adds the fact that people now can see the same correct date (23-05-2016) no matter of the timezone they are in!
I like the outcome and would love to see some better solutions to achieve the same and improve the system.
Actually, we have noticed the problem only when the daylight saving time changed, so my solution (as answer bellow) is a good solution for that as well. And it only consumes resources client-side.
I have posted my own solution to this question as an answer bellow.
It would be really cool to see a much better solution from you!
With Javascript
Save your dates in ISO format (including timezone information) and use moment.js to convert the datetime to another timezone.
If moment.js is not already a dependency, and you want to avoid extra libraries, keep reading.
With MySQL
Instead of solving this problem when you write the data (losing timezone information in the process), solve it when you read the database.
In your SELECT query, normalize all DATETIME values to your preferred timezone using the convert_tz built-in function.
MomentJs is your best bet. Find the timezone you want and pass the ISO string to it and you should be good to go.
http://momentjs.com/timezone/docs/#/using-timezones/
A DATE is just a year, month, and day. It doesn't have a time, or a time zone. Think about your birthday or your wedding date, or today's date.
The JS Date object is not this at all. It's a timestamp. It's the number of milliseconds elapsed since Midnight January 1st 1970 UTC.
You should leave your date as a date-only wherever possible. Use the ISO-8601 date-only format, which is YYYY-MM-DD. If you have to assign it a time and time zone, then be very careful when you do.
If you just assign midnight local time, then you're risking losing a day (as you showed), and you're not considering that there are local days in some time zones where midnight does not exist! (Such as the spring-forward day in Brazil). Noon is a safer bet than Midnight, but still you should use this sparingly. The better approach is to keep dates as dates, not as date-times.
Also, I'd answer with code if I could, but you didn't provide any code in your question showing what was broken. Please read How do I ask a good question? and How to create a Minimal, Complete, and Verifiable example. Thanks.
There are more solutions to this, but the fastest and easiest that I could come up with is described bellow:
Let's intervene as early as possible in the information stream.
Just change the data before transmitting it through AJAX.
The function we used is this:
function addTimezoneDiffAnd12HoursToDate(date) {
var timezoneOffset = date.getTimezoneOffset();
date.setHours(12-Math.floor(timezoneOffset/60));
date.setMinutes(-timezoneOffset % 60);
return date;
}
What it does is that it converts a Date to be always at noon (12:00) UTC!
You can use it like this:
$scope.contract.contractDate = addTimezoneDiffAnd12HoursToDate($scope.contract.contractDate);
and send it as such to be stored in the DATE field.
Let me know if you have a simpler solution. I'd like to see it.

What's the difference between datetime in ISO 8601 and UTC formats in javascript?

I pick some date and time in javascript and then want to store it on server (.NET). Dates are supposed to be in future from the current moment (so they won't be before 1970).
Having read topics here on SO I learnt it's better to store date as a string and people suggest using Date.prototype.toISOString() or Date.prototype.toUTCString().
I've read that toISOString() is not available in IE 7. And I'd like to know other differences, when I should choose one or another function.
They're for different purposes.
UTC is the primary time standard by which the world regulates clocks and time.
ISO is standard format time. ISO also supports ms in its format.
So if you want to send data to the server, send the ISO, because ISO is the standard format:
var date = new Date();
sendDate(date.toISOString());
You can also use toISOString in IE7 polyfill.
I hope it will helpful to you.
Summary About toISOString() :-
The toISOString() method returns a string in ISO format (ISO 8601 Extended Format), which can be described as follows: YYYY-MM-DDTHH:mm:ss.sssZ. The timezone is always UTC as denoted by the suffix "Z".
Refer Below link for more information about toISOString().
Date.prototype.toISOString()
Summary About toUTCString() :-
The toUTCString() method converts a date to a string, using the UTC time zone.
Refer Below link for more information about toUTCString()
Date.prototype.toUTCString()
Always use .toISOString()
They give almost the same information, but in different formats. Here is what I get on my machine.
new Date().toISOString()
"2019-10-11T18:56:08.984Z"
new Date().toUTCString()
"Fri, 11 Oct 2019 18:56:08 GMT"
There are 4 reasons .toISOString() is more often what you want than .toUTCString().
A. More convenient sorting
When you sort alphabetically, the "2019-10-11T18:56:08.984Z" pattern of .toISOString() gives you the correct date order.
B. Millisecond precision
.toISOString() provides millisecond values, whereas .toUTCString() does not.
C. Any user can interpret correctly
The .toUTCString() value may be more familiar to human end-users, but only if the language settings are suitable for them. In contrast, the .toISOString() is the same regardless of language settings.
D. Reproducibly regeneratable by software
You can easily convert the ISO date string to a Javascript Date object, and then back again, regenerating exactly the same string. This is regardless of who gave you the ISO date string, where the server is, and where you are.
This is not automatically true for the UTC string. For example, if a second instance of your app system is running in a different time zone, or language, it's .toUTCstring() may use different numbers or words (respectively) to represent the same instant in time. It will be difficult for it to create a UTCString that matches what was made by the first instance of the app, since in general it will not know the language or timezone in which the first UTC string was produced.
I think nobody needs .toUTCString()
I don't know why `.toUTCString()` exists. Its word-heavy format makes it useless for internal storage of dates in your program, because it varies depending on your language and timezone setting etc.
So maybe it is to produce something nice to display externally for the user to see? Well, not really. Anyone who is not in the London time zone will not find it very helpful.
I live in London. And even I, even if I was writing an app purely for use by me, solely on my system, and only in my home, would still not want to use .toUTCString(). Because it is showing UTC (also known as GMT). London is not always on GMT. In summer, we move to GMT+1, so the .toUTCString() result would mislead anyone who didn't notice the "GMT" and do the time adjustment in their head.
If I wanted a natural-language time, to make non-computer literate users comfortable, I would construct it manually from parts, using a library like moment.js. If I wanted a quick-and-dirty solution, I would use .toString() which at least will move to Summer time when appropriate.

How to find browser date time format [duplicate]

I have set a deadline in UTC, as shown below, and I'm wondering what exactly the toLocaleString() method will do to it on user's local machines. For instance, will it account for daylight savings if they are in a timezone that recognizes it? Or will I need to insert additional code that checks where the user is, and then fixes the displayed time?
http://javascript.about.com/library/bldst.htm
var deadline = new Date('5/1/2013 ' + "16:15" + ' UTC');
alert(deadline.toLocaleString());
In general, the answer is yes. JavaScript will represent the UTC value at the appropriate local time based on the time zone settings of the computer it is running on. This includes adjustment for DST. However, as others have pointed out, the details are implementation specific.
If you want a consistent output, I would use a library to format your dates instead of relying on the default implementation. The best library (IMHO) for this is moment.js. The live examples on their main page will give you an idea of what it can do.
UPDATE
If you are passing UTC values that you want converted to the correct local time, and that time falls into a period where the time zone rules are different than the current one - then the results will be invalid. This is crazy, but true - and by design in the ECMA spec. Read - JavaScript Time Zone is wrong for past Daylight Saving Time transition rules
We don't know what exactly the toLocaleString method does (§15.9.5.5):
This function returns a String value. The contents of the String are
implementation-dependent, but are intended to represent the Date in
the current time zone in a convenient, human-readable form that
corresponds to the conventions of the host environment’s current
locale.
But yes, most implementations will consider DST if it is active in the current local timezone. For your example I'm getting "Mittwoch, 1. Mai 2013 18:15:00" - CEST.
Will I need to insert additional code that checks where the user is, and then fixes the displayed time?
I think you can trust toLocaleString - the browser should respect the user's settings. If you want to do it manually, check out timezone.js.
As you use "UTC" the date itself will be UTC format, but the toLocaleString() takes client's locale into account, which means it'll return the date in string updated with all and every changes typical to client's regional and locale settings (DST, date/time format, etc).As JS documentation describes this: "The toLocaleString() method converts a Date object to a string, using locale settings.".If you want to avoid this, use the toUTCString() method instead.I'd also recommend reading the accepted solution for the question Javascript dates: what is the best way to deal with Daylight Savings Time? to avoid (at least, to try to avoid :) future issues related to JS, browsers and locales.Hope this helps!

Categories