Erstellen Sie ein Datum mit einer festgelegten Zeitzone, ohne eine Zeichenfolgendarstellung zu verwenden

412

Ich habe eine Webseite mit drei Dropdowns für Tag, Monat und Jahr. Wenn ich den JavaScript- DateKonstruktor verwende, der Zahlen akzeptiert, erhalte ich ein DateObjekt für meine aktuelle Zeitzone:

new Date(xiYear, xiMonth, xiDate)

Geben Sie das richtige Datum an, aber es wird angenommen, dass das Datum aufgrund der Sommerzeit GMT + 01: 00 ist.

Das Problem hierbei ist, dass ich dies dann Datean eine Ajax-Methode übergebe. Wenn das Datum auf dem Server deserialisiert wird, wurde es in GMT konvertiert und hat so eine Stunde verloren, die den Tag um eins zurückversetzt. Jetzt könnte ich Tag, Monat und Jahr einzeln in die Ajax-Methode übergehen, aber es scheint, dass es einen besseren Weg geben sollte.

Die akzeptierte Antwort wies mich in die richtige Richtung, aber die Verwendung setUTCHours()allein änderte sich:

Apr 5th 00:00 GMT+01:00 

zu

Apr 4th 23:00 GMT+01:00

Ich musste dann auch das UTC-Datum, den Monat und das Jahr einstellen, um am Ende zu landen

Apr 5th 01:00 GMT+01:00

Welches ist, was ich wollte.

Dan
quelle
9
Wenn die akzeptierte Antwort Sie in die richtige Richtung wies, aber Ihre Frage nicht beantwortete, würde ich argumentieren, dass dies nicht die akzeptierte Antwort sein sollte. Die Antwort sollte die gestellte Frage beantworten.
TWR Cole

Antworten:

481

Mit .setUTCHours()dieser Funktion können Datumsangaben tatsächlich in UTC-Zeit festgelegt werden, sodass Sie UTC-Zeiten im gesamten System verwenden können.

Sie können es jedoch nicht mit UTC im Konstruktor festlegen, es sei denn, Sie geben eine Datumszeichenfolge an.

Mit können new Date(Date.UTC(year, month, day, hour, minute, second))Sie ein Datumsobjekt aus einer bestimmten UTC-Zeit erstellen.

Jishi
quelle
101
Die „new Date (Date.UTC (...))“ Syntax ermöglicht es Ihnen , ein Datum zu schaffen , das ist äquivalent zu einem UTC - Datum in Bezug auf den Zeitpunkt , die es darstellt, aber es ist nicht das gleiche - es ist eine hat andere Zeitzone (nicht UTC).
Anthony
51
Beachten Sie, dass bei Verwendung von "Datum" der "Monat" -Wert zwischen 0 und 11 liegt (nicht zwischen 1 und 12). Ich bekam immer wieder einen Zeitzonenversatz von 2 Stunden (während es 1 Stunde hätte sein sollen) und ich brauchte Stunden, um herauszufinden, dass der Grund ein falscher Monat war.
Select0r
4
Diese Antwort ist großartig. Aber ich benutze eine Bibliothek [datepicker ui], die an vielen Stellen ein neues Datum verwendet. Ich möchte nur die UTC-Zeitzone einstellen und jedes Datum entspricht der neuen Zeitzone. Ich bin überrascht, dass Javascript nichts dafür hat.
Sanjeev Kumar Dangi
6
@ jishi - Datumsobjekte basieren auf einem UTC-Zeitwert und nicht auf der Ortszeit. Allerdings ist die Standard - Date.prototype.toString wird Methode angezeigt werden lokale Zeitwerte.
RobG
5
@ Anthony - " aber es ist nicht die gleiche Zeit " ist nicht korrekt. Es repräsentiert genau den gleichen Zeitpunkt, der einzige Unterschied ist der Zeitzonenversatz.
RobG
198
var d = new Date(xiYear, xiMonth, xiDate);
d.setTime( d.getTime() + d.getTimezoneOffset()*60*1000 );

Diese Antwort ist speziell auf die ursprüngliche Frage zugeschnitten und gibt nicht die Antwort, die Sie unbedingt erwarten. Insbesondere möchten einige Leute den Zeitzonenversatz subtrahieren, anstatt ihn hinzuzufügen. Denken Sie jedoch daran, dass der springende Punkt dieser Lösung darin besteht, das Datumsobjekt von Javascript für eine bestimmte Deserialisierung zu hacken, um nicht in allen Fällen korrekt zu sein.

