Crea una data con un fuso orario impostato senza utilizzare una rappresentazione di stringa


412

Ho una pagina web con tre menu a discesa per giorno, mese e anno. Se uso il Datecostruttore JavaScript che accetta numeri, ottengo un Dateoggetto per il mio fuso orario corrente:

new Date(xiYear, xiMonth, xiDate)

Indicare la data corretta, ma si ritiene che la data sia GMT + 01: 00 a causa dell'ora legale.

Il problema qui è che poi lo passo Datea un metodo Ajax e quando la data viene deserializzata sul server, è stata convertita in GMT e quindi ho perso un'ora che sposta il giorno indietro di uno. Ora potrei semplicemente passare il giorno, il mese e l'anno individualmente nel metodo Ajax, ma sembra che dovrebbe esserci un modo migliore.

La risposta accettata mi ha indicato la giusta direzione, tuttavia il solo utilizzo setUTCHours()da solo è cambiato:

Apr 5th 00:00 GMT+01:00 

per

Apr 4th 23:00 GMT+01:00

Ho anche dovuto impostare la data, il mese e l'anno UTC con cui finire

Apr 5th 01:00 GMT+01:00

che è quello che volevo.


9
Se la risposta accettata ti indicasse la giusta direzione ma non rispondesse alla tua domanda, direi che non dovrebbe essere la risposta accettata. La risposta dovrebbe rispondere alla domanda posta.
TWR Cole,

Risposte:


481

usarlo .setUTCHours()sarebbe possibile impostare effettivamente le date in UTC-time, che ti permetterebbe di usare le UTC-times in tutto il sistema.

Tuttavia, non è possibile impostarlo utilizzando UTC nel costruttore, a meno che non si specifichi una stringa di date.

Usando new Date(Date.UTC(year, month, day, hour, minute, second))puoi creare un oggetto Date da un orario UTC specifico.


101
La sintassi "nuova data (Date.UTC (...))" consente di creare una data equivalente a una data UTC in termini di punto nel tempo che rappresenta, ma non è la stessa - ha un fuso orario diverso (non UTC).
Anthony,

52
Tenere presente che quando si utilizza "Data" il valore "mese" ha un intervallo compreso tra 0-11 (non 1-12). Continuavo a ricevere un fuso orario di 2 ore (mentre avrebbe dovuto essere 1 ora) e mi ci sono volute ore per scoprire che il motivo era un mese sbagliato.
Seleziona0r

4
Questa risposta è fantastica Ma sto usando una libreria [datepicker ui] che sta usando la nuova data in molti posti. Tutto quello che voglio è impostare il fuso orario UTC e ogni data è come per il nuovo fuso orario. Sono sorpreso che Javascript non abbia nulla per questo.
Sanjeev Kumar Dangi,

6
@ jishi: gli oggetti data si basano su un valore di ora UTC, non sull'ora locale. Tuttavia, il metodo Date.prototype.toString predefinito visualizzerà i valori dell'ora locale.
RobG,

5
@ Anthony— " ma non è la stessa ora " non è corretto. Rappresenta esattamente lo stesso momento nel tempo, l'unica differenza è l'offset del fuso orario.
RobG

199
var d = new Date(xiYear, xiMonth, xiDate);
d.setTime( d.getTime() + d.getTimezoneOffset()*60*1000 );

Questa risposta è adattata in modo specifico alla domanda originale e non fornirà la risposta che ci si aspetta necessariamente. In particolare, alcune persone vorranno sottrarre l'offset del fuso orario invece di aggiungerlo. Ricorda però che il punto centrale di questa soluzione è hackerare l'oggetto data javascript per una particolare deserializzazione, per non essere corretto in tutti i casi.


62
@gthmb ovviamente, ma ritengo che *60*1000sia più chiaro in questo caso; in altre parole, è abbastanza evidente perché è lì.
TWR Cole

22
Questo funziona quasi per me, tranne per il fatto che devo usare - (meno) anziché + (più) per ottenere l'orario giusto per il mio fuso orario.
Wytze,

3
Sì, come altri hanno sottolineato - Penso che ci sia un errore in questa risposta. Dovrebbe essere meno non più.
UpTheCreek

