Crear una fecha con una zona horaria establecida sin usar una representación de cadena

412

Tengo una página web con tres menús desplegables por día, mes y año. Si uso el Dateconstructor de JavaScript que toma números, entonces obtengo un Dateobjeto para mi zona horaria actual:

new Date(xiYear, xiMonth, xiDate)

Indique la fecha correcta, pero cree que esa fecha es GMT + 01: 00 debido al horario de verano.

El problema aquí es que luego paso esto Datea un método Ajax y cuando la fecha se deserializa en el servidor, se convierte a GMT y, por lo tanto, pierde una hora, lo que hace que el día retroceda. Ahora podría pasar el día, mes y año individualmente al método Ajax, pero parece que debería haber una mejor manera.

La respuesta aceptada me señaló en la dirección correcta, sin embargo, solo el uso setUTCHours()por sí mismo cambió:

Apr 5th 00:00 GMT+01:00 

a

Apr 4th 23:00 GMT+01:00

Luego también tuve que establecer la fecha UTC, mes y año para terminar con

Apr 5th 01:00 GMT+01:00

que es lo que quería

Dan
fuente
99
Si la respuesta aceptada lo señaló en la dirección correcta pero no respondió su pregunta, diría que no debería ser la respuesta aceptada. La respuesta debería responder a la pregunta formulada.
TWR Cole

Respuestas:

481

usarlo .setUTCHours()sería posible establecer fechas en tiempo UTC, lo que le permitiría usar tiempos UTC en todo el sistema.

Sin embargo, no puede configurarlo utilizando UTC en el constructor, a menos que especifique una cadena de fecha.

Utilizando new Date(Date.UTC(year, month, day, hour, minute, second))puede crear un objeto de fecha a partir de una hora UTC específica.

jishi
fuente
101
La sintaxis "new Date (Date.UTC (...))" le permite crear una fecha que es equivalente a una fecha UTC en términos del punto en el tiempo que representa, pero no es lo mismo: tiene una zona horaria diferente (no UTC).
Anthony
52
Tenga en cuenta que al usar "Fecha", el valor del "mes" tiene un rango de 0-11 (no 1-12). Seguí obteniendo un desplazamiento de zona horaria de 2 h (aunque debería haber sido 1 h) y me llevó horas descubrir que la razón era un mes equivocado.
Select0r
44
Esta respuesta es genial. Pero estoy usando una biblioteca [datepicker ui] que está usando una nueva fecha en muchos lugares. Todo lo que quiero es establecer la zona horaria UTC y cada fecha es según la nueva zona horaria. Me sorprende que Javascript no tenga nada para esto.
Sanjeev Kumar Dangi
66
@ jishi: los objetos de fecha se basan en un valor de hora UTC, no en la hora local. Sin embargo, el método predeterminado Date.prototype.toString mostrará valores de hora local.
RobG
55
@ Anthony— " pero no es la misma hora " no es correcto. Representa exactamente el mismo momento en el tiempo, la única diferencia es el desplazamiento de la zona horaria.
RobG
199
var d = new Date(xiYear, xiMonth, xiDate);
d.setTime( d.getTime() + d.getTimezoneOffset()*60*1000 );

Esta respuesta está diseñada específicamente para la pregunta original, y no dará la respuesta que necesariamente espera. En particular, algunas personas querrán restar el desplazamiento de la zona horaria en lugar de agregarlo. Sin embargo, recuerde que el objetivo de esta solución es hackear el objeto de fecha de javascript para una deserialización particular, no ser correcto en todos los casos.

