zonas zona mexico horarias horaria hora cual como cambiar c# timezone datetimeoffset

c# - mexico - zona horaria utc



Analizar una cadena de fecha en una determinada zona horaria(compatible con el horario de verano) (5)

Aquí hay una solución simple para un formato predefinido, esto también puede ser dinámico. Personalmente uso esto para hablar con javascript:

public DateTimeOffset ParseDateExactForTimeZone(string dateTime, TimeZoneInfo timezone) { var parsedDateLocal = DateTimeOffset.ParseExact(dateTime, "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture); var tzOffset = timezone.GetUtcOffset(parsedDateLocal.DateTime); var parsedDateTimeZone = new DateTimeOffset(parsedDateLocal.DateTime, tzOffset); return parsedDateTimeZone; }

Ok, he estado trabajando muy duro las últimas semanas y he encontrado un pequeño problema. No creo que mi mente esté a la altura de las tareas ahora mismo :) ¡así que necesito algunos consejos / ayuda! Es probable que sea muy simple, pero mi cabeza aún no hace clic.

Los usuarios introducirán una fecha y hora en AEST. También hay un conjunto de aplicaciones en la zona horaria "predeterminada" (que podría necesitar cambiar), actualmente está establecido en "AUS Eastern Standard Time"

Por lo tanto, tenemos una cadena de usuario sin zona horaria y una zona horaria del sistema definida en un servidor en los EE. UU. (Por lo tanto, local no coincide y no se puede cambiar ni usar)

Ahora, lo que necesito es una forma de decir "analizar esta cadena ingresada por el usuario usando la zona horaria X" no puedo ingresar +10 o +11 como compensación, ya que las fechas pueden estar dentro o fuera del horario de verano; ¡lo que sí lo cambia entre +10 y +11 incluso para la misma zona horaria!

La hora AEST actual también puede estar dentro o fuera del horario de verano, por lo que no puedo convertir una fecha UTC a la hora AEST actual y obtener la cadena "zzz" y adjuntarla, ya que las fechas estarán desactivadas por una hora para cualquier cosa ingresada de la configuración actual DST.

Por ahora el código realmente hace eso:

TimeZoneInfo ConvTo = TimeZoneInfo.FindSystemTimeZoneById(ConfigurationManager.AppSettings["DefaultTimeZone"]); DateTimeOffset getDate = TimeZoneInfo.ConvertTime(DateTimeOffset.UtcNow, ConvTo); string TimeZoneId = " " + getDate.ToString("zzz"); DateTimeOffset cvStartDate = DateTimeOffset.MinValue; DateTimeOffset.TryParse(StartDate + TimeZoneId, out cvStartDate);

Luego verifico si la fecha no es válida verificando si aún es == DateTimeOffset.MinValue o la convierto a UTC y la agrego a la base de datos, se convertirá de nuevo a AEST cuando se muestre. Sin embargo, algunas fechas están apagadas por una hora y otras son perfectas (como se esperaba) :)

¿Cuál es la forma más elegante de resolver esto?

EDITAR:

Para ayudar a explicar el problema, escribí un código de prueba como una aplicación de prueba de Windows:

// User entered date string EnteredDate = "2011/01/01 10:00:00 AM"; // Get the timezone we want to use TimeZoneInfo myTimeZone = TimeZoneInfo.FindSystemTimeZoneById("AUS Eastern Standard Time"); // Find the timezone string of the selected timezone to parse the user string // This is the part that is incorrect and what i need help with. DateTimeOffset getDate = TimeZoneInfo.ConvertTime(DateTimeOffset.UtcNow, myTimeZone); string TimeZoneId = " " + getDate.ToString("zzz"); // Parse the string into the date object DateTimeOffset cvEnteredDate = DateTimeOffset.MinValue; DateTimeOffset.TryParse(EnteredDate + TimeZoneId, out cvEnteredDate); // Display textBox1.Text += "Parsed: " + cvEnteredDate.ToString("yyyy/MM/dd HH:mm:ss zzz") + Environment.NewLine; // Convert to UTC and display cvEnteredDate = cvEnteredDate.ToUniversalTime(); textBox1.Text += "UTC: " + cvEnteredDate.ToString("yyyy/MM/dd HH:mm:ss zzz") + Environment.NewLine; // Convert back to AEST and display cvEnteredDate = TimeZoneInfo.ConvertTime(cvEnteredDate, myTimeZone); textBox1.Text += "Changed Back: " + cvEnteredDate.ToString("yyyy/MM/dd HH:mm:ss zzz") + Environment.NewLine;