3
Secondo developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… il valore restituito da getTimezoneOffset è firmato in base all'offset effettivo nella propria lingua locale al momento in cui si chiama la funzione, incluso il prendere in considerazione l'ora legale, quindi non capisco perché dovresti sottrarlo.
TWR Cole,

15
Se aggiungi timezoneOffset all'oggetto data, il suo valore come formattato nel fuso orario locale apparirà come il valore corretto in UTC, ma avrà comunque l'offset del fuso orario originale (e alcune rappresentazioni come "ISOString" lo mostreranno effettivamente). Quindi, a seconda di come quindi serializzare l'oggetto data, JS potrebbe applicare nuovamente l' offset del fuso orario , dandoti la risposta sbagliata. Credo che questo sia responsabile della confusione in questi commenti tra +/-. Comunque, il mio downvote è per questo fatto e anche per "nella maggior parte dei casi ottieni quello che ti aspetti".
Metamatt,

173

Credo che tu abbia bisogno della funzione createDateAsUTC (confronta con 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()); 
}

36
Sono sorpreso della sua risposta chiarezza e disponibilità. Non sapevo che lavorare con le date di Javascript fosse un incubo fino ad oggi: S
will824,

Ti dispiace spiegare la differenza tra i due? Il primo si converte datein fuso orario UTC, ma il secondo sembra non fare nulla di utile? (restituisce la stessa data date)
Jonathan Lin il

4
Ora capisco: il primo restituisce la data nel fuso orario UTC, con i valori letterali della data dell'ora locale. Il secondo restituisce la data nel fuso orario locale, ma con i valori della data letterale UTC.
Jonathan Lin,

8
Questo approccio è un'implementazione di un modello chiamato "spostamento epocale", che ha lo scopo di spostare l'epoca (che è basata su UTC) su una che viene spostata dall'offset del fuso orario corrente. Sfortunatamente, anche se questo è comunemente visto, questo approccio è imperfetto. L' Dateoggetto JavaScript rifletterà sempre l'epoca unix basata su UTC e il fuso orario locale . Il sintomo è evidente quando si chiama toStringl'oggetto data risultante e si continua a vedere il fuso orario locale, anche se ci si aspettava che fosse in UTC.
Matt Johnson-Pint,

2
Può anche causare errori nei valori dell'ora, vicino alle transizioni dell'ora legale del fuso orario locale. In breve, il cambio di epoca (tramite qualsiasi implementazione) non funziona con l' Dateoggetto JavaScript . Un altro modo per vederlo qui è che Date.UTCprevede valori basati su UTC, e tu stai fornendo valori di ora locale e viceversa con il Datecostruttore.
Matt Johnson-Pint,

70

Basta impostare il fuso orario e tornare indietro secondo

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

Altri fusi orari sono i seguenti

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'
];

8
Questo dovrebbe essere il massimo
Eugene il

Tranne essere consapevoli del fatto che questo non funziona in alcuni browser. Per esempio. IE11.
Paul LeBeau,

Errore in IE Console: il valore dell'opzione 'AMERICA / NEW_YORK' per 'timeZone' è al di fuori dell'intervallo valido. Previsto: ['UTC'] @OloghoCyrilPaul
Matee Gojra,

1
Molto facile, molto elegante. Puoi trovare qui un elenco con tutti i fusi orari stackoverflow.com/questions/38399465/… . Per UTC selezionare il fuso orario di Londra.
EPurpl3,

1
Nessuno di questi valori sono "fusi orari", sono posizioni rappresentative del database del fuso orario IANA per i luoghi che hanno lo stesso fuso orario locale e le stesse modifiche dell'ora legale.
RobG,

28

Non credo sia possibile: non è possibile impostare il fuso orario su un oggetto Date dopo che è stato creato.

E in un certo senso questo ha senso - concettualmente (se non forse in attuazione); per http://en.wikipedia.org/wiki/Unix_timestamp (sottolineatura mia):

Il tempo Unix, o tempo POSIX, è un sistema per descrivere gli istanti nel tempo, definito come il numero di secondi trascorsi dalla mezzanotte al tempo universale coordinato (UTC) di giovedì 1 gennaio 1970.