TWR Cole
fuente
6262
@gthmb, por supuesto, pero creo que *60*1000es más claro en este caso; en otras palabras, es bastante evidente por qué está allí.
TWR Cole
22
Esto casi funciona para mí, excepto que tengo que usar - (menos) en lugar de + (más) para obtener el momento adecuado para mi zona horaria.
Wytze
3
Sí, como otros han señalado, creo que hay un error en esta respuesta. Debería ser menos no más.
UpTheCreek
3
De acuerdo con developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…, el valor devuelto por getTimezoneOffset se firma de acuerdo con el desplazamiento real en su ubicación en el momento en que llama a la función, incluida la toma de DST en cuenta, así que no entiendo por qué necesitarías restarlo.
TWR Cole
15
Si agrega timezoneOffset al objeto de fecha, su valor con el formato de la zona horaria local se verá como el valor correcto en UTC, pero aún tendrá el desplazamiento de la zona horaria original (y algunas representaciones como "ISOString" en realidad lo mostrarán). Entonces, dependiendo de cómo serialice el objeto de fecha, JS podría aplicar el desplazamiento de zona horaria nuevamente , dándole la respuesta incorrecta. Creo que esto es responsable de la confusión en estos comentarios entre +/-. De todos modos, mi voto negativo es por este hecho y también por "en la mayoría de los casos obtienes lo que esperas".
metamatt
173

Creo que necesita la función createDateAsUTC (compárela 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()); 
}
club de monstruos
fuente
36
Estoy sorprendido por su respuesta, claridad y amabilidad. No sabía que trabajar con fechas Javascript era una pesadilla hasta hoy: S
will824
¿Te importaría explicar la diferencia entre los dos? El primero se convierte dateen la zona horaria UTC, pero el segundo parece no estar haciendo nada útil. (devuelve la misma fecha que date)
Jonathan Lin
44
Lo entiendo ahora: el primero devuelve la fecha en la zona horaria UTC, con los valores de fecha literal de la hora local. El segundo devuelve la fecha en la zona horaria local, pero con los valores de fecha literal UTC.
Jonathan Lin
8
Este enfoque es una implementación de un patrón llamado "desplazamiento de época", que está destinado a mover la época (que está basada en UTC) a una que se desplaza por el desplazamiento de la zona horaria actual. Desafortunadamente, aunque esto se ve comúnmente, este enfoque es defectuoso. El Dateobjeto de JavaScript siempre reflejará la época de Unix basada en UTC y la zona horaria local . El síntoma es evidente cuando llama toStringal objeto de fecha resultante y aún ve la zona horaria local, aunque esperaba que estuviera en UTC.
Matt Johnson-Pint el
2
También puede causar errores en los valores de hora, cerca de las transiciones de horario de verano de la zona horaria local. En resumen, el cambio de época (a través de cualquier implementación) no funciona con el Dateobjeto JavaScript . Otra forma de ver esto aquí es que Date.UTCespera valores basados ​​en UTC, y lo está alimentando con valores de hora local, y viceversa con el Dateconstructor.
Matt Johnson-Pint el
70

Simplemente configure la zona horaria y regrese de acuerdo

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

Otras zonas horarias son las siguientes

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
fuente
8
Esto debería estar en la cima
Eugene
Excepto tenga en cuenta que esto no funciona en algunos navegadores. P.ej. IE11.
Paul LeBeau
Error en la consola IE: el valor de la opción 'AMERICA / NEW_YORK' para 'timeZone' está fuera del rango válido. Esperado: ['UTC'] @OloghoCyrilPaul
Matee Gojra
1
Muy fácil, muy elegante. Puede encontrar aquí una lista con todas las zonas horarias stackoverflow.com/questions/38399465/… . Para UTC, elija la zona horaria de Londres.
EPurpl3
1
Ninguno de esos valores son "zonas horarias", son ubicaciones representativas de la base de datos de zonas horarias de la IANA para lugares que tienen la misma zona horaria histórica local y cambios de horario de verano.
RobG
28

No creo que esto sea posible: no existe la posibilidad de establecer la zona horaria en un objeto Fecha después de que se crea.

Y en cierto modo, esto tiene sentido: conceptualmente (si tal vez no en la implementación); por http://en.wikipedia.org/wiki/Unix_timestamp (énfasis mío):

El tiempo Unix, o tiempo POSIX, es un sistema para describir instantes en el tiempo, definido como el número de segundos transcurridos desde la medianoche , hora universal coordinada (UTC) del jueves 1 de enero de 1970.

Una vez que haya construido uno, representará un cierto punto en tiempo "real". La zona horaria solo es relevante cuando desea convertir ese punto de tiempo abstracto en una cadena legible por humanos.

