Javascript - Retrieve OS Date formatting - javascript

Hmmm... Okay so I've been searching the web for 2 days now without any luck. I've seen a lot of answers on how to format a javascript date for example new Date().toString("yyyy-MM-dd")... Which would return something like 2013-04-05.
This is absolutely not the problem.
What I want, is the possibility to set the format in which my OS displays dates, then retrieve that specific format and display it in the browser.
For example, let's say I changed the format of the date in my OS to MM-yyyy/dd (this is for arguement sakes, whether that would work or not is irrelevant)). Then I'd expect to see 04-2013/05 in my OS, right? Next I want to retrieve this specific format in my browser via Javascript so that I can use this to format my dates throughout my webpage.
If this is lunacy and cannot be done, please tell me, as I've got a headache from searching.
Also, if you say use someDateObject.toLocaleDateString() without explaining exactly why .toLocaleDateString would work, I'm going to ignore it, because I've tried setting my date-format in my OS to numerous formats and every single time I use .toLocaleDateString(), I receive the same format: dd/MM/yyyy

first attribute of .toLocaleDateString method locale(s) used.
current locale you can obtain through navigator.language (in firefox or chrome) parameter.
in IE you can obtain navigator.browserLanguage or navigator.systemLanguage
in browsers other than IE it is impossible to obtain system language this way
after this you can call new Date.toLocaleString(navigator.language||navigator.browserLanguage) and it will be formated correctly depending on browser language

Related

toLocaleTimeString() behaviour without arguments in Chrome and Safari

I read in the MDN documentation that:
toLocaleTimeString() without arguments depends on the
implementation,the default locale, and the default time zone
What does this mean exactly?
And I tried the following code in both Chrome(Version 87.0.4280.88) and Safari browser(Version 14.0).
new Date().toLocaleTimeString()
in Chrome it gives output as
16:57:37
whereas in Safari it gives output as
4:57:37 PM
With regards to the above example can someone explain how the implementation is changing from one browser to another, and why is it so?
Edit:
All this was done using MAC, I tried changing preferred language under Setting -> "Language and Region" to English(US) it was English(India) before, as soon as I did that change and restarted chrome the result became.
4:57:37 PM
But for Safari without doing this change it was able to show in 12 hour format, what was the reason for that?
The specification for toLocaleTimeString states:
This function returns a String value. The contents of the String are implementation-defined, but are intended to represent the “time” portion of 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.
with the definition of implementation-defined being:
An implementation-defined facility is one that defers its definition
to an external source without further qualification. This
specification does not make any recommendations for particular
behaviours, and conforming implementations are free to choose any
behaviour within the constraints put forth by this specification.
Therefore browsers are free to implement this feature as they see fit.

Should I use `Date()` to store a date without time in javascript

I need to store in the backend a date in the format yyyy-mm-dd;
I've initially used in the frontend a js Date() object to store it, and dropping the time and timezone info while sending it to the backend; but that caused a "timezone issue" when parsing back the yyyy-mm-dd string into Date();
even if it's possible to workaround that issue I was wondering if using a simple String wouldn't be better; is there any drawback that now I cannot see and so I should use a Date anyway?
Similar to other comments, I would also recommend sticking with Date instead of strings to prevent browser differences and for ease of use. One note is when setting the date, don't forget to account for day-light savings which might cause a database crash if not accounted for.
CSS-Tricks: Everything you need to know about date in javascript

Moment dates are parsed different in Mozilla and Chrome?

I have an issue with dates in Mozilla, I am using fullcalendar plugin for angularJs in my project. While using the moment dates, Chrome seems to be working fine but Mozilla seems breaking. I am using Timezones with the moment. Many blogs and posts seems to mention the format of moment dates while having cross browser issues.
Here it is,
console.log(moment(new Date('2017-02-28T18:30:00')).format('dddd-MMM DD,YYYY'));
Mozilla : Tuesday-Feb 28,2017
Chrome : Wednesday-Mar 01,2017
I am really stuck with this, and I have seen post about mentioning the format with the moment dates, but I have used the format in the above sample but it fails to return the desired output. On the other hand Chrome is returning the correct result, what am I doing wrong ?
If you need any details please leave a comment.
Do not use moment(new Date('2017-02-28T18:30:00')) use moment(String) instead (since your input is in ISO 8601 format).
As moment parsing docs says:
Warning: Browser support for parsing strings is inconsistent. Because there is no specification on which formats should be supported, what works in some browsers will not work in other browsers.
Here a working sample:
console.log(moment('2017-02-28T18:30:00').format('dddd-MMM DD,YYYY'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.17.1/moment.min.js"></script>
If your input is UTC use moment.utc:
moment.utc('2017-02-28T18:30:00')
If your input is in a given timezone (e.g. Asia/Calcutta) use moment.tz(..., String);
moment.tz('2017-02-28T18:30:00', 'Asia/Calcutta')
By default moment parses string in local time, you need to know timezone of your input. Note the moment has local(), utc(), and tz(String) methods to change timezone of a moment object.
You are converting a JS Date to a MomentJS date so I can only assume Firefox parses the JS date differently.
With MomentJS you should be able to simply replace your code:
moment(new Date('2017-02-28T18:30:00')).format('dddd-MMM DD,YYYY')
with:
moment('2017-02-28T18:30:00').format('dddd-MMM DD,YYYY')
https://momentjs.com/docs/#/parsing/
if you use angularjs, it's easier to use filter.
$filter('date')('2017-02-28T18:30:00', "dd/MM/yyyy");

How does toLocaleDateString() work in Chrome?

I understood the javascript method toLocaleDateString() used computer settings.
Let's take the W3Schools example :
when i change date and hour formats of my computer, the result is different in Firefox or IE (as expected), but Chrome still shows the same date format, why?
From the MDN:
"The exact format depends on the platform, locale and user's settings."
And,
"You shouldn't use this method in contexts where you rely on a particular format or locale."
Basically, "Why" is because that's how Chrome does it. If you need a specific format, you're going to have to specify it yourself.
From the EMCAScript 5 standard:
15.9.5.6 Date.prototype.toLocaleDateString ( )
This function returns a String value. The contents of the String are implementation-dependent, but are intended to represent the “date” portion of 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.
Chrome can represent the date as a locale date string in whatever manner it likes. The standard only supplies guidelines; it does not mandate a particular format. And, in fact, the result will vary not only between browsers but also within Chrome itself depending on your locale settings.
It looks like Chrome does not use the Windows regional settings, but its own settings instead. These are available via Settings > Advanced Settings > Language. However the date format is not explicitly defined, it is inferred from the language + country choice, for instance:
English (US) sets date format to mm/dd/yyyy
English (UK) sets date format to dd/mm/yyyy
(For anyone trying to change these, don't forget - like I did - to restart Chrome for the settings to take effect)
Back to the original question, it looks like it was legit to use toLocaleDateString() as long as the idea is to present the information in a format the human user understands. But this would be an ideal world, where every user has his/her browser properly configured. Instead, Chrome is set by default to English(US) as long as people leave it be in English, and it takes some googling (which most users won't do) to change these settings.
This makes it risky to use toLocaleDateString() even when not "relying on a particular format or locale". It looks like the only "serious" option for any cross-browser web application is to manage its own date format preferences (per user, of course...)

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