Tworzenie daty z ustawioną strefą czasową bez użycia reprezentacji łańcuchowej

Mam stronę internetową z trzema rozwijanymi rozwinięciami dla dnia, miesiąca i roku. Jeśli używam konstruktora JavaScript Date, który pobiera liczby, wtedy otrzymuję obiekt Date dla mojej bieżącej strefy czasowej:

new Date(xiYear, xiMonth, xiDate)

Podaj poprawną datę, ale uważa, że data jest GMT + 01: 00 ze względu na czas letni.

Problem polega na tym, że następnie przekazuję to Date do metody Ajax i kiedy Data jest deserializowana na serwerze została przekonwertowana na GMT i tak straciła godzinę, która przesuwa dzień z powrotem o jeden. Teraz mogę po prostu przekazać dzień, miesiąc i rok indywidualnie do metody Ajax, ale wydaje się, że powinien być lepszy sposób.

Przyjęta odpowiedź wskazała mi właściwy kierunek, jednak samo użycie setUTCHours() samo w sobie zmieniło:

Apr 5th 00:00 GMT+01:00 

Do

Apr 4th 23:00 GMT+01:00

Musiałem też ustawić datę, miesiąc i rok UTC, aby zakończyć się

Apr 5th 01:00 GMT+01:00
Tego właśnie chciałem.
Author: Dan, 2009-01-13

19 answers

Używając .setUTCHours() możliwe byłoby ustawienie dat w czasie UTC, co pozwoliłoby na używanie czasu UTC w całym systemie.

nie można go ustawić za pomocą UTC w konstruktorze, chyba że podasz łańcuch daty.

Za pomocą new Date(Date.UTC(year, month, day, hour, minute, second)) można utworzyć obiekt Date z określonego czasu UTC.

 421
Author: jishi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-01 13:40:52
var d = new Date(xiYear, xiMonth, xiDate);
d.setTime( d.getTime() + d.getTimezoneOffset()*60*1000 );

Ta odpowiedź jest dostosowana specjalnie do pierwotnego pytania i nie da odpowiedzi, której koniecznie oczekujesz. W szczególności, niektórzy ludzie będą chcieli odjąć przesunięcie strefy czasowej zamiast dodać go. Pamiętaj jednak, że celem tego rozwiązania jest zhakowanie obiektu javascript date dla konkretnej deserializacji, a nie poprawność we wszystkich przypadkach.

 172
Author: T.W.R. Cole,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-29 18:21:51

Uważam, że potrzebujesz createDateAsUTC funkcji (proszę porównać z 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()); 
}
 135
Author: monsterclub,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-11 15:22:02

Nie wydaje mi się to możliwe - nie ma możliwości ustawienia strefy czasowej w obiekcie Date po jego utworzeniu.

I w pewnym sensie ma to sens - koncepcyjnie (jeśli może nie w implementacji); per http://en.wikipedia.org/wiki/Unix_timestamp (podkreślenie):

Czas Unix (ang. UNIX time, lub POSIX time) - system opisujący momenty w czasie, zdefiniowany jako liczba sekund, które upłynęły od północy Coordinated Universal Time (UTC) z czwartku, stycznia 1, 1970.

Kiedy już je zbudujesz, będzie ono reprezentować pewien punkt w czasie "rzeczywistym". Strefa czasowa ma znaczenie tylko wtedy, gdy chcesz przekonwertować ten abstrakcyjny punkt czasowy na czytelny dla człowieka ciąg znaków.

Ma więc sens, że będziesz mógł zmienić tylko rzeczywisty czas, który reprezentuje data w konstruktorze. Niestety wydaje się, że nie ma sposobu, aby przejść w wyraźnej strefie czasowej - a konstruktor, który dzwonisz (prawdopodobnie poprawnie), tłumaczy twój "lokalny" czas zmienne do GMT, gdy przechowuje je kanonicznie - więc nie ma możliwości użycia konstruktora int, int, int dla czasów GMT.