Por lo tanto, tiene sentido que solo pueda cambiar la hora real que representa la Fecha en el constructor. Lamentablemente, parece que no hay forma de pasar en una zona horaria explícita, y el constructor al que está llamando (posiblemente correctamente) traduce sus variables de tiempo "locales" en GMT cuando las almacena canónicamente, por lo que no hay forma de usar el int, int, intconstructor para GMT veces.

En el lado positivo, es trivial usar solo el constructor que toma una cadena en su lugar. Ni siquiera tiene que convertir el mes numérico en una Cadena (al menos en Firefox), por lo que esperaba que una implementación ingenua funcionara. Sin embargo, después de probarlo, funciona correctamente en Firefox, Chrome y Opera, pero falla en Konqueror ("Fecha inválida"), Safari ("Fecha inválida") e IE ("NaN"). Supongo que solo tendría una matriz de búsqueda para convertir el mes en una cadena, así:

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

function createGMTDate(xiYear, xiMonth, xiDate) {
   return new Date(months[xiMonth] + ' ' + xiDate + ', ' + xiYear + ' 00:00:00 GMT');
}
Andrzej Doyle
fuente
66
Si no hay forma de "establecer la zona horaria en un objeto Fecha después de que se crea", ¿está implicando que hay una manera de establecer la zona horaria en un objeto Fecha a medida que se crea? No parece que una fecha js sea "una envoltura delgada alrededor de varios segundos desde la Época", parece que es esa cuenta de segundos, más una zona horaria.
Anthony
1
@Anthony, solo puede usar la zona horaria del cliente. Javascript puede hacer local a utc y viceversa, pero no hay acceso a una base de datos de zona horaria. No puede, por ejemplo, decirle la hora en la Ciudad de México cuando se encuentra en San Diego.
Samuel Danielson
20

Sé que esto es antiguo, pero si te ayuda, podrías usar el momento y la zona horaria del momento. Si no los ha visto, eche un vistazo.

http://momentjs.com/timezone/

http://momentjs.com/

dos bibliotecas de manipulación del tiempo realmente útiles.

ChewOnThis_Trident
fuente
16

Si desea lidiar con el problema ligeramente diferente, pero relacionado, de crear un objeto Fecha de Javascript desde año, mes, día, ..., incluida la zona horaria , es decir, si desea analizar una cadena en una Fecha, entonces usted aparentemente tiene que hacer un baile exasperantemente complicado:

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

Es decir, crea una 'hora UTC' utilizando la fecha sin zona horaria (para que sepa en qué localidad se encuentra, es decir, la 'localidad' UTC, y no está predeterminada en la local), y luego aplique manualmente el desplazamiento de la zona horaria indicada.

¿No hubiera sido bueno si alguien hubiera pensado en el objeto de fecha Javascript por más de, oooh, cinco minutos ...