Una volta che ne hai costruito uno, questo rappresenterà un certo punto nel tempo "reale". Il fuso orario è rilevante solo quando si desidera convertire quel punto temporale astratto in una stringa leggibile dall'uomo.

Quindi ha senso che tu possa solo cambiare l'ora effettiva che la Data rappresenta nel costruttore. Purtroppo sembra che non ci sia modo di passare in un fuso orario esplicito - e il costruttore che stai chiamando (probabilmente correttamente) traduce le tue variabili temporali "locali" in GMT quando le memorizza in modo canonico - quindi non c'è modo di usare ilint, int, int costruttore per Orari GMT.

Tra i lati positivi, è banale usare semplicemente il costruttore che prende invece una stringa. Non devi nemmeno convertire il mese numerico in una stringa (almeno su Firefox), quindi speravo che un'implementazione ingenua avrebbe funzionato. Tuttavia, dopo averlo provato, funziona con successo in Firefox, Chrome e Opera ma non riesce in Konqueror ("Data non valida"), Safari ("Data non valida") e IE ("NaN"). Suppongo che avresti solo un array di ricerca per convertire il mese in una stringa, in questo modo:

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

function createGMTDate(xiYear, xiMonth, xiDate) {
   return new Date(months[xiMonth] + ' ' + xiDate + ', ' + xiYear + ' 00:00:00 GMT');
}

6
Se non c'è modo di "impostare il fuso orario su un oggetto Date dopo che è stato creato", stai insinuando che c'è un modo per impostare il fuso orario su un oggetto Date mentre viene creato? Non sembra che una data js sia "un wrapper sottile per un numero di secondi dall'epoca" - sembra che sia quel conteggio dei secondi, più un fuso orario.
Anthony,

1
@Anthony, può usare solo il fuso orario del cliente. Javascript può eseguire localmente in utc e viceversa, ma non è possibile accedere a un database del fuso orario. Ad esempio, non può dirti l'ora di Città del Messico quando sei a San Diego.
Samuel Danielson,


16

Se si desidera affrontare il problema leggermente diverso, ma correlato, della creazione di un oggetto Date Javascript da anno, mese, giorno, ..., incluso il fuso orario , ovvero se si desidera analizzare una stringa in una data, allora si a quanto pare devono fare una danza esasperatamente complicata:

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

Cioè, si crea un 'orario UTC' utilizzando la data senza fuso orario (quindi si conosce la locale in cui si trova, vale a dire la 'locale' UTC, e non è predefinita a quella locale), quindi si applica manualmente l'offset del fuso orario indicato.

Non sarebbe stato carino se qualcuno avesse effettivamente pensato all'oggetto data Javascript per più di, oooh, cinque minuti ...


1
grazie per l'ottima funzione! l'unica cosa che vorrei cambiare è aggiungere il supporto per i due punti nell'offset del fuso orario. 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
Ci hanno pensato; sfortunatamente, i "loro" erano i progettisti del linguaggio Java, poiché JS aveva appena copiato la classe Date di Java per la sua implementazione iniziale.
Xanthir,

@Xanthir Oooh, hai ragione, e avevo dimenticato quanto fosse terribile l'oggetto Java Date originale; ma almeno Java lo ha deprecato e è passato, qualcosa che Javascript sembra incapace di fare (è un linguaggio bizzarro, Javascript: piuttosto carino, e non così terribile come sembra essere).
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

per tutto l'offset della posizione Wiki Elenco di offset dell'ora UTC


In che modo questo aiuta a New York durante l'ora legale?
frederj,

Per New York si prega di utilizzare il valore di offset -4
Vijay Lathiya il

1
L'offset per New York varia in base all'ora legale. A volte è -4 e a volte è -5 en.wikipedia.org/wiki/Eastern_Time_Zone
frederj

8

getTimeZoneOffset è meno per UTC + z.

var d = new Date(xiYear, xiMonth, xiDate);
if(d.getTimezoneOffset() > 0){
    d.setTime( d.getTime() + d.getTimezoneOffset()*60*1000 );
}

1
Un piccolo errore! = 0 no> 0. Ho finito per usare questo
Cristi Băluță

8

