zona how horaria convert change c# javascript timezone utc

c# - how - ¿Cómo puedo determinar una zona horaria por el desplazamiento UTC?



zona horaria c# (3)

Tengo un escenario donde tengo un desplazamiento de zona horaria (en minutos) y necesito determinar la zona horaria para ello. Sé que todos los datos no están disponibles (por ejemplo, puede haber varias zonas horarias con un desplazamiento de -240 minutos) pero es aceptable una "mejor estimación".

Mi primer pase se veía así:

foreach (var info in TimeZoneInfo.GetSystemTimeZones()) { if (info.BaseUtcOffset.TotalMinutes == timezoneOffset) { // do something here if this is a valid timezone } }

Esta especie funciona, pero necesito tener en cuenta el ahorro de luz diurna que me está echando un poco. He añadido este terrible hack:

foreach (var info in TimeZoneInfo.GetSystemTimeZones()) { var extra = info.IsDaylightSavingTime(DateTime.Now) ? 60 : 0; if (info.BaseUtcOffset.TotalMinutes + extra == timezoneOffset) { // do something here if this is a valid timezone } }

Esto funciona "suficientemente bien", ya que puedo mostrarle al usuario la hora correcta cuando el horario de verano no está vigente y tengo una corrección de alrededor del 70% durante el horario de verano. Aún así ... este es un código horrible para mis ojos.

¿Hay una mejor manera de hacer esto? Más elegancia sería buena, y más precisión sería aún mejor.

Actualizar

Técnicamente tengo acceso a cualquier información que Javascript pueda obtener sobre la fecha. Tengo una página en la que he colocado un campo oculto llamado "desplazamiento". Tengo una función JQuery que rellena el campo de compensación con DateTime (). GetTimezoneOffset (). Si bien no veo nada en el objeto DateTime que ayude, quizás esto abra otras vías para las ideas.


Con algunos trucos puedes estar en lo correcto el 99% del tiempo, y cerrar el otro 1%. Echa un vistazo a jstimezonedetect para una implementación extremadamente completa.

El enfoque de un hombre pobre sería mapear manualmente cada posible desplazamiento de zona horaria reportado a su mejor conjetura. ¡Ya que estás adivinando, también podrías ser explícito al respecto!


Debido a la diferencia de UTC, no puede saber en qué zona horaria se encuentra, debido al horario de verano. Podría considerar mirar la parte del tiempo para tratar de adivinar si el horario de verano estaba vigente o no, pero las consideraciones políticas lo hacen casi imposible, ya que diferentes jurisdicciones cambian la definición de horario de verano.


Respuesta corta: no puedes.

El horario de verano lo hace imposible. Por ejemplo, no hay forma de determinar, únicamente a partir de la compensación UTC, la diferencia entre Arizona y California en el verano, o Arizona y Nuevo México en el invierno (ya que Arizona no cumple con el DST).

También está la cuestión de la hora en que los diferentes países observan el horario de verano. Por ejemplo, en los Estados Unidos, el horario de verano comienza antes y termina más tarde que en Europa.

Es posible realizar una estimación cercana (es decir, +/- una hora), pero si lo está utilizando para mostrar el tiempo a los usuarios, inevitablemente se mostrará el tiempo equivocado para algunos de ellos.

Actualización : a partir de los comentarios, parece que su objetivo principal es mostrar una marca de tiempo en la zona horaria local del usuario. Si eso es lo que quiere hacer, debe enviar la hora como una marca de hora UTC y, a continuación, volver a escribirla en el navegador del usuario con Javascript. En el caso de que no tengan Javascript habilitado, todavía verán una marca de tiempo UTC utilizable. Aquí hay una función que se me ocurrió en esta pregunta , que usé en este script de Greasemonkey . Es posible que desee modificarlo para satisfacer sus necesidades.

//@param timestamp An ISO-8601 timestamp in the form YYYY-MM-DDTHH:MM:SS±HH:MM //Note: Some other valid ISO-8601 timestamps are not accepted by this function function parseISO8601(timestamp) { var regex = new RegExp("^([//d]{4})-([//d]{2})-([//d]{2})T([//d]{2}):([//d]{2}):([//d]{2})([//+//-])([//d]{2}):([//d]{2})$"); var matches = regex.exec(timestamp); if(matches != null) { var offset = parseInt(matches[8], 10) * 60 + parseInt(matches[9], 10); if(matches[7] == "-") offset = -offset; return new Date( Date.UTC( parseInt(matches[1], 10), parseInt(matches[2], 10) - 1, parseInt(matches[3], 10), parseInt(matches[4], 10), parseInt(matches[5], 10), parseInt(matches[6], 10) ) - offset*60*1000 ); } return null; }

Esta es una función que utilizo en mi blog para mostrar una marca de tiempo analizada en la zona horaria local del usuario. Nuevamente, puedes ajustarlo al formato que desees.

var weekDays = new Array("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"); var months = new Array("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"); function toLocalTime(date) { var hour = date.getHours(); var ampm = (hour < 12 ? "am" : "pm"); hour = (hour + 11)%12 + 1; var minutes = date.getMinutes(); if(minutes < 10) minutes = "0" + minutes; return weekDays[date.getDay()] + ", " + months[date.getMonth()] + " " + date.getDate() + ", " + date.getFullYear() + " at " + hour + ":" + minutes + " " + ampm; }