Procedimiento para enumerar zonas horarias presentes en un equipo

Para trabajar correctamente con una zona horaria designada, es necesario que la información sobre esa zona horaria esté a disposición del sistema. Los sistemas operativos Windows XP y Windows Vista almacenan esta información en el registro. Pero aunque el número total de zonas horarias que existe en el mundo es elevado, el Registro contiene información sobre solo un subconjunto de ellas. Además, el propio Registro es una estructura dinámica cuyo contenido está sujeto a cambios intencionados y accidentales. Como resultado, una aplicación no siempre puede suponer que una zona horaria determinada esté definida y disponible en un sistema. El primer paso para muchas aplicaciones que usan aplicaciones de información de zona horaria es determinar si las zonas horarias necesarias están disponibles en el sistema local o proporcionar al usuario una lista de zonas horarias entre las que seleccionar. Esto exige que una aplicación enumere las zonas horarias definidas en un sistema local.

Nota

Si una aplicación se basa en la presencia de una zona horaria determinada que puede no definirse en un sistema local, la aplicación puede garantizar su presencia serializando y deserializando información sobre la zona horaria. A continuación, se puede agregar la zona horaria a un control de lista para que el usuario de la aplicación pueda seleccionarla. Para obtener más información, consulte Cómo guardar zonas horarias en un recurso incrustado y Cómo restaurar zonas horarias desde un recurso incrustado.

Para enumerar las zonas horarias presentes en el sistema local

  1. Llame al método TimeZoneInfo.GetSystemTimeZones. El método ReadOnlyCollection<T> devuelve una colección genérica de objetos TimeZoneInfo. Las entradas de la colección se ordenan por su propiedad DisplayName. Por ejemplo:

    ReadOnlyCollection<TimeZoneInfo> tzCollection;
    tzCollection = TimeZoneInfo.GetSystemTimeZones();
    
    Dim tzCollection As ReadOnlyCollection(Of TimeZoneInfo) = TimeZoneInfo.GetSystemTimeZones
    
  2. Enumerar los objetos TimeZoneInfo individuales en la colección usando un bucle foreach (en C#) o un For Each…Bucle Next (en Visual Basic) y realizar el procesamiento necesario en cada objeto. Por ejemplo, el código siguiente enumera la colección ReadOnlyCollection<T> de objetos TimeZoneInfo devueltos en el paso 1 y enumera el nombre para mostrar de cada zona horaria en la consola.

    foreach (TimeZoneInfo timeZone in tzCollection)
        Console.WriteLine($"   {timeZone.Id}: {timeZone.DisplayName}");
    
    For Each timeZone As TimeZoneInfo In tzCollection
        Console.WriteLine("   {0}: {1}", timeZone.Id, timeZone.DisplayName)
    Next
    

Para presentar al usuario una lista de zonas horarias presentes en el sistema local

  1. Llame al método TimeZoneInfo.GetSystemTimeZones. El método ReadOnlyCollection<T> devuelve una colección genérica de objetos TimeZoneInfo.

  2. Asigne la colección devuelta en el paso 1 a la propiedad DataSource de un control de lista de formularios Windows Forms o ASP.NET.

  3. Recupere el objeto TimeZoneInfo que el usuario ha seleccionado.

En el ejemplo se proporciona una ilustración para una aplicación de Windows.

Ejemplo

En el ejemplo se inicia una aplicación de Windows que muestra las zonas horarias definidas en un sistema en un cuadro de lista. A continuación, en el ejemplo se muestra un cuadro de diálogo que contiene el valor de la propiedad DisplayName del objeto de zona horaria seleccionado por el usuario.

private void Form1_Load(object sender, EventArgs e)
{
    ReadOnlyCollection<TimeZoneInfo> tzCollection;
    tzCollection = TimeZoneInfo.GetSystemTimeZones();
    _timeZoneList.DataSource = tzCollection;
}

private void OkButton_Click(object sender, EventArgs e)
{
    TimeZoneInfo? selectedTimeZone = (TimeZoneInfo?)_timeZoneList.SelectedItem;
    MessageBox.Show($"You selected the {selectedTimeZone?.ToString()} time zone.");
}
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    Dim tzCollection As ReadOnlyCollection(Of TimeZoneInfo)
    tzCollection = TimeZoneInfo.GetSystemTimeZones()
    Me.timeZoneList.DataSource = tzCollection
End Sub

Private Sub OkButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OkButton.Click
    Dim selectedTimeZone As TimeZoneInfo = DirectCast(Me.timeZoneList.SelectedItem(), TimeZoneInfo)
    MsgBox("You selected the " & selectedTimeZone.ToString() & " time zone.")
End Sub

La mayoría de los controles de lista (como el control System.Windows.Forms.ListBox o System.Web.UI.WebControls.BulletedList) permiten asignar una colección de variables de objeto a su propiedad DataSource siempre y cuando esa colección implemente la interfaz IEnumerable. (La clase genérica ReadOnlyCollection<T> hace esto). Para mostrar un objeto individual en la colección, el control llama al método ToString del objeto para extraer la cadena que se usa para representar el objeto. En el caso de los objetos TimeZoneInfo, el método ToString devuelve el nombre para mostrar del objeto TimeZoneInfo (el valor de su propiedad DisplayName).

Nota

Dado que los controles de lista llaman al método ToString de un objeto, puede asignar una colección de objetos TimeZoneInfo al control, hacer que el control muestre un nombre descriptivo para cada objeto y recupere el objeto TimeZoneInfo que el usuario ha seleccionado. Esto elimina la necesidad de extraer una cadena para cada objeto de la colección, asignar la cadena a una colección que se asigna a su vez a la propiedad DataSource del control, recuperar la cadena que el usuario ha seleccionado y, a continuación, usar esta cadena para extraer el objeto que describe.

Compilación del código

Para este ejemplo se necesita:

Consulte también