Questo può aiutare qualcuno, mettere UTC alla fine di ciò che si passa al nuovo costruttore

Almeno in Chrome puoi dire var date = new Date("2014-01-01 11:00:00 UTC")


1
Restituisce "Data non valida" su Safari
pmrotule,

1
Sostituisci `UTC` con +0000(notato che lo spazio tra 00 e UTC deve essere rimosso) e questo funzionerà sia su Firefox che su Chrome. Non è sicuro per Safari però (Riferimento:. Stackoverflow.com/a/17545854/1273587 )
cytsunny

8

Una soluzione di linea

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

Invece di 1422524805305, usa il timestamp in millisecondi Invece di 330, usa il tuo fuso orario in minuti. GMT (ad es. India +5: 30 è 5 * 60 + 30 = 330 minuti)


4
Questo sarebbe un codice eseguito sul client, il che significa che il fuso orario sarà diverso per gli utenti che si trovano in posizioni diverse. Questa soluzione richiederebbe che chiunque ne abbia bisogno viva nello stesso fuso orario (il tuo).
Kevin Beal,

@Kevin Beal in quel caso basta usare getTimezoneOffset
massimo

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)

Spiegare il tuo codice e come risolve il problema aumenterà la qualità della tua risposta e aiuterà l'apprendimento degli utenti.
Nic3500,

5

Il modo più semplice che ho trovato per ottenere la data corretta è usare datejs.

http://www.datejs.com/

Ottengo le mie date tramite Ajax in questo formato come una stringa: '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);

La console leggerà:

Lun 11 gennaio 2016 19:00:00 GMT-0500 (ora solare orientale)

Mar 12 gen 2016 00:00:00 GMT-0500 (ora solare orientale)

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

'AddMinutes' proviene da datejs, probabilmente potresti farlo da solo in js da solo, ma avevo già datejs nel mio progetto, quindi ho trovato un modo per usarlo per ottenere le date corrette.

Ho pensato che questo potesse aiutare qualcuno ...


Ho provato tutti i metodi e questo è stato l'unico ad avere la mezzanotte che era quello che stavo cercando!
SharpC,

3

qualsiasi chilometraggio in

var d = new Date(xiYear, xiMonth, xiDate).toLocaleString();

Questo sembra fare il trucco per me (un fuso orario di distanza dal GMT), ma poiché "locale" non è necessariamente correlato al fuso orario, non vorrei fare affidamento su di esso.
Wytze,

3

Questo codice restituirà l' oggetto Date formattato con il fuso orario del browser .

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

Modificare:

Per evitare di inquinare l'API Date, la funzione sopra può essere trasformata in una funzione di utilità. La funzione accetta un oggetto Date e restituisce un oggetto Date mutato.

function setTimeZone(date) {
    date.setHours(date.getHours() + (new Date().getTimezoneOffset() / 60));
    return date;
}

6
No all'estensione di oggetti nativi
Paul Rumkin,

1

La migliore soluzione che ho visto da questo è venuta

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

Funzione Stampa tempo

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

Esempio di codice completo

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

Il tuo esempio esclude l'ora legale. Orario corrente: ven 04 ott 2013 11:13:43 GMT-0700 (ora legale del Pacifico) UtcTime: ven, 04 ott 2013 18:13:43 GMT Banff, Canada: 1213 ore. Michigan: 1413 ore Greenwich, Inghilterra (UTC): 1913 ore. Tokyo, Giappone: 0413 ore Berlino, Germania: 2013 ore
Jeson Martajaya,

0

se si desidera verificare la differenza in un intervallo di tempo tra due date, è possibile semplicemente verificare se il secondo fuso orario è minore o maggiore rispetto al primo fuso orario desiderato e sottrarre o aggiungere un orario.

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

0

GMT -03: 00 Esempio

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

O anche

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

-1

Questo ha funzionato per me. Non sono sicuro che sia una buona idea.

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

Ho usato il pacchetto 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());
},

-11

Questa è la soluzione MIGLIORE

usando:

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

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

Codice:

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

Versione caffè:

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

2
Caspita, non mi piace neanche, ma immagino che le persone ti odiano davvero scavalcando il prototipo dei builtin!
Josh di Qaribou,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.