¿Por qué DateTime.ToShortTimeString() no respeta el formato de tiempo corto en “Configuración regional y de idioma”?

StackOverflow https://stackoverflow.com/questions/1292246

Pregunta

Me encontré con un problema que probablemente se debe a que no entiendo cómo funciona el método DateTime.ToShortTimeString().Al formatear cadenas de tiempo con esta función, supuse que respetaría la configuración de "Tiempo corto" en la configuración de formato de Windows 7.

Control Panel -> Clock, Language and Region -> Region and Language -> Formats Tab.

Sin embargo, .NET parece seleccionar un formato de tiempo corto que no se basa en esta configuración sino en la cultura actual:

Region and Language -> Location -> Current Location

Hice algunas pruebas en Windows 7 RC:

Culture: en-GB, 6AM: 06:00, 6PM: 18:00 // HH:mm (United Kingdom)
Culture: en-GB, 6AM: 06:00, 6PM: 18:00 // hh:mm (United Kingdom)
Culture: en-US, 6AM: 6:00 AM, 6PM: 6:00 PM // HH:mm (United States)
Culture: en-US, 6AM: 6:00 AM, 6PM: 6:00 PM // hh:mm (United States)
Culture: el-GR, 6AM: 6:00 πμ, 6PM: 6:00 μμ // HH:mm (Greece)
Culture: el-GR, 6AM: 6:00 πμ, 6PM: 6:00 μμ // hh:mm (Greece)

Utilicé el-GR ya que esa era la cultura con la que el usuario informó el problema; también probó esto en Vista SP2 y Win 7 RC con el mismo resultado.

En realidad, la pregunta es doble:1) ¿Cuál es mi malentendido sobre .NET y los formatos de Windows?2) ¿Cuál es la mejor solución para crear una cadena de tiempo de formato corto (HH:mm o hh:mm tt) basada en el sistema operativo? Idealmente, esto debería funcionar en Mono, por lo que preferiría evitar leer desde el registro o P/Invoke. .

Método utilizado para generar lo anterior, para referencia y pruebas futuras.

[STAThread]
static void Main(string[] args)
{
    CultureInfo culture = CultureInfo.CurrentCulture;

    DateTime sixAm = new DateTime(2009, 07, 05, 6, 0, 0); // 6AM 
    DateTime sixPm = new DateTime(2009, 07, 05, 18, 0, 0); // 6PM

    string sixAmString = sixAm.ToShortTimeString();
    string sixPmString = sixPm.ToShortTimeString();

    string format = "Culture: {0}, 6AM: {1}, 6PM: {2}";

    string output = String.Format(format, culture, sixAmString, sixPmString);
    Console.WriteLine(output);
    Clipboard.Clear();
    Clipboard.SetText(output);

    Console.ReadKey();
}

Actualizar:Según los comentarios de Mike a continuación, adapté el método anterior con los siguientes cambios:

Las dos líneas siguientes

string sixAmString = sixAm.ToShortTimeString();
string sixPmString = sixPm.ToShortTimeString();

Cambiado a

string sixAmString = sixAm.ToString("t", culture);
string sixPmString = sixPm.ToString("t", culture);

También cambié la variable cultural para usar CultureInfo.CurrentUICulture.

Desafortunadamente, esto no funcionó tan bien como esperaba, el resultado, independientemente de la configuración de Short Time en la pestaña Formatos de Windows 7, fue:

Culture: en-US, 6AM: 6:00 AM, 6PM: 6:00 PM

Parece que CultureInfo.CurrentUICulture siempre está en-US.

¿Fue útil?

Solución 3

En respuesta a cada una de mis preguntas:

1) ¿Cuál es mi falta de comprensión de formatos .NET y Windows?

La respuesta corta es, no existe un vínculo entre el "tiempo corto" en el establecimiento de la configuración de "regional y de idioma" y la propiedad ShortTimePattern de .NET. Sin embargo la propiedad LongTimePattern es dictado por el ajuste "largo tiempo".

I adaptado el método anterior sustitución de las dos líneas de formato a:

string sixAmString = sixAm.ToString("T", culture.DateTimeFormat);
string sixPmString = sixPm.ToString("T", culture.DateTimeFormat);

Aquí está la salida:

Culture: en-GB, 6AM: 06:00:00, 6PM: 18:00:00 // HH:mm:ss
Culture: en-GB, 6AM: 06:00:00 AM, 6PM: 06:00:00 PM //hh:mm:ss tt

La parte inferior de este artículo explicó el problema para mí.

2) ¿Cuál es la mejor solución para crear una cadena de tiempo formato corto (HH: mm o hh:? Mm tt) basándose en la configuración del sistema operativo

No sé cuál es la mejor solución, pero he creado la siguiente función que convierte la LongTimeFormat a un ShortTimeFormat lo que permite una aplicación para seguir la opción a los usuarios si cambian el "Long Time" (aunque no va a realizar un seguimiento el "tiempo corto" ajuste).

static string GetShortTimeString(DateTime ShortTimeString)
{
    DateTimeFormatInfo dateTimeFormat = CultureInfo.CurrentCulture.DateTimeFormat;
    string ShortTimePattern = dateTimeFormat.LongTimePattern.Replace(":ss", String.Empty);
    ShortTimePattern = ShortTimePattern.Replace(":s", String.Empty);

    return ShortTimeString.ToString(ShortTimePattern);
}

La salida después de hacer los cambios anteriores:

Culture: en-GB, 6AM: 06:00, 6PM: 18:00
Culture: en-GB, 6AM: 06:00 AM, 6PM: 06:00 PM

El P / opción Invoke es utilizar GetTimeFormat pasar los TIME_NOSECONDS utilizando DateTime.ToString (Formato) como anteriormente. No he probado esto como yo preferiría evitar el uso de P / Invoke.

Otros consejos

respuesta a la segunda pregunta es

DateTimeFormat.Format(DateTime.Now, "t", CultureInfo.CurrentUICulture);

o

DateTime.Now.ToString("t", CultureInfo.CurrentUICulture);

En realidad es siempre mejor utilizar métodos explícitos que aceptan CultureInfo. No hay consistencia cómo .Net elige qué usar de forma predeterminada, ya sea CurrentCulture o CurrentUICulture o InvarinatCulture.

Para hacer respuesta. También voy a describir las diferencias entre las culturas.

Así se CurrentCulture "Panel de control -> Reloj, idioma y región -> regional y de idioma -> Formatos Tab." Esta es la cultura que usted espera que sus cálculos sean. Por ejemplo, puede hacer su contabilidad en los Estados Unidos, por lo que tiene que esto se configura en los Estados Unidos.

CurrentUICulture es "regional y de idioma -> Idioma de la pantalla", significa que cuando usted está emigrante de Ucrania, desea que la aplicación que se localiza en la AU (pero todos los cálculos se encuentra todavía en los Estados Unidos)

.

Y InvariantCulture se llama así la cultura local agnóstico. Debe utilizar esta información para almacenar y así sucesivamente. Efectivamente en-US.

Nota: Podría estar equivocado, donde se encuentra cada ajuste en las ventanas. Pero probablemente tiene una idea.

Estoy seguro de que la cadena de formato corto período de tiempo no se utiliza en DateTime.ToShortTimeString () o DateTime.ToString ( "T") es un error, porque se fijó en el marco .NET 4.0.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top