¿Cuál es la salida de esto?

Parsed: 2011/01/01 10:00:00 +10:00 UTC: 2011/01/01 00:00:00 +00:00 Changed Back: 2011/01/01 11:00:00 +11:00

Tenga en cuenta que la hora está apagada en uno y el desplazamiento es diferente. Además, ¿qué pasa si SÓLO cambiamos la fecha ingresada a:

string EnteredDate = "2011/04/20 10:00:00 AM";

obtenemos:

Parsed: 2011/04/20 10:00:00 +10:00 UTC: 2011/04/20 00:00:00 +00:00 Changed Back: 2011/04/20 10:00:00 +10:00

Lo cual es perfectamente bueno y correcto, usando el mismo código solo una fecha diferente ingresada.

Esto sucede porque la configuración DST actual y la configuración DST de la fecha ingresada son diferentes, para eso quiero una solución :)

Piense en ello como el problema del huevo y la gallina. Necesito los datos de zona horaria correctos para la cadena ingresada antes de analizarla, que solo puedo obtener después de haber analizado la cadena (por lo que será una solución elaborada)

O necesito .NET para analizar la cadena usando el objeto myTimeZone para que sepa qué configurarlo, pero no puedo ver ninguna función que haga esto, todos toman un objeto ya analizado y establecido datetime o datetimeoffset

¿Estoy buscando soluciones elegantes que otros podrían haber hecho? Ciertamente no puedo ser el único que ha notado esto?

EDIT2:

Ok, he creado una función de ''trabajo'' que resuelve el problema, creo que aquí hay un ejemplo (agregue un cuadro de texto a la aplicación ac # windows y use el código siguiente para probarse a sí mismo):

private void Form1_Load(object sender, EventArgs e) { TimeZoneInfo myTimeZone = TimeZoneInfo.FindSystemTimeZoneById("AUS Eastern Standard Time"); DateTimeOffset get1Date = ReadStringWithTimeZone("2011/01/01 10:00:00 AM", myTimeZone); textBox1.Text += "Read1: " + get1Date.ToString("yyyy/MM/dd HH:mm:ss zzz") + Environment.NewLine; get1Date = get1Date.ToUniversalTime(); textBox1.Text += "Read1 - UTC: " + get1Date.ToString("yyyy/MM/dd HH:mm:ss zzz") + Environment.NewLine; get1Date = TimeZoneInfo.ConvertTime(get1Date, myTimeZone); textBox1.Text += "Changed Back: " + get1Date.ToString("yyyy/MM/dd HH:mm:ss zzz") + Environment.NewLine + Environment.NewLine; DateTimeOffset get2Date = ReadStringWithTimeZone("2011/04/20 10:00:00 AM", myTimeZone); textBox1.Text += "Read2: " + get2Date.ToString("yyyy/MM/dd HH:mm:ss zzz") + Environment.NewLine; get2Date = get2Date.ToUniversalTime(); textBox1.Text += "Read2 - UTC: " + get2Date.ToString("yyyy/MM/dd HH:mm:ss zzz") + Environment.NewLine; get2Date = TimeZoneInfo.ConvertTime(get2Date, myTimeZone); textBox1.Text += "Changed Back: " + get2Date.ToString("yyyy/MM/dd HH:mm:ss zzz") + Environment.NewLine + Environment.NewLine; } public DateTimeOffset ReadStringWithTimeZone(string EnteredDate, TimeZoneInfo tzi) { DateTimeOffset cvUTCToTZI = TimeZoneInfo.ConvertTime(DateTimeOffset.UtcNow, tzi); DateTimeOffset cvParsedDate = DateTimeOffset.MinValue; DateTimeOffset.TryParse(EnteredDate + " " + cvUTCToTZI.ToString("zzz"), out cvParsedDate); if (tzi.SupportsDaylightSavingTime) { TimeSpan getDiff = tzi.GetUtcOffset(cvParsedDate); string MakeFinalOffset = (getDiff.Hours < 0 ? "-" : "+") + (getDiff.Hours > 9 ? "" : "0") + getDiff.Hours + ":" + (getDiff.Minutes > 9 ? "" : "0") + getDiff.Minutes; textBox1.Text += "Diff: " + MakeFinalOffset + Environment.NewLine; DateTimeOffset.TryParse(EnteredDate + " " + MakeFinalOffset, out cvParsedDate); return cvParsedDate; } else { return cvParsedDate; } }

Y la salida:

Diff: +11:00 Read1: 2011/01/01 10:00:00 +11:00 Read1 - UTC: 2010/12/31 23:00:00 +00:00 Changed Back: 2011/01/01 10:00:00 +11:00 Diff: +10:00 Read2: 2011/04/20 10:00:00 +10:00 Read2 - UTC: 2011/04/20 00:00:00 +00:00 Changed Back: 2011/04/20 10:00:00 +10:00

Lo único es que puede haber un problema si la fecha ingresada por el usuario es correcta en el cambio en el horario de DST, aún puede faltar una hora, ya que solo está leyendo el desplazamiento actual y usándolo, luego verificando si se supone que es el horario de verano o No, y si está ahí fuera leería incorrectamente. Sin embargo, es mucho mejor que lo que tengo ahora.

¿Alguien puede ayudarme a limpiar esta función? ¿Es esta la mejor ruta para bajar lo que necesito? ideas?


Como nadie ha proporcionado mejores soluciones (¡lo cual es muy sorprendente!), Acepto mi propia función como respuesta, aunque podría hacer la función más concisa y volver a trabajar un poco más tarde:

public DateTimeOffset ReadStringWithTimeZone(string EnteredDate, TimeZoneInfo tzi) { DateTimeOffset cvUTCToTZI = TimeZoneInfo.ConvertTime(DateTimeOffset.UtcNow, tzi); DateTimeOffset cvParsedDate = DateTimeOffset.MinValue; DateTimeOffset.TryParse(EnteredDate + " " + cvUTCToTZI.ToString("zzz"), out cvParsedDate); if (tzi.SupportsDaylightSavingTime) { TimeSpan getDiff = tzi.GetUtcOffset(cvParsedDate); string MakeFinalOffset = (getDiff.Hours < 0 ? "-" : "+") + (getDiff.Hours > 9 ? "" : "0") + getDiff.Hours + ":" + (getDiff.Minutes > 9 ? "" : "0") + getDiff.Minutes; DateTimeOffset.TryParse(EnteredDate + " " + MakeFinalOffset, out cvParsedDate); return cvParsedDate; } else { return cvParsedDate; } }


Esto parece funcionar para mí cuando necesito analizar una cadena de fecha y hora de una zona horaria conocida en mi local. No lo he probado en muchos casos, pero hasta ahora ha funcionado bien para analizar los tiempos en un servidor en algún lugar de la UE

TimeZoneInfo.ConvertTime(DateTime.Parse("2012-05-25 23:17:15", CultureInfo.CreateSpecificCulture("en-EU")),TimeZoneInfo.FindSystemTimeZoneById("W. Europe Standard Time"),TimeZoneInfo.Local)


La solución más simple: primero analizar la cadena a DateTime local, usar cualquier método de análisis y luego llamar

new DateTimeOffset(dateTimeLocal.Ticks, timezone.BaseUtcOffset)


TimeZoneInfo tiene un método estático ConvertTimeToUtc que le permite especificar la fecha y la zona horaria. Esto hará el ajuste de tiempo por usted y devolverá la fecha UTC.

La documentación de MSDN es http://msdn.microsoft.com/en-us/library/bb495915.aspx , completa con el ejemplo.