Create a Date with a set timezone without using a

2018-12-31 05:29发布

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 object for my current timezone:

new Date(xiYear, xiMonth, xiDate)

Give the correct date, but it thinks that date is GMT+01:00 due to daylight savings time.

The problem here is that I then pass this Date to an Ajax method and when the date is deserialised on the server it has been converted to GMT and so lost an hour which moves the day back by one. Now I could just pass the day, month, and year individually into the Ajax method, but it seems that there ought to be a better way.

The accepted answer pointed me in the right direction, however just using setUTCHours() by itself changed:

Apr 5th 00:00 GMT+01:00 

to

Apr 4th 23:00 GMT+01:00

I then also had to set the UTC date, month and year to end up with

Apr 5th 01:00 GMT+01:00

which is what I wanted.

18条回答
情到深处是孤独
2楼-- · 2018-12-31 06:00

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
查看更多
冷夜・残月
3楼-- · 2018-12-31 06:01
// My clock 2018-07-25, 00:26:00 (GMT+7)
let date = new Date(); // 2018-07-24:17:26:00 (Look like GMT+0)
const myTimeZone = 7; // my timeZone 
// my timeZone = 7h = 7 * 60 * 60 * 1000 (millisecond);
// 2018-07-24:17:26:00 = x (milliseconds)
// finally, time in milliseconds (GMT+7) = x + myTimezone 
date.setTime( date.getTime() + myTimeZone * 60 * 60 * 1000 );
// date.toISOString() = 2018-07-25, 00:26:00 (GMT+7)
查看更多
荒废的爱情
4楼-- · 2018-12-31 06:02

I know this is old but if it helps you could use moment and moment time zone. If you haven't seen them take a look.

http://momentjs.com/timezone/

http://momentjs.com/

two really handy time manipulation libraries.

查看更多
无与为乐者.
5楼-- · 2018-12-31 06:03

I believe you need the createDateAsUTC function (please compare with convertDateToUTC)

function createDateAsUTC(date) {
    return new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds()));
}

function convertDateToUTC(date) { 
    return new Date(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds()); 
}
查看更多
梦醉为红颜
6楼-- · 2018-12-31 06:04

any mileage in

var d = new Date(xiYear, xiMonth, xiDate).toLocaleString();
查看更多
裙下三千臣
7楼-- · 2018-12-31 06:06

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")

查看更多
登录 后发表回答