Z drugiej strony, trywialne jest użycie konstruktora, który pobiera ciąg znaków. Nie trzeba nawet konwertować numerycznego miesiąca na ciąg znaków (przynajmniej na Firefoksie), więc miałem nadzieję, że naiwna implementacja zadziała. Jednak po wypróbowaniu działa pomyślnie w Firefoksie, Chrome i operze, ale nie w Konquerorze ("Invalid Date"), Safari ("Invalid Date") i IE ("NaN"). Domyślam się, że po prostu masz tablicę odnośników do konwersji miesiąca na ciąg znaków, jak TAK:

var months = [ '', 'January', 'February', ..., 'December'];

function createGMTDate(xiYear, xiMonth, xiDate) {
   return new Date(months[xiMonth] + ' ' + xiDate + ', ' + xiYear + ' 00:00:00 GMT');
}
 23
Author: Andrzej Doyle,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-05 21:46:35

Wiem, że to jest stare, ale jeśli to pomoże, możesz użyć chwili i strefy czasowej. Jeśli ich nie widziałeś, Zerknij.

Http://momentjs.com/timezone/

Http://momentjs.com/

Dwie naprawdę poręczne biblioteki manipulacji czasem.

 17
Author: ChewOnThis_Trident,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-13 15:06:59

Jeśli chcesz poradzić sobie z nieco innym, ale pokrewnym, problemem tworzenia obiektu Javascript Date z roku, miesiąca, dnia, ..., łącznie ze strefą czasową – czyli jeśli chcesz parsować ciąg znaków do Daty-to najwyraźniej musisz wykonać irytująco skomplikowany taniec:

// parseISO8601String : string -> Date
// Parse an ISO-8601 date, including possible timezone,
// into a Javascript Date object.
//
// Test strings: parseISO8601String(x).toISOString()
// "2013-01-31T12:34"              -> "2013-01-31T12:34:00.000Z"
// "2013-01-31T12:34:56"           -> "2013-01-31T12:34:56.000Z"
// "2013-01-31T12:34:56.78"        -> "2013-01-31T12:34:56.780Z"
// "2013-01-31T12:34:56.78+0100"   -> "2013-01-31T11:34:56.780Z"
// "2013-01-31T12:34:56.78+0530"   -> "2013-01-31T07:04:56.780Z"
// "2013-01-31T12:34:56.78-0330"   -> "2013-01-31T16:04:56.780Z"
// "2013-01-31T12:34:56-0330"      -> "2013-01-31T16:04:56.000Z"
// "2013-01-31T12:34:56Z"          -> "2013-01-31T12:34:56.000Z"
function parseISO8601String(dateString) {
    var timebits = /^([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}):([0-9]{2})(?::([0-9]*)(\.[0-9]*)?)?(?:([+-])([0-9]{2})([0-9]{2}))?/;
    var m = timebits.exec(dateString);
    var resultDate;
    if (m) {
        var utcdate = Date.UTC(parseInt(m[1]),
                               parseInt(m[2])-1, // months are zero-offset (!)
                               parseInt(m[3]),
                               parseInt(m[4]), parseInt(m[5]), // hh:mm
                               (m[6] && parseInt(m[6]) || 0),  // optional seconds
                               (m[7] && parseFloat(m[7])*1000) || 0); // optional fraction
        // utcdate is milliseconds since the epoch
        if (m[9] && m[10]) {
            var offsetMinutes = parseInt(m[9]) * 60 + parseInt(m[10]);
            utcdate += (m[8] === '+' ? -1 : +1) * offsetMinutes * 60000;
        }
        resultDate = new Date(utcdate);
    } else {
        resultDate = null;
    }
    return resultDate;
}

Oznacza to, że tworzysz "czas UTC", używając daty bez strefy czasowej (więc wiesz, w jakim ustawieniu jest, a mianowicie "ustawienia regionalne" UTC i nie jest domyślne dla lokalnego), a następnie ręcznie zastosuj wskazane przesunięcie strefy czasowej.

Czy nie byłoby miło, gdyby ktoś rzeczywiście myślał o obiekcie Javascript date dłużej niż, oooh, pięć minut....

 16
Author: Norman Gray,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-31 22:36:45
d = new Date();
utc = d.getTime() + (d.getTimezoneOffset() * 60000);
nd = new Date(utc + (3600000*offset));

offset value base on which location time zone you would like to set 
For India offset value +5.5,
New York offset value -4,
London offset value +1

For all location offset Wiki List of UTC time offsets

 11
Author: Vijay Lathiya,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-10 14:10:16

One line solution

new Date(new Date(1422524805305).getTime() - 330*60*1000)

Zamiast 1422524805305 użyj znacznika czasu w milisekundach Zamiast 330 użyj przesunięcia strefy czasowej w minutach wrt. GMT (np. Indie +5: 30 jest 5*60+30 = 330 minut)

 9
Author: Vinay Vemula,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-29 09:56:02

GetTimeZoneOffset jest minus dla UTC + z.

var d = new Date(xiYear, xiMonth, xiDate);
if(d.getTimezoneOffset() > 0){
    d.setTime( d.getTime() + d.getTimezoneOffset()*60*1000 );
}
 7
Author: rinjan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-31 15:18:26

To może komuś pomóc, umieść UTC na końcu tego, co PRZEKAZUJESZ do nowego konstruktora

Przynajmniej w chrome można powiedzieć var date = new Date("2014-01-01 11:00:00 UTC")

 7
Author: Drew LeSueur,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-28 14:39:54

Najprostszym sposobem, jaki znalazłem, aby uzyskać poprawną datę, jest użycie datejs.

Http://www.datejs.com/

Dostaję moje daty przez Ajax w tym formacie jako ciąg znaków: '2016-01-12t00:00: 00'

var yourDateString = '2016-01-12T00:00:00';
var yourDate = new Date(yourDateString);
console.log(yourDate);
if (yourDate.getTimezoneOffset() > 0){
    yourDate = new Date(yourDateString).addMinutes(yourDate.getTimezoneOffset());
}
console.log(yourDate);

Konsola będzie czytać:

2016-11-16 19: 00: 00 GMT-0500 (Eastern Standard Time) W dniu 12 stycznia 2016 00: 00: 00 GMT-0500 (Eastern Standard Time)

Https://jsfiddle.net/vp1ena7b/3/

'addMinutes' pochodzi z datejs, można prawdopodobnie zrobić to w czystym js na własną rękę, ale miałem już datejs w moim projekcie, więc znalazłem sposób, aby go użyć, aby uzyskać poprawne daty.

Myślałam, że to może komuś pomóc...
 5
Author: Barry Franklin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-05 13:11:19

Dowolny przebieg w

var d = new Date(xiYear, xiMonth, xiDate).toLocaleString();
 2
Author: meouw,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-13 17:11:39

Ten kod zwróci obiekt Date sformatowany za pomocą strefy czasowej przeglądarki.

Date.prototype.timezone = function () {
    this.setHours(this.getHours() + (new Date().getTimezoneOffset() / 60));
    return this;
}
 2
Author: Marco Dal Zovo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-25 16:27:32
// 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)
 2
Author: Tuan Nguyen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-25 02:40:21

Najlepsze rozwiązanie jakie widziałem z tego pochodzi

Http://www.codingforums.com/archive/index.php/t-19663.html

Funkcja Czasu Wydruku

<script language="javascript" type="text/javascript">
//borrowed from echoecho
//http://www.echoecho.com/ubb/viewthread.php?tid=2362&pid=10482&#pid10482
workDate = new Date()
UTCDate = new Date()
UTCDate.setTime(workDate.getTime()+workDate.getTimezoneOffset()*60000)

function printTime(offset) {
    offset++;
    tempDate = new Date()
    tempDate.setTime(UTCDate.getTime()+3600000*(offset))
    timeValue = ((tempDate.getHours()<10) ? ("0"+tempDate.getHours()) : (""+tempDate.getHours()))
    timeValue += ((tempDate.getMinutes()<10) ? ("0"+tempDate.getMinutes()) : tempDate.getMinutes())
    timeValue += " hrs."
    return timeValue
    }
    var now = new Date()
    var seed = now.getTime() % 0xfffffff
    var same = rand(12)
</script>

Banff, Canada:
<script language="JavaScript">document.write(printTime("-7"))</script>

Przykład Pełnego Kodu

<html>

<head>
<script language="javascript" type="text/javascript">
//borrowed from echoecho
//http://www.echoecho.com/ubb/viewthread.php?tid=2362&pid=10482&#pid10482
workDate = new Date()
UTCDate = new Date()
UTCDate.setTime(workDate.getTime()+workDate.getTimezoneOffset()*60000)

function printTime(offset) {
offset++;
tempDate = new Date()
tempDate.setTime(UTCDate.getTime()+3600000*(offset))
timeValue = ((tempDate.getHours()<10) ? ("0"+tempDate.getHours()) : (""+tempDate.getHours()))
timeValue += ((tempDate.getMinutes()<10) ? ("0"+tempDate.getMinutes()) : tempDate.getMinutes())
timeValue += " hrs."
return timeValue
}
var now = new Date()
var seed = now.getTime() % 0xfffffff
var same = rand(12)
</script>

</head>

<body>
Banff, Canada:
<script language="JavaScript">document.write(printTime("-7"))</script>
<br>
Michigan:
<script language="JavaScript">document.write(printTime("-5"))</script>
<br>
Greenwich, England(UTC):
<script language="JavaScript">document.write(printTime("-0"))</script>
<br>
Tokyo, Japan:
<script language="JavaScript">document.write(printTime("+9"))</script>
<br>
Berlin, Germany:
<script language="JavaScript">document.write(printTime("+1"))</script>

</body>
</html>
 1
Author: Jeffrey L. Roberts,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-17 17:13:02

Znalazłem sposób, który dla wszystkich celów działa....

//get your time/date
let a = new Date();
//convert it to another time zone, but it's in string format
let b = a.toLocaleString('en-US', { timeZone: 'Asia/Seoul' });
//now convert string to date object again
let c = new Date(b);
//just grab whatever you were looking for
c.toLocaleString('en-US', { hour: 'numeric', minute: 'numeric', hour12: true });
c.getHours() // you can do comparison of hours if you want
 0
Author: Muhammad Umer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-14 17:11:31

Użyłem pakietu timezone-js.

var timezoneJS  = require('timezone-js');
var tzdata = require('tzdata');

: :

createDate(dateObj) {
    if ( dateObj == null ) {
        return null;
    }
    var nativeTimezoneOffset = new Date().getTimezoneOffset();
    var offset = this.getTimeZoneOffset();

    // use the native Date object if the timezone matches
    if ( offset == -1 * nativeTimezoneOffset ) {
        return dateObj;
    }

    this.loadTimeZones();

    // FIXME: it would be better if timezoneJS.Date was an instanceof of Date
    //        tried jquery $.extend
    //        added hack to Fiterpickr to look for Dater.getTime instead of "d instanceof Date"
    return new timezoneJS.Date(dateObj,this.getTimeZoneName());
},
 -1
Author: Stephen Ince,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-31 16:02:58

To mi pomogło. Nie jestem pewien, czy to dobry pomysł.

var myDate = new Date();
console.log('myDate:', myDate);   // myDate: "2018-04-04T01:09:38.112Z"

var offset = '+5';  // e.g. if the timeZone is -5

var MyDateWithOffset = new Date( myDate.toGMTString() + offset );   

console.log('MyDateWithOffset:', MyDateWithOffset); // myDateWithOffset: "2018-04-03T20:09:38.000Z"
 -1
Author: ofmoreno06,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-04 01:57:28

To jest najlepsze rozwiązanie

Użycie:

// TO ALL dates
Date.timezoneOffset(-240) // +4 UTC

// Override offset only for THIS date
new Date().timezoneOffset(-180) // +3 UTC

Kod:

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

Wersja kawowa:

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
 -7
Author: Maxmaxmaximus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-24 05:43:40