Formatting Date and Time for a Specific Culture

The DateTime structure provides methods that allow your applications to perform culture-sensitive operations on a DateTime type. An application can use the DateTimeFormatInfo class to format and display a DateTime type based on culture. For example, using ShortDatePattern, the date February 1, 2001 can be formatted as 2/1/2001 for the English (United States), "en-US", culture and 01/02/2001 for the English (United Kingdom), "en-GB", culture.

An DateTimeFormatInfo object can be created for a specific culture or for the invariant culture, but not for a neutral culture. A neutral culture does not provide enough information to display the correct date format. An exception is thrown if the application attempts to create a DateTimeFormatInfo object using a neutral culture. For additional information and examples of using DateTime formatting, see Date and Time Format Strings.

The following code example displays the current date using ShortDatePattern when the CurrentThread current culture is set to English (United States), "en-US", and then to German (Germany), "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));
   }
}

If you execute this code on July 9, 2001, the output appears as follows:

7/9/2001
09.07.2001

Working with Time Zones

The DateTime structure always uses the local time zone for calculations and comparisons. You should consider this when your application uses the Parse and ParseExact methods. These methods provide overloads that allow conversion of the string representation of a date and time to a DateTime type. Your application can also format a DateTime type for a specific culture. If a time zone is not specified in the string passed to these methods, they retrieve the parsed date and time without performing a time zone adjustment. The date and time are based on the operating system time zone setting. If the application specifies a time zone offset, these methods parse the date/time string, convert it to Coordinated Universal Time (UTC, previously known as Greenwich Mean Time, or GMT), and then convert it to the time on the local system.

The application should use the ToUniversalTime method to convert a local DateTime type to its UTC equivalent. To parse a date/time string and convert it to a UTC DateTime type, the application should use the DateTimeStyles enumeration AdjustToUniversal value with either the Parse method or the ParseExact method.

The following code example creates a DateTime type for the local time and then converts it to the UTC equivalent. Both types are converted to strings and written to the console. Notice that the strings differ by the UTC offset between the local time zone and UTC. These strings are converted back to DateTime types using the ParseExact method. To capture the time zone information stored in utcdt, the AdjustToUniversal value of DateTimeStyles must be specified as a parameter to the ParseExact method. For more information about the UTC offset for various time zones, see 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);
   }
}

This code produces the following output:

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

Working with DateTime Members

When you use the DateTime structure, be aware that the members such as Day are based on the Gregorian calendar. Even if your application changes the current calendar or allows the user to change date and time settings through the regional and language options in Control Panel, the Gregorian calendar is still used to perform the calculations for DateTime methods, which prevents the arithmetic performed by these methods from being corrupted by user settings. If you want your application to perform culture-sensitive date and time operations based on the current calendar, the application must use the Calendar property to call methods provided by the Calendar class, such as GetDayOfMonth. For an example of the difference in values retrieved by the DateTime members and the Calendar members, see Using Calendars for Specific Cultures.

When working with the DateTime structure, be aware that a DateTime type is an immutable value. Therefore, methods such as AddDays retrieve a new DateTime value instead of incrementing an existing value. The following example illustrates how to increment a DateTime type by a day using the statement 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"));

   }
}

If you execute this code on August 3, 2001, it displays the following output:

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

See Also

Concepts

Date and Time Format Strings

Other Resources

Encoding and Localization