new Date() Operating System Dependent?

后端 未结 5 488
伪装坚强ぢ
伪装坚强ぢ 2021-01-17 07:07

Alright so I\'m using javascript to return the shorthand timezone of the users system time with a simple regex like so

new RegExp(\'\\\\(.*\\\\)\').exec(new          


        
相关标签:
5条回答
  • 2021-01-17 07:25

    A few things:

    • Yes, the output of .toString() on a JavaScript Date object is implementation dependent. You will get different results on different operating systems, browsers, and versions. This is defined by ECMAScript 5.1 §15.9.5.2 as follows:

      15.9.5.2   Date.prototype.toString()

      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.

    • Abbreviations like EST and EDT do not represent the entire time zone. They represent specifically the segment of the time zone that applies to that particular moment in time. remember, new Date() is initialized to the current "now". See also "Time Zone != Offset" in the timezone tag wiki.

    • In general, time zone abbreviations are ambiguous. EST might mean Eastern Standard Time in the US, or it might mean Eastern Standard Time in Australia. Of course, they might use AEST in Australia, but who's to say that they are the ones to prepend an A instead of the Americans? Besides, EST could also mean Australian Eastern Summer Time. The abbreviation "CST" is even worse, having 5 different interpretations - two in Australia, one in the USA, one in China, and one in Cuba, and all have different offsets. See this list on Wikipedia for more examples.

    • The only standard for time zone abbreviations that are even defined in a specification are, those in RFC822 §5.1:

      zone        =  "UT"  / "GMT"                ; Universal Time
                                                  ; North American : UT
                  /  "EST" / "EDT"                ;  Eastern:  - 5/ - 4
                  /  "CST" / "CDT"                ;  Central:  - 6/ - 5
                  /  "MST" / "MDT"                ;  Mountain: - 7/ - 6
                  /  "PST" / "PDT"                ;  Pacific:  - 8/ - 7
      

      But this is a very discouraged format, as it's focused just on the USA and says very little about the rest of the world. The "military" zones A-Y were deprecated in RFC1123 anyway. Only "Z" to represent UTC remains in modern formats like ISO8601.

    • You've said what you want, but not why you want it. If you're just trying to determine the time zone of the user, please consider jsTimeZoneDetect which will return you an IANA time zone identifier, such as America/New_York. You can then take that back to your server. Most platforms have either native support or libraries for working with these.

    You can use Date#toISOString to get a consistent format.

    0 讨论(0)
  • 2021-01-17 07:25

    It is implementation dependent, meaning it is operating system and browser dependent, making it not very reliable if you want a consistent result.

    If you want to parse it consistently in a specific way your best bet is gonna be to parse it out manually in code or to use a package like datejs or similar.

    0 讨论(0)
  • 2021-01-17 07:34

    It doesn't make sense, because javascript.

    However, you can get the timezone offset by this way:

    yourDate.getTimezoneOffset();
    

    This will return the browser clients offset in minutes. See getTimezoneOffset()

    0 讨论(0)
  • 2021-01-17 07:43

    I appreciate all the answers that were presented and here is what I came up with

    getUserTz: function() {
        var tz;
        try {
          tz = new RegExp('\\(.*\\)').exec(new Date().toString())[0];
        } catch(e) { // IE10 and lower support
          tz = new Date().toString();
          tz = tz.replace(/[^A-Z]/g, '');
          var zones = ['ADT','AKDT','AKST','AST','CDT','EDT','EGST','EGT','EST','HADT','HAST','MDT','MST','NDT','PDT','PMDT','PMST','PST','WGST','WGT'];
          for(var i=0; i < zones.length; i++) {
            if(tz.indexOf(zones[i]) != -1) {
              tz = "(" + tz.substr(tz.indexOf(zones[i]), tz.length) + ")";
            }
          }
        }
        if(tz && tz.length <= 6) {
          return tz;
        }
        tz = tz.replace("US","");
        tz = tz.replace(/[^A-Z]/g, '');
        return "("+tz+")";
    }
    

    First try the original method I was using so that way I get for example (EDT) on mac, then if the characters returned are greater than 6 i take the string returned on windows for example

    "(US Eastern Daylight Time)"

    and strip out US, then i strip out all lowercase characters leaving me with "EDT" and wala, i have a shorthand property of this timezone, this probably doesn't cover all possible zones but my only concern at the moment is north american timezones and this should handle 90% of the use cases.

    If anyone wants to use this code, feel free https://gist.github.com/austinksmith/10281815 I made some updates to support IE10 and lower since the returned format differs from IE11 , feel free to update to add support for other timezones :)

    EDIT: This has been tested in IE11-9, FireFox, Chrome, Safari and works cross platform at least in regards to Windows & Mac PC's

    0 讨论(0)
  • 2021-01-17 07:49

    Never tried but the text you are trying to find is, at the end of the day, a human-readable description of the timezone. One could reasonably expect it to change based on language for example. It is entirely possible that different browsers have taken different approaches.

    The part to program against, IMO, would be the GMT-0400. Although a better way to get that in my opinion is

    new Date().getTimezoneOffset() / -60
    

    I suppose you could then translate that to a text yourself (either load an array of all timezones or via a web service) if it is important to have the same on all browsers.

    Edit in response to comments

    If you want to use the information programatically then I'd suggest using the offset instead. If you want to present it to the user then you have a couple of options as I see it:

    1. Use the Regexp you originally had and accept that it will be a slightly different text on different browsers/operating systems

    2. Create a translation table of the value returned from the regexp for the most popular browsers/OSes and present that (with the "key" beng the value returned by your regexp above). In the event that no match exists you could either present the value returned by the regexp or fall back to a default translation per offset.

    3. Combine the offset and some form of geoIP lookup to take a best guess at the zone (matching again to a list of your own for the text to present), maybe again with a default per offset.

    Or, of course, some combination of the above. What is the use case? Why is a human readable but cross-browser text important?

    0 讨论(0)
提交回复
热议问题