Форматирование даты и времени для определенного языка и региональных параметров

Структура DateTime предоставляет методы, позволяющие приложениям выполнять операции с учетом языка и региона над типом DateTime. Приложение может использовать класс DateTimeFormatInfo для форматирования и отображения типа DateTime в зависимости от языка и региональных параметров. Например, с помощью DateTimeFormatInfo.ShortDatePattern дата "1 февраля 2001 года" форматируется как "2/1/2001" для английского языка (США), "en-US" и как 01/02/2001 для английского языка (Великобритания), "en-GB".

Объект DateTimeFormatInfo можно создать для определенного или инвариантного языка и региона, но не для нейтрального языка и региональных параметров. Нейтральный язык и региональные параметры не предоставляют сведений, достаточных для отображения даты в правильном формате. При попытке приложения создать объект DateTimeFormatInfo с использованием нейтрального языка и региональных параметров возникает исключение. Дополнительные сведения и примеры использования форматирования DateTime см. в разделе Строки форматов даты и времени.

Следующий пример кода отображает текущую дату с использованием DateTimeFormatInfo.ShortDatePattern, когда для Thread.CurrentThread текущего языка и региональных параметров задано значение "en-US" (английский – США), а затем "de-DE" (немецкий – Германия).

Imports System
Imports System.Globalization
Imports System.Threading

Public Class FormatDate
   
   Public Shared Sub Main()
      Dim dt As DateTime = DateTime.Now
      ' Sets the CurrentCulture property to U.S. English.
      Thread.CurrentThread.CurrentCulture = New CultureInfo("en-US")
      ' Displays dt, formatted using the ShortDatePattern
      ' and the CurrentThread.CurrentCulture.
      Console.WriteLine(dt.ToString("d"))
      
      ' Creates a CultureInfo for German in Germany.
      Dim ci As New CultureInfo("de-DE")
      ' Displays dt, formatted using the ShortDatePattern
      ' and the CultureInfo.
      Console.WriteLine(dt.ToString("d", ci))
   End Sub
End Class
using System;
using System.Globalization;
using System.Threading;

public class FormatDate
{
   public static void Main()
   {
      DateTime dt = DateTime.Now;
      // Sets the CurrentCulture property to U.S. English.
      Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
      // Displays dt, formatted using the ShortDatePattern
      // and the CurrentThread.CurrentCulture.
      Console.WriteLine(dt.ToString("d"));
      
      // Creates a CultureInfo for German in Germany.
      CultureInfo ci = new CultureInfo("de-DE");
      // Displays dt, formatted using the ShortDatePattern
      // and the CultureInfo.
      Console.WriteLine(dt.ToString("d", ci));
   }
}

Если выполнить этот код 9 июля 2001 года, то будет выдан следующий результат.

7/9/2001
09.07.2001

Работа с часовыми поясами

При вычислениях и сравнениях структура DateTime всегда использует локальный часовой пояс. Этот момент необходимо учитывать, когда приложение использует методы DateTime.Parse и DateTime.ParseExact. Эти методы поддерживают перегрузки, которые позволяют преобразовывать строковое представление даты и времени в тип DateTime. Приложение может отформатировать тип DateTime для определенного языка и региональных параметров. Если часовой пояс не определен в строке, которая передается этим методам, они извлекают дату и время без изменения, учитывающего часовой пояс. В основе значений даты и времени находятся системные настройки часового пояса. Если в приложении задать смещение часового пояса, эти методы выполняют анализ строки с датой и временем и преобразуют время сначала в формат UTC (Coordinated Universal Time, прежнее название – время по Гринвичу, GMT), а затем – в местное время.

Для преобразования локального типа DateTime в его UTC-эквивалент в приложении необходимо использовать метод DateTime.ToUniversalTime. Для анализа строки с датой и временем и преобразования ее в тип DateTime времени в формате UTC в приложении следует использовать значение перечисления DateTimeStyles.AdjustToUniversal с методом DateTime.Parse либо DateTime.ParseExact.

В следующем примере кода показано создание типа DateTime для местного времени и последующее преобразование в UTC-эквивалент. Оба типа преобразуются в строки для вывода на консоль. Необходимо обратить внимание на то, что строки отличаются по UTC-сдвигу между локальным часовым поясом и временем UTC. С помощью метода DateTime.ParseExact эти строки преобразуются обратно в тип DateTime. Для сбора сведений о часовом поясе, которые хранятся в utcdt, значение DateTimeStyles.AdjustToUniversal должно быть определено как параметр для метода DateTime.ParseExact. Дополнительные сведения о UTC-смещении для различных часовых поясов см. в разделе GetUtcOffset.

Imports System
Imports System.Globalization
Imports System.Threading

Public Class TimeZoneSample
   Public Shared Sub Main()
      Dim en As New CultureInfo("en-US")
      Thread.CurrentThread.CurrentCulture = en

      ' Creates a DateTime for the local time.
      Dim dt As New DateTime(2001, 7, 13, 4, 0, 0)

      ' Converts the local DateTime to the UTC time.
      Dim utcdt As DateTime = dt.ToUniversalTime()

      ' Defines a custom string format to display the DateTime.
      ' zzz specifies the full time zone offset.
      Dim format As [String] = "MM/dd/yyyy hh:mm:sszzz"

      ' Converts the local time to a string
      ' using the custom format string and display.
      Dim str As [String] = dt.ToString(format)
      Console.WriteLine(str)

      ' Converts the UTC time to a string
      ' using the custom format string and display.
      Dim utcstr As [String] = utcdt.ToString(format)
      Console.WriteLine(utcstr)

      ' Converts the string back to a local DateTime and displays it.
      Dim parsedBack As DateTime = DateTime.ParseExact(str, format, 
            en.DateTimeFormat)
      Console.WriteLine(parsedBack)

      ' Converts the string back to a UTC DateTime and displays it.
      ' If you do not use the DateTime.ParseExact method that takes
      ' a DateTimeStyles.AdjustToUniversal value, the parsed DateTime
      ' will not include the time zone information. 
      Dim parsedBackUTC As DateTime = DateTime.ParseExact(str, format, _
            en.DateTimeFormat, DateTimeStyles.AdjustToUniversal)
      Console.WriteLine(parsedBackUTC)
   End Sub
End Class
using System;
using System.Globalization;
using System.Threading;

public class TimeZoneSample
{
   public static void Main()
   {
      CultureInfo en = new CultureInfo("en-US");
      Thread.CurrentThread.CurrentCulture = en;

      // Creates a DateTime for the local time.
      DateTime dt = new DateTime(2001, 7, 13, 4, 0, 0);

      // Converts the local DateTime to the UTC time.
      DateTime utcdt = dt.ToUniversalTime();

      // Defines a custom string format to display the DateTime value.
      // zzzz specifies the full time zone offset.
      String format = "MM/dd/yyyy hh:mm:sszzz";

      // Converts the local DateTime to a string 
      // using the custom format string and display.
      String str = dt.ToString(format);
      Console.WriteLine(str);

      // Converts the UTC DateTime to a string 
      // using the custom format string and display.
      String utcstr = utcdt.ToString(format);
      Console.WriteLine(utcstr);

      // Converts the string back to a local DateTime and displays it.
      DateTime parsedBack =
            DateTime.ParseExact(str,format,en.DateTimeFormat);
      Console.WriteLine(parsedBack);

      // Converts the string back to a UTC DateTime and displays it.
      // If you do not use the DateTime.ParseExact method that takes
      // a DateTimeStyles.AdjustToUniversal value, the parsed DateTime
      // object will not include the time zone information.
      DateTime parsedBackUTC = DateTime.ParseExact(str,format, _
            en.DateTimeFormat, DateTimeStyles.AdjustToUniversal);
      Console.WriteLine(parsedBackUTC);
   }
}

В результате выполнения кода получены следующие выходные данные.

07/13/2001 04:00:00-07:00
07/13/2001 11:00:00-07:00
7/13/2001 4:00:00 AM
7/13/2001 11:00:00 AM

Работа с элементами DateTime

При использовании структуры DateTime необходимо помнить, что такие элементы, как DateTime.Day, основаны на григорианском календаре. Даже если приложение изменяет текущий календарь или позволяет пользователям изменять настройки даты и времени в диалоговом окне "Язык и региональные стандарты", доступном с панели управления, для методов DateTime по-прежнему будет использоваться григорианский календарь, защищающий арифметические операции, выполняемые этими методами, от ошибок, связанных с пользовательскими настройками. Для выполнения операций с датой и временем, которые зависят от языка и региональных параметров и основаны на значениях текущего календаря, в приложении необходимо использовать свойство DateTimeFormatInfo.Calendar для вызова методов, предоставляемых классом Calendar, таких как Calendar.GetDayOfMonth. Пример различий в значениях, возвращаемых элементами DateTime, и класса DateTimeFormatInfo.Calendar см. в разделе Использование календарей для определенных языков и региональных параметров.

При работе со структурой DateTime следует помнить, что тип DateTime неизменяем. Поэтому такие методы, как DateTime.AddDays, извлекают новое значение DateTime вместо увеличения текущего значения. В следующем примере показано, как увеличить тип DateTime на один день с использованием оператора dt = dt.AddDays(1).

Imports System
Imports System.Globalization
Imports System.Threading
Imports Microsoft.VisualBasic

Public Class TestClass
   
   Public Shared Sub Main()
      Thread.CurrentThread.CurrentCulture = New CultureInfo("en-US")
      
      Dim dt As DateTime = DateTime.Now
      Console.WriteLine(ControlChars.Newline + " Today is {0}", _
         DateTime.Now.ToString("d"))
      
      ' Increments dt by one day.
      dt = dt.AddDays(1)
      Console.WriteLine(ControlChars.Newline + " Tomorrow is {0}", _
         dt.ToString("d"))
   End Sub
End Class
using System;
using System.Globalization;
using System.Threading;

public class TestClass
{
   public static void Main()
   {
      Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");

      DateTime dt = DateTime.Now;
      Console.WriteLine("Today is {0}", DateTime.Now.ToString("d"));

      // Increments dt by one day.
      dt = dt.AddDays(1);
      Console.WriteLine("Tomorrow is {0}", dt.ToString("d"));

   }
}

Если выполнить этот код 3 августа 2001 года, то будет выдан следующий результат.

Today is 8/3/2001
Tomorrow is 8/4/2001

См. также

Другие ресурсы

Шифрование и локализация

Date and Time Format Strings