Gris normando
fuente
1
Gracias por la gran función! Lo único que cambiaría es agregar soporte para los dos puntos en el desplazamiento de zona horaria. bits de tiempo var = / ^ ([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
Ellos lo pensaron; desafortunadamente, "ellos" fueron los diseñadores del lenguaje Java, ya que JS simplemente copió la clase Date de Java para su implementación inicial.
Xanthir
@ Xanthir Oooh, tienes razón, y había olvidado lo horrible que era el objeto Java Date original; pero al menos Java lo desaprobó y siguió adelante, algo que Javascript parece incapaz de hacer (es un lenguaje extraño, Javascript: bastante lindo, y no tan horrible como parece ser).
Norman Gray el
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

para todos los desplazamientos de ubicación Wiki Lista de desplazamientos de hora UTC

Vijay Lathiya
fuente
¿Cómo ayuda esto a Nueva York durante el horario de verano?
frederj
Para Nueva York, utilice el valor de compensación -4
Vijay Lathiya
1
La compensación para Nueva York varía según el horario de verano. A veces es -4 y a veces es -5 es.wikipedia.org/wiki/Eastern_Time_Zone
frederj
8

getTimeZoneOffset es negativo para UTC + z.

var d = new Date(xiYear, xiMonth, xiDate);
if(d.getTimezoneOffset() > 0){
    d.setTime( d.getTime() + d.getTimezoneOffset()*60*1000 );
}
rinjan
fuente
1
Un pequeño error
,!
8

Esto puede ayudar a alguien, poner UTC al final de lo que pasa al nuevo constructor

Al menos en cromo puedes decir var date = new Date("2014-01-01 11:00:00 UTC")

Drew LeSueur
fuente
1
Devuelve "Fecha inválida" en Safari
pmrotule
1
Reemplace `UTC` con +0000(notó que el espacio entre 00 y UTC debe eliminarse) y esto funcionará tanto en Firefox como en Chrome. Sin embargo, no estoy seguro para Safari. (Referencia: stackoverflow.com/a/17545854/1273587 )
cytsunny el
8

Solución de una línea

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

En lugar de 1422524805305, use la marca de tiempo en milisegundos En lugar de 330, use el desplazamiento de su zona horaria en minutos wrt. GMT (por ejemplo, India +5: 30 es 5 * 60 + 30 = 330 minutos)

Vinay Vemula
fuente
44
Este sería el código que se ejecuta en el cliente, lo que significa que la zona horaria será diferente para los usuarios ubicados de manera diferente. Esta solución requeriría que todos los que la necesiten vivan en la misma zona horaria (la suya).
Kevin Beal
@Kevin Beal en ese caso solo use 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
fuente
Explicar su código y cómo resuelve el problema elevará la calidad de su respuesta y ayudará a los usuarios a aprender.
Nic3500
5

La forma más fácil que he encontrado para obtener la fecha correcta es usando datejs.

http://www.datejs.com/

Recibo mis fechas a través de Ajax en este formato como una cadena: '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 consola leerá:

Lun 11 de enero de 2016 19:00:00 GMT-0500 (hora estándar del este)

Martes 12 de enero de 2016 00:00:00 GMT-0500 (hora estándar del este)

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

El 'addMinutes' proviene de datejs, probablemente podría hacerlo en js puro por su cuenta, pero ya tenía datejs en mi proyecto, así que encontré una manera de usarlo para obtener las fechas correctas.

Pensé que esto podría ayudar a alguien ...

Barry Franklin
fuente
Probé todos los métodos y este fue el único en llegar a la medianoche, que era lo que buscaba.
SharpC
3

cualquier kilometraje en

var d = new Date(xiYear, xiMonth, xiDate).toLocaleString();
meouw
fuente
Esto parece ser el truco para mí (una zona horaria lejos de GMT), pero como la "configuración regional" no está necesariamente relacionada con la zona horaria, no confiaría en ella.
Wytze
3

Este código devolverá su objeto Date formateado con la zona horaria del navegador .

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

Editar:

Para evitar contaminar la API de fecha, la función anterior se puede transformar en una función de utilidad. La función toma un objeto Date y devuelve un objeto Date mutado.

function setTimeZone(date) {
    date.setHours(date.getHours() + (new Date().getTimezoneOffset() / 60));
    return date;
}
Marco Dal Zovo
fuente
66
No a la extensión de objetos nativos
Paul Rumkin
1

La mejor solución que he visto de esto provino de

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

Función de tiempo de impresión

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

Ejemplo de código 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>
Jeffrey L. Roberts
fuente
Su ejemplo excluye el horario de verano. Hora actual: viernes 4 de octubre de 2013 11:13:43 GMT-0700 (hora del Pacífico) Hora Utc: viernes, 04 de octubre de 2013 18:13:43 GMT Banff, Canadá: 1213 h. Michigan: 1413 hrs. Greenwich, Inglaterra (UTC): 1913 hrs. Tokio, Japón: 0413 hrs. Berlín, Alemania: 2013 hrs.
Jeson Martajaya
0

si desea verificar la diferencia en un tiempo entre dos fechas, simplemente puede verificar si la segunda zona horaria es menor o mayor que la primera zona horaria deseada y restar o agregar una hora.

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

GMT -03: 00 Ejemplo

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

O incluso

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

Esto funcionó para mí. Sin embargo, no estoy seguro de si es una buena 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"

ofmoreno06
fuente
-1

Usé el paquete 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());
},
Stephen Ince
fuente
-11

Esta es la MEJOR solución

Utilizando:

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

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

Código:

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

Versión café:

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
fuente
2
Wow, a mí tampoco me gusta, ¡pero creo que la gente realmente te odia anulando el prototipo de builtins!
Josh de Qaribou