TWR Cole
quelle
62
@gthmb natürlich, aber ich denke, das *60*1000ist in diesem Fall klarer; Mit anderen Worten, es ist ziemlich selbstverständlich, warum es dort ist.
TWR Cole
22
Dies funktioniert fast für mich, außer dass ich - (minus) anstelle von + (plus) verwenden muss, um die richtige Zeit für meine Zeitzone zu erhalten.
Wytze
3
Ja, wie andere betont haben - ich denke, diese Antwort enthält einen Fehler. Sollte minus nicht plus sein.
UpTheCreek
3
Laut developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… wird der von getTimezoneOffset zurückgegebene Wert entsprechend dem tatsächlichen Versatz in Ihrem Gebietsschema zum Zeitpunkt des Aufrufs der Funktion signiert, einschließlich der Berücksichtigung der Sommerzeit. Ich verstehe also nicht, warum Sie es subtrahieren müssen.
TWR Cole
15
Wenn Sie das timezoneOffset zum Datumsobjekt hinzufügen, sieht der in der lokalen Zeitzone formatierte Wert wie der korrekte Wert in UTC aus, hat jedoch weiterhin den ursprünglichen Zeitzonenversatz (und einige Darstellungen wie "ISOString" zeigen ihn tatsächlich an). Abhängig davon, wie Sie das Datumsobjekt dann serialisieren, wendet JS möglicherweise den Zeitzonenversatz erneut an und gibt Ihnen die falsche Antwort. Ich glaube, dies ist verantwortlich für die Verwirrung in diesen Kommentaren zwischen +/-. Wie auch immer, meine Ablehnung ist für diese Tatsache und auch für die "in den meisten Fällen bekommen Sie, was Sie erwarten".
Metamatt
173

Ich glaube, Sie brauchen die Funktion createDateAsUTC (bitte vergleichen Sie mit 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()); 
}
Monsterclub
quelle
36
Ich bin erstaunt über seine klare und hilfreiche Antwort. Wusste nicht, dass die Arbeit mit Javascript-Daten bis heute so ein Albtraum war: S
will824
Möchtest du den Unterschied zwischen den beiden erklären? Der erste konvertiert datein die UTC-Zeitzone, aber der zweite scheint nichts Nützliches zu tun? (gibt das gleiche Datum zurück wie date)
Jonathan Lin
4
Ich verstehe es jetzt: Der erste gibt das Datum in der UTC-Zeitzone mit den wörtlichen Datumswerten der Ortszeit zurück. Die Sekunde gibt das Datum in der lokalen Zeitzone zurück, jedoch mit den UTC-Literal-Datumswerten.
Jonathan Lin
8
Dieser Ansatz ist eine Implementierung eines Musters, das als "Epochenverschiebung" bezeichnet wird und das die Epoche (dh UTC-basiert) auf eine verschieben soll, die um den aktuellen Zeitzonenversatz verschoben ist. Leider ist dieser Ansatz fehlerhaft, obwohl dies häufig gesehen wird. Das JavaScript- DateObjekt spiegelt immer die UTC-basierte Unix-Epoche und die lokale Zeitzone wider . Das Symptom tritt auf, wenn Sie toStringdas resultierende Datumsobjekt aufrufen und trotzdem die lokale Zeitzone sehen, obwohl Sie erwartet haben, dass sie in UTC vorliegt.
Matt Johnson-Pint
2
Es kann auch Fehler in den Zeitwerten in der Nähe der Sommerzeitübergänge der lokalen Zeitzone verursachen. Kurz gesagt, Epochenverschiebung (über eine beliebige Implementierung) funktioniert nicht mit dem JavaScript- DateObjekt. Eine andere Möglichkeit, dies hier zu sehen, besteht darin, Date.UTCUTC-basierte Werte zu erwarten und diese lokalen Zeitwerte einzugeben und umgekehrt mit dem DateKonstruktor.
Matt Johnson-Pint
70

Stellen Sie einfach die Zeitzone ein und kehren Sie entsprechend zurück

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

Andere Zeitzonen sind wie folgt

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'
];
Matee Gojra
quelle
8
Dies sollte ganz oben sein
Eugene
Beachten Sie jedoch, dass dies in einigen Browsern nicht funktioniert. Z.B. IE11.
Paul LeBeau
Fehler in der IE-Konsole: Der Optionswert 'AMERICA / NEW_YORK' für 'timeZone' liegt außerhalb des gültigen Bereichs. Erwartet: ['UTC'] @OloghoCyrilPaul
Matee Gojra
1
Sehr einfach, sehr elegant. Hier finden Sie eine Liste mit allen Zeitzonen stackoverflow.com/questions/38399465/… . Für UTC wählen Sie die Zeitzone London.
EPurpl3
1
Keiner dieser Werte ist eine "Zeitzone". Es handelt sich um repräsentative Standorte der IANA-Zeitzonendatenbank für Orte mit denselben historischen lokalen Zeitzonen- und Sommerzeitänderungen.
RobG
28

Ich glaube nicht, dass dies möglich ist - es gibt keine Möglichkeit, die Zeitzone für ein Datumsobjekt festzulegen, nachdem es erstellt wurde.

Und in gewisser Weise macht dies Sinn - konzeptionell (wenn vielleicht nicht in der Umsetzung); per http://en.wikipedia.org/wiki/Unix_timestamp (Schwerpunkt Mine):

Die Unix-Zeit oder POSIX-Zeit ist ein System zur Beschreibung von Zeitpunkten, definiert als die Anzahl der Sekunden, die seit Mitternacht der koordinierten Weltzeit (UTC) vom Donnerstag, dem 1. Januar 1970, vergangen sind .

Sobald Sie eine erstellt haben, wird sie einen bestimmten Punkt in "Echtzeit" darstellen. Die Zeitzone ist nur relevant, wenn Sie diesen abstrakten Zeitpunkt in eine für Menschen lesbare Zeichenfolge konvertieren möchten.

Daher ist es sinnvoll, dass Sie nur die tatsächliche Zeit ändern können, die das Datum im Konstruktor darstellt. Leider scheint es keine Möglichkeit zu geben, eine explizite Zeitzone zu übergeben - und der Konstruktor, den Sie aufrufen (wohl richtig), übersetzt Ihre "lokalen" Zeitvariablen in GMT, wenn er sie kanonisch speichert - daher gibt es keine Möglichkeit, die zu verwendenint, int, int Konstruktor für zu verwenden GMT-Zeiten.

Auf der positiven Seite ist es trivial, nur den Konstruktor zu verwenden, der stattdessen einen String verwendet. Sie müssen nicht einmal den numerischen Monat in einen String konvertieren (zumindest in Firefox), also hatte ich gehofft, dass eine naive Implementierung funktionieren würde. Nach dem Ausprobieren funktioniert es jedoch erfolgreich in Firefox, Chrome und Opera, schlägt jedoch in Konqueror ("Ungültiges Datum"), Safari ("Ungültiges Datum") und IE ("NaN") fehl. Ich nehme an, Sie hätten nur ein Sucharray, um den Monat in eine Zeichenfolge umzuwandeln, wie folgt:

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

function createGMTDate(xiYear, xiMonth, xiDate) {
   return new Date(months[xiMonth] + ' ' + xiDate + ', ' + xiYear + ' 00:00:00 GMT');
}
Andrzej Doyle
quelle
6
Wenn es keine Möglichkeit gibt, "die Zeitzone für ein Datumsobjekt nach seiner Erstellung festzulegen", implizieren Sie, dass es eine Möglichkeit gibt, die Zeitzone für ein Datumsobjekt während der Erstellung festzulegen ? Es sieht nicht so aus, als wäre ein js-Datum "ein dünner Wrapper um einige Sekunden seit der Epoche" - es sieht so aus, als würde es die Anzahl der Sekunden plus eine Zeitzone sein.
Anthony
1
@Anthony, Es kann nur die Zeitzone des Clients verwendet werden. Javascript kann lokal mit utc und zurück arbeiten, es gibt jedoch keinen Zugriff auf eine Zeitzonendatenbank. Es kann Ihnen beispielsweise nicht die Zeit in Mexiko-Stadt anzeigen, wenn Sie in San Diego sind.
Samuel Danielson
20

Ich weiß, dass dies alt ist, aber wenn es hilft, können Sie Moment und Moment Zeitzone verwenden. Wenn Sie sie nicht gesehen haben, schauen Sie sie sich an.

http://momentjs.com/timezone/

http://momentjs.com/

zwei wirklich praktische Zeitmanipulationsbibliotheken.

ChewOnThis_Trident
quelle
16

Wenn Sie sich mit dem etwas anderen, aber verwandten Problem befassen möchten, ein Javascript-Datumsobjekt aus Jahr, Monat, Tag, ... einschließlich Zeitzone zu erstellen, dh wenn Sie eine Zeichenfolge in ein Datum analysieren möchten, dann sind Sie es müssen anscheinend einen ärgerlich komplizierten Tanz machen:

// 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;
}

Das heißt, Sie erstellen eine 'UTC-Zeit' unter Verwendung des Datums ohne Zeitzone (damit Sie wissen, in welchem ​​Gebietsschema es sich befindet, nämlich im UTC-Gebietsschema, und es ist nicht standardmäßig das lokale Gebietsschema), und wenden dann manuell den angegebenen Zeitzonenversatz an.

Wäre es nicht schön gewesen , wenn jemand tatsächlich hatte gedacht , über das Javascript Date - Objekt für mehr als, oooh, 5 Minuten ....

Norman Gray
quelle
1
danke für die tolle funktion! Das einzige, was ich ändern würde, ist die Unterstützung für den Doppelpunkt im Zeitzonenversatz hinzuzufügen. 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}))? /;
Robnardo
2
Sie haben darüber nachgedacht; Leider waren die "sie" die Java-Sprachdesigner, da JS gerade die Date-Klasse von Java für die anfängliche Implementierung kopiert hat.
Xanthir
@ Xanthir Oooh, Sie haben Recht, und ich hatte vergessen, wie schrecklich das ursprüngliche Java Date-Objekt war. Aber zumindest Java hat es abgelehnt und ist weitergegangen, was Javascript anscheinend nicht kann (es ist eine bizarre Sprache, Javascript: ziemlich niedlich und bei weitem nicht so schrecklich, wie es zunächst scheint).
Norman Gray
13
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

für alle Standortversätze Wiki Liste der UTC- Zeitversätze

Vijay Lathiya
quelle
Wie hilft dies New York während der Sommerzeit?
Frederick
Für New York verwenden Sie bitte den Versatzwert -4
Vijay Lathiya
1
Der Versatz für New York variiert je nach Sommerzeit. Manchmal ist es -4 und manchmal ist es -5 en.wikipedia.org/wiki/Eastern_Time_Zone
frederj
8

getTimeZoneOffset ist für UTC + z minus.

var d = new Date(xiYear, xiMonth, xiDate);
if(d.getTimezoneOffset() > 0){
    d.setTime( d.getTime() + d.getTimezoneOffset()*60*1000 );
}
Rinjan
quelle
1
Ein kleiner Fehler! = 0 nicht> 0.
Am
8

Dies kann jemandem helfen, UTC an das Ende dessen zu setzen, was Sie an den neuen Konstruktor übergeben

Zumindest in Chrom kann man sagen var date = new Date("2014-01-01 11:00:00 UTC")

Drew LeSueur
quelle
1
Gibt "Ungültiges Datum" auf Safari zurück
pmrotule
1
Ersetzen Sie "UTC" durch +0000( beachten Sie, dass der Abstand zwischen 00 und UTC entfernt werden muss), und dies funktioniert sowohl in Firefox als auch in Chrome. Ich bin mir jedoch nicht sicher für Safari. (Referenz: stackoverflow.com/a/17545854/1273587 )
Cytsunny
8

Einzeilige Lösung

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

Verwenden Sie anstelle von 1422524805305 den Zeitstempel in Millisekunden. Verwenden Sie anstelle von 330 Ihren Zeitzonenversatz in Minuten. GMT (zB Indien +5: 30 ist 5 * 60 + 30 = 330 Minuten)

Vinay Vemula
quelle
4
Dies wäre Code, der auf dem Client ausgeführt wird, was bedeutet, dass die Zeitzone für Ihre Benutzer mit unterschiedlichen Standorten unterschiedlich sein wird. Diese Lösung würde erfordern, dass jeder, der sie benötigt, in derselben Zeitzone lebt (Ihre).
Kevin Beal
@ Kevin Beal in diesem Fall verwenden Sie einfach getTimezoneOffset
maximus
6
// 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)
Tuan Nguyen
quelle
Wenn Sie Ihren Code erläutern und erläutern, wie er das Problem löst, wird die Qualität Ihrer Antwort verbessert und das Lernen der Benutzer erleichtert.
Nic3500
5

Der einfachste Weg, das richtige Datum zu finden, ist die Verwendung von datejs.

http://www.datejs.com/

Ich erhalte meine Daten über Ajax in diesem Format als Zeichenfolge: '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);

Die Konsole lautet:

Montag, 11. Januar 2016, 19:00:00 GMT-0500 (Eastern Standard Time)

Di Jan 12 2016 00:00:00 GMT-0500 (Eastern Standard Time)

https://jsfiddle.net/vp1ena7b/3/

Die 'addMinutes' stammen von datejs. Sie können dies wahrscheinlich in reinen js selbst tun, aber ich hatte bereits datejs in meinem Projekt, sodass ich einen Weg gefunden habe, damit die richtigen Daten zu erhalten.

Ich dachte, das könnte jemandem helfen ...

Barry Franklin
quelle
Versuchte alle Methoden und dies war die einzige, die Mitternacht bekam, was ich suchte!
SharpC
3

jeder Kilometerstand in

var d = new Date(xiYear, xiMonth, xiDate).toLocaleString();
meouw
quelle
Dies scheint der Trick für mich zu sein (eine Zeitzone von GMT entfernt), aber da "Gebietsschema" nicht unbedingt zeitzonenbezogen ist, würde ich mich nicht darauf verlassen.
Wytze
3

Dieser Code gibt Ihr Date-Objekt zurück, das mit der Zeitzone des Browsers formatiert ist .

Date.prototype.timezone = function () {
    this.setHours(this.getHours() + (new Date().getTimezoneOffset() / 60));
    return this;
}

Bearbeiten:

Um zu vermeiden, dass die Datums-API verschmutzt wird, kann die obige Funktion in eine Dienstprogrammfunktion umgewandelt werden. Die Funktion nimmt ein Date-Objekt und gibt ein mutiertes Date-Objekt zurück.

function setTimeZone(date) {
    date.setHours(date.getHours() + (new Date().getTimezoneOffset() / 60));
    return date;
}
Marco Dal Zovo
quelle
6
Nein zur Erweiterung einheimischer Objekte
Paul Rumkin
1

Die beste Lösung, die ich daraus gesehen habe, kam von

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

Druckzeitfunktion

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

Vollständiges Codebeispiel

<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>
Jeffrey L. Roberts
quelle
In Ihrem Beispiel ist die Sommerzeit nicht enthalten. Aktuelle Zeit: Fr 04. Oktober 2013 11:13:43 GMT-0700 (Pacific Daylight Time) UtcTime: Fr, 04. Oktober 2013 18:13:43 GMT Banff, Kanada: 1213 Uhr. Michigan: 1413 Stunden. Greenwich, England (UTC): 1913 Stunden. Tokio, Japan: 0413 Uhr Berlin, Deutschland: 2013 Std.
Jeson Martajaya
0

Wenn Sie den Zeitunterschied zwischen zwei Daten überprüfen möchten, können Sie einfach überprüfen, ob die zweite Zeitzone von Ihrer ersten gewünschten Zeitzone kleiner oder größer ist, und eine Zeit subtrahieren oder addieren.

  const currTimezone = new Date().getTimezoneOffset(); // your timezone
  const newDateTimezone = date.getTimezoneOffset(); // date with unknown timezone

  if (currTimezone !== newDateTimezone) {
    // and below you are checking if difference should be - or +. It depends on if unknown timezone is lesser or greater than yours
    const newTimezone = (currTimezone - newDateTimezone) * (currTimezone > newDateTimezone ? 1 : -1);
    date.setTime(date.getTime() + (newTimezone * 60 * 1000));
  }
Piosek
quelle
0

GMT -03: 00 Beispiel

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

Oder auch

now  = new Date().getTime()-3600*1000*3; // 1582818380528
data = new Date(now).toISOString();      // 2020-02-27T15:03:26.261Z
Rafael Xavier
quelle
-1

Das hat bei mir funktioniert. Ich bin mir nicht sicher, ob es eine gute Idee ist.

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"

ofmoreno06
quelle
-1

Ich habe das timezone-js-Paket verwendet.

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());
},
Stephen Ince
quelle
-10

Dies ist die beste Lösung

Verwenden von:

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

Kaffeeversion:

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
Maxmaxmaximus
quelle
2
Wow, ich mag es auch nicht, aber ich denke, die Leute hassen es wirklich , wenn Sie den Prototyp von Builtins überschreiben!
Josh von Qaribou