Create a Date with a set timezone without using a string representation

前端 未结 23 1110
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-11-22 01:48

I have a web page with three dropdowns for day, month and year. If I use the JavaScript Date constructor that takes numbers, then I get a Date obje

相关标签:
23条回答
  • 2020-11-22 02:09

    This is BEST solution

    Using:

    // TO ALL dates
    Date.timezoneOffset(-240) // +4 UTC
    
    // Override offset only for THIS date
    new Date().timezoneOffset(-180) // +3 UTC
    

    Code:

    Date.prototype.timezoneOffset = new Date().getTimezoneOffset();
    
    Date.setTimezoneOffset = function(timezoneOffset) {
      return this.prototype.timezoneOffset = timezoneOffset;
    };
    
    Date.getTimezoneOffset = function() {
      return this.prototype.timezoneOffset;
    };
    
    Date.prototype.setTimezoneOffset = function(timezoneOffset) {
      return this.timezoneOffset = timezoneOffset;
    };
    
    Date.prototype.getTimezoneOffset = function() {
      return this.timezoneOffset;
    };
    
    Date.prototype.toString = function() {
      var offsetDate, offsetTime;
      offsetTime = this.timezoneOffset * 60 * 1000;
      offsetDate = new Date(this.getTime() - offsetTime);
      return offsetDate.toUTCString();
    };
    
    ['Milliseconds', 'Seconds', 'Minutes', 'Hours', 'Date', 'Month', 'FullYear', 'Year', 'Day'].forEach((function(_this) {
      return function(key) {
        Date.prototype["get" + key] = function() {
          var offsetDate, offsetTime;
          offsetTime = this.timezoneOffset * 60 * 1000;
          offsetDate = new Date(this.getTime() - offsetTime);
          return offsetDate["getUTC" + key]();
        };
        return Date.prototype["set" + key] = function(value) {
          var offsetDate, offsetTime, time;
          offsetTime = this.timezoneOffset * 60 * 1000;
          offsetDate = new Date(this.getTime() - offsetTime);
          offsetDate["setUTC" + key](value);
          time = offsetDate.getTime() + offsetTime;
          this.setTime(time);
          return time;
        };
      };
    })(this));
    

    Coffee version:

    Date.prototype.timezoneOffset = new Date().getTimezoneOffset()
    
    
    Date.setTimezoneOffset = (timezoneOffset)->
        return @prototype.timezoneOffset = timezoneOffset
    
    
    Date.getTimezoneOffset = ->
        return @prototype.timezoneOffset
    
    
    Date.prototype.setTimezoneOffset = (timezoneOffset)->
        return @timezoneOffset = timezoneOffset
    
    
    Date.prototype.getTimezoneOffset = ->
        return @timezoneOffset
    
    
    Date.prototype.toString = ->
        offsetTime = @timezoneOffset * 60 * 1000
        offsetDate = new Date(@getTime() - offsetTime)
        return offsetDate.toUTCString()
    
    
    [
        'Milliseconds', 'Seconds', 'Minutes', 'Hours',
        'Date', 'Month', 'FullYear', 'Year', 'Day'
    ]
    .forEach (key)=>
        Date.prototype["get#{key}"] = ->
            offsetTime = @timezoneOffset * 60 * 1000
            offsetDate = new Date(@getTime() - offsetTime)
            return offsetDate["getUTC#{key}"]()
    
        Date.prototype["set#{key}"] = (value)->
            offsetTime = @timezoneOffset * 60 * 1000
            offsetDate = new Date(@getTime() - offsetTime)
            offsetDate["setUTC#{key}"](value)
            time = offsetDate.getTime() + offsetTime
            @setTime(time)
            return time
    
    0 讨论(0)
  • 2020-11-22 02:11

    GMT -03:00 Example

    new Date(new Date()-3600*1000*3).toISOString();  // 2020-02-27T15:03:26.261Z
    

    Or even

    now  = new Date().getTime()-3600*1000*3; // 1582818380528
    data = new Date(now).toISOString();      // 2020-02-27T15:03:26.261Z
    
    0 讨论(0)
  • 2020-11-22 02:13

    Simply Set the Time Zone and Get Back According

    new Date().toLocaleString("en-US", {timeZone: "America/New_York"})
    

    Other Time-zones are as Following

    var world_timezones =
    [
        'Europe/Andorra',
        'Asia/Dubai',
        'Asia/Kabul',
        'Europe/Tirane',
        'Asia/Yerevan',
        'Antarctica/Casey',
        'Antarctica/Davis',
        'Antarctica/DumontDUrville', 
        'Antarctica/Mawson',
        'Antarctica/Palmer',
        'Antarctica/Rothera',
        'Antarctica/Syowa',
        'Antarctica/Troll',
        'Antarctica/Vostok',
        'America/Argentina/Buenos_Aires',
        'America/Argentina/Cordoba',
        'America/Argentina/Salta',
        'America/Argentina/Jujuy',
        'America/Argentina/Tucuman',
        'America/Argentina/Catamarca',
        'America/Argentina/La_Rioja',
        'America/Argentina/San_Juan',
        'America/Argentina/Mendoza',
        'America/Argentina/San_Luis',
        'America/Argentina/Rio_Gallegos',
        'America/Argentina/Ushuaia',
        'Pacific/Pago_Pago',
        'Europe/Vienna',
        'Australia/Lord_Howe',
        'Antarctica/Macquarie',
        'Australia/Hobart',
        'Australia/Currie',
        'Australia/Melbourne',
        'Australia/Sydney',
        'Australia/Broken_Hill',
        'Australia/Brisbane',
        'Australia/Lindeman',
        'Australia/Adelaide',
        'Australia/Darwin',
        'Australia/Perth',
        'Australia/Eucla',
        'Asia/Baku',
        'America/Barbados',
        'Asia/Dhaka',
        'Europe/Brussels',
        'Europe/Sofia',
        'Atlantic/Bermuda',
        'Asia/Brunei',
        'America/La_Paz',
        'America/Noronha',
        'America/Belem',
        'America/Fortaleza',
        'America/Recife',
        'America/Araguaina',
        'America/Maceio',
        'America/Bahia',
        'America/Sao_Paulo',
        'America/Campo_Grande',
        'America/Cuiaba',
        'America/Santarem',
        'America/Porto_Velho',
        'America/Boa_Vista',
        'America/Manaus',
        'America/Eirunepe',
        'America/Rio_Branco',
        'America/Nassau',
        'Asia/Thimphu',
        'Europe/Minsk',
        'America/Belize',
        'America/St_Johns',
        'America/Halifax',
        'America/Glace_Bay',
        'America/Moncton',
        'America/Goose_Bay',
        'America/Blanc-Sablon',
        'America/Toronto',
        'America/Nipigon',
        'America/Thunder_Bay',
        'America/Iqaluit',
        'America/Pangnirtung',
        'America/Atikokan',
        'America/Winnipeg',
        'America/Rainy_River',
        'America/Resolute',
        'America/Rankin_Inlet',
        'America/Regina',
        'America/Swift_Current',
        'America/Edmonton',
        'America/Cambridge_Bay',
        'America/Yellowknife',
        'America/Inuvik',
        'America/Creston',
        'America/Dawson_Creek',
        'America/Fort_Nelson',
        'America/Vancouver',
        'America/Whitehorse',
        'America/Dawson',
        'Indian/Cocos',
        'Europe/Zurich',
        'Africa/Abidjan',
        'Pacific/Rarotonga',
        'America/Santiago',
        'America/Punta_Arenas',
        'Pacific/Easter',
        'Asia/Shanghai',
        'Asia/Urumqi',
        'America/Bogota',
        'America/Costa_Rica',
        'America/Havana',
        'Atlantic/Cape_Verde',
        'America/Curacao',
        'Indian/Christmas',
        'Asia/Nicosia',
        'Asia/Famagusta',
        'Europe/Prague',
        'Europe/Berlin',
        'Europe/Copenhagen',
        'America/Santo_Domingo',
        'Africa/Algiers',
        'America/Guayaquil',
        'Pacific/Galapagos',
        'Europe/Tallinn',
        'Africa/Cairo',
        'Africa/El_Aaiun',
        'Europe/Madrid',
        'Africa/Ceuta',
        'Atlantic/Canary',
        'Europe/Helsinki',
        'Pacific/Fiji',
        'Atlantic/Stanley',
        'Pacific/Chuuk',
        'Pacific/Pohnpei',
        'Pacific/Kosrae',
        'Atlantic/Faroe',
        'Europe/Paris',
        'Europe/London',
        'Asia/Tbilisi',
        'America/Cayenne',
        'Africa/Accra',
        'Europe/Gibraltar',
        'America/Godthab',
        'America/Danmarkshavn',
        'America/Scoresbysund',
        'America/Thule',
        'Europe/Athens',
        'Atlantic/South_Georgia',
        'America/Guatemala',
        'Pacific/Guam',
        'Africa/Bissau',
        'America/Guyana',
        'Asia/Hong_Kong',
        'America/Tegucigalpa',
        'America/Port-au-Prince',
        'Europe/Budapest',
        'Asia/Jakarta',
        'Asia/Pontianak',
        'Asia/Makassar',
        'Asia/Jayapura',
        'Europe/Dublin',
        'Asia/Jerusalem',
        'Asia/Kolkata',
        'Indian/Chagos',
        'Asia/Baghdad',
        'Asia/Tehran',
        'Atlantic/Reykjavik',
        'Europe/Rome',
        'America/Jamaica',
        'Asia/Amman',
        'Asia/Tokyo',
        'Africa/Nairobi',
        'Asia/Bishkek',
        'Pacific/Tarawa',
        'Pacific/Enderbury',
        'Pacific/Kiritimati',
        'Asia/Pyongyang',
        'Asia/Seoul',
        'Asia/Almaty',
        'Asia/Qyzylorda',
        'Asia/Qostanay', 
        'Asia/Aqtobe',
        'Asia/Aqtau',
        'Asia/Atyrau',
        'Asia/Oral',
        'Asia/Beirut',
        'Asia/Colombo',
        'Africa/Monrovia',
        'Europe/Vilnius',
        'Europe/Luxembourg',
        'Europe/Riga',
        'Africa/Tripoli',
        'Africa/Casablanca',
        'Europe/Monaco',
        'Europe/Chisinau',
        'Pacific/Majuro',
        'Pacific/Kwajalein',
        'Asia/Yangon',
        'Asia/Ulaanbaatar',
        'Asia/Hovd',
        'Asia/Choibalsan',
        'Asia/Macau',
        'America/Martinique',
        'Europe/Malta',
        'Indian/Mauritius',
        'Indian/Maldives',
        'America/Mexico_City',
        'America/Cancun',
        'America/Merida',
        'America/Monterrey',
        'America/Matamoros',
        'America/Mazatlan',
        'America/Chihuahua',
        'America/Ojinaga',
        'America/Hermosillo',
        'America/Tijuana',
        'America/Bahia_Banderas',
        'Asia/Kuala_Lumpur',
        'Asia/Kuching',
        'Africa/Maputo',
        'Africa/Windhoek',
        'Pacific/Noumea',
        'Pacific/Norfolk',
        'Africa/Lagos',
        'America/Managua',
        'Europe/Amsterdam',
        'Europe/Oslo',
        'Asia/Kathmandu',
        'Pacific/Nauru',
        'Pacific/Niue',
        'Pacific/Auckland',
        'Pacific/Chatham',
        'America/Panama',
        'America/Lima',
        'Pacific/Tahiti',
        'Pacific/Marquesas',
        'Pacific/Gambier',
        'Pacific/Port_Moresby',
        'Pacific/Bougainville',
        'Asia/Manila',
        'Asia/Karachi',
        'Europe/Warsaw',
        'America/Miquelon',
        'Pacific/Pitcairn',
        'America/Puerto_Rico',
        'Asia/Gaza',
        'Asia/Hebron',
        'Europe/Lisbon',
        'Atlantic/Madeira',
        'Atlantic/Azores',
        'Pacific/Palau',
        'America/Asuncion',
        'Asia/Qatar',
        'Indian/Reunion',
        'Europe/Bucharest',
        'Europe/Belgrade',
        'Europe/Kaliningrad',
        'Europe/Moscow',
        'Europe/Simferopol',
        'Europe/Kirov',
        'Europe/Astrakhan',
        'Europe/Volgograd',
        'Europe/Saratov',
        'Europe/Ulyanovsk',
        'Europe/Samara',
        'Asia/Yekaterinburg',
        'Asia/Omsk',
        'Asia/Novosibirsk',
        'Asia/Barnaul',
        'Asia/Tomsk',
        'Asia/Novokuznetsk',
        'Asia/Krasnoyarsk',
        'Asia/Irkutsk',
        'Asia/Chita',
        'Asia/Yakutsk',
        'Asia/Khandyga',
        'Asia/Vladivostok',
        'Asia/Ust-Nera',
        'Asia/Magadan',
        'Asia/Sakhalin',
        'Asia/Srednekolymsk',
        'Asia/Kamchatka',
        'Asia/Anadyr',
        'Asia/Riyadh',
        'Pacific/Guadalcanal',
        'Indian/Mahe',
        'Africa/Khartoum',
        'Europe/Stockholm',
        'Asia/Singapore',
        'America/Paramaribo',
        'Africa/Juba',
        'Africa/Sao_Tome',
        'America/El_Salvador',
        'Asia/Damascus',
        'America/Grand_Turk',
        'Africa/Ndjamena',
        'Indian/Kerguelen',
        'Asia/Bangkok',
        'Asia/Dushanbe',
        'Pacific/Fakaofo',
        'Asia/Dili',
        'Asia/Ashgabat',
        'Africa/Tunis',
        'Pacific/Tongatapu',
        'Europe/Istanbul',
        'America/Port_of_Spain',
        'Pacific/Funafuti',
        'Asia/Taipei',
        'Europe/Kiev',
        'Europe/Uzhgorod',
        'Europe/Zaporozhye',
        'Pacific/Wake',
        'America/New_York',
        'America/Detroit',
        'America/Kentucky/Louisville',
        'America/Kentucky/Monticello',
        'America/Indiana/Indianapolis',
        'America/Indiana/Vincennes',
        'America/Indiana/Winamac',
        'America/Indiana/Marengo',
        'America/Indiana/Petersburg',
        'America/Indiana/Vevay',
        'America/Chicago',
        'America/Indiana/Tell_City',
        'America/Indiana/Knox',
        'America/Menominee',
        'America/North_Dakota/Center',
        'America/North_Dakota/New_Salem',
        'America/North_Dakota/Beulah',
        'America/Denver',
        'America/Boise',
        'America/Phoenix',
        'America/Los_Angeles',
        'America/Anchorage',
        'America/Juneau',
        'America/Sitka',
        'America/Metlakatla',
        'America/Yakutat',
        'America/Nome',
        'America/Adak',
        'Pacific/Honolulu',
        'America/Montevideo',
        'Asia/Samarkand',
        'Asia/Tashkent',
        'America/Caracas',
        'Asia/Ho_Chi_Minh',
        'Pacific/Efate',
        'Pacific/Wallis',
        'Pacific/Apia',
        'Africa/Johannesburg'
    ];
    
    0 讨论(0)
  • 2020-11-22 02:13

    I don't believe this is possible - there is no ability to set the timezone on a Date object after it is created.

    And in a way this makes sense - conceptually (if perhaps not in implementation); per http://en.wikipedia.org/wiki/Unix_timestamp (emphasis mine):

    Unix time, or POSIX time, is a system for describing instants in time, defined as the number of seconds elapsed since midnight Coordinated Universal Time (UTC) of Thursday, January 1, 1970.

    Once you've constructed one it will represent a certain point in "real" time. The time zone is only relevant when you want to convert that abstract time point into a human-readable string.

    Thus it makes sense you would only be able to change the actual time the Date represents in the constructor. Sadly it seems that there is no way to pass in an explicit timezone - and the constructor you are calling (arguably correctly) translates your "local" time variables into GMT when it stores them canonically - so there is no way to use the int, int, int constructor for GMT times.

    On the plus side, it's trivial to just use the constructor that takes a String instead. You don't even have to convert the numeric month into a String (on Firefox at least), so I was hoping a naive implementation would work. However, after trying it out it works successfully in Firefox, Chrome, and Opera but fails in Konqueror ("Invalid Date") , Safari ("Invalid Date") and IE ("NaN"). I suppose you'd just have a lookup array to convert the month to a string, like so:

    var months = [ '', 'January', 'February', ..., 'December'];
    
    function createGMTDate(xiYear, xiMonth, xiDate) {
       return new Date(months[xiMonth] + ' ' + xiDate + ', ' + xiYear + ' 00:00:00 GMT');
    }
    
    0 讨论(0)
  • 2020-11-22 02:15

    This may help someone, put UTC at the end of what you pass in to the new constructor

    At least in chrome you can say var date = new Date("2014-01-01 11:00:00 UTC")

    0 讨论(0)
  • 2020-11-22 02:15

    I was having a similar problem with a date picker. My research led to a very simple solution, without any extra libraries or hardcoded multipliers.

    Key info:

    1. ISO is the Javascript preferred date standard. Assume date utilities will likely return date values in that format.
      • My date picker displays the date in a localized format: mm/dd/yyyy

      • However, it returns the date value in the ISO format: yyyy-mm-dd

        //Select "08/12/2020" in Date Picker date_input 
        
        var input = $('#date_input').val();  //input: 2020-08-12
        
    1. Date.getTimezoneOffset() returns the offset in minutes.

    Examples:

    If you use the default returned date value without modifying the string format, the Date might not get set to your timezone. This can lead to unexpected results.

    var input = $('#date_input').val();  //input: 2020-08-12
    var date = new Date(input);          //This get interpreted as an ISO date, already in UTC
    //date:                             Tue Aug 11 2020 20:00:00 GMT-0400 (Eastern Daylight Time)
    //date.toUTCString():               Wed, 12 Aug 2020 00:00:00 GMT
    //date.toLocaleDateString('en-US'):       8/11/2020
    

    Using a different date string format than the ISO standard yyyy-mm-dd applies your timezone to the Date.

    var date = new Date("08/12/2020");  //This gets interpreted as local timezone
    //date:                             Wed Aug 12 2020 00:00:00 GMT-0400 (Eastern Daylight Time)
    //date.toUTCString():               Wed, 12 Aug 2020 04:00:00 GMT
    //date.toLocaleDateString('en-US'):       8/12/2020
    

    Solution:

    To apply your timezone to the format-agnostic Date without doing string manipulation, use Date.getTimezoneOffset() with Minutes. This works with either original date string format (i.e. UTC dates or localized dates). It provides a consistent result which can then be converted accurately to UTC for storage or interacting with other code.

    var input = $('#date_input').val();
    var date = new Date(input);
    date.setMinutes(date.getMinutes() + date.getTimezoneOffset());
    //date:                             Wed Aug 12 2020 00:00:00 GMT-0400 (Eastern Daylight Time)
    //date.toUTCString():               Wed, 12 Aug 2020 04:00:00 GMT
    //date.toLocaleDateString('en-US'):       8/12/2020
                    
    
    0 讨论(0)
提交回复
热议问题