Export (0) Print
Expand All

DateTimeFormatInfo Class

Provides culture-specific information about the format of date and time values.

System.Object
  System.Globalization.DateTimeFormatInfo

Namespace:  System.Globalization
Assembly:  mscorlib (in mscorlib.dll)

[SerializableAttribute]
[ComVisibleAttribute(true)]
public sealed class DateTimeFormatInfo : ICloneable, 
	IFormatProvider

The DateTimeFormatInfo type exposes the following members.

  NameDescription
Public methodSupported by the XNA FrameworkSupported by Portable Class LibrarySupported in .NET for Windows Store appsDateTimeFormatInfoInitializes a new writable instance of the DateTimeFormatInfo class that is culture-independent (invariant).
Top

  NameDescription
Public propertySupported by the XNA FrameworkSupported by Portable Class LibrarySupported in .NET for Windows Store appsAbbreviatedDayNamesGets or sets a one-dimensional array of type String containing the culture-specific abbreviated names of the days of the week.
Public propertySupported by the XNA FrameworkSupported by Portable Class LibrarySupported in .NET for Windows Store appsAbbreviatedMonthGenitiveNamesGets or sets a string array of abbreviated month names associated with the current DateTimeFormatInfo object.
Public propertySupported by the XNA FrameworkSupported by Portable Class LibrarySupported in .NET for Windows Store appsAbbreviatedMonthNamesGets or sets a one-dimensional string array that contains the culture-specific abbreviated names of the months.
Public propertySupported by the XNA FrameworkSupported by Portable Class LibrarySupported in .NET for Windows Store appsAMDesignatorGets or sets the string designator for hours that are "ante meridiem" (before noon).
Public propertySupported by the XNA FrameworkSupported by Portable Class LibrarySupported in .NET for Windows Store appsCalendarGets or sets the calendar to use for the current culture.
Public propertySupported by the XNA FrameworkSupported by Portable Class LibrarySupported in .NET for Windows Store appsCalendarWeekRuleGets or sets a value that specifies which rule is used to determine the first calendar week of the year.
Public propertyStatic memberSupported by the XNA FrameworkSupported by Portable Class LibrarySupported in .NET for Windows Store appsCurrentInfoGets a read-only DateTimeFormatInfo object that formats values based on the current culture.
Public propertySupported by the XNA FrameworkDateSeparatorGets or sets the string that separates the components of a date, that is, the year, month, and day.
Public propertySupported by the XNA FrameworkSupported by Portable Class LibrarySupported in .NET for Windows Store appsDayNamesGets or sets a one-dimensional string array that contains the culture-specific full names of the days of the week.
Public propertySupported by the XNA FrameworkSupported by Portable Class LibrarySupported in .NET for Windows Store appsFirstDayOfWeekGets or sets the first day of the week.
Public propertySupported by the XNA FrameworkSupported by Portable Class LibrarySupported in .NET for Windows Store appsFullDateTimePatternGets or sets the custom format string for a long date and long time value.
Public propertyStatic memberSupported by the XNA FrameworkSupported by Portable Class LibrarySupported in .NET for Windows Store appsInvariantInfoGets the default read-only DateTimeFormatInfo object that is culture-independent (invariant).
Public propertySupported by the XNA FrameworkSupported by Portable Class LibrarySupported in .NET for Windows Store appsIsReadOnlyGets a value indicating whether the DateTimeFormatInfo object is read-only.
Public propertySupported by the XNA FrameworkSupported by Portable Class LibrarySupported in .NET for Windows Store appsLongDatePatternGets or sets the custom format string for a long date value.
Public propertySupported by the XNA FrameworkSupported by Portable Class LibrarySupported in .NET for Windows Store appsLongTimePatternGets or sets the custom format string for a long time value.
Public propertySupported by the XNA FrameworkSupported by Portable Class LibrarySupported in .NET for Windows Store appsMonthDayPatternGets or sets the custom format string for a month and day value.
Public propertySupported by the XNA FrameworkSupported by Portable Class LibrarySupported in .NET for Windows Store appsMonthGenitiveNamesGets or sets a string array of month names associated with the current DateTimeFormatInfo object.
Public propertySupported by the XNA FrameworkSupported by Portable Class LibrarySupported in .NET for Windows Store appsMonthNamesGets or sets a one-dimensional array of type String containing the culture-specific full names of the months.
Public propertyNativeCalendarNameGets the native name of the calendar associated with the current DateTimeFormatInfo object.
Public propertySupported by the XNA FrameworkSupported by Portable Class LibrarySupported in .NET for Windows Store appsPMDesignatorGets or sets the string designator for hours that are "post meridiem" (after noon).
Public propertySupported by the XNA FrameworkSupported by Portable Class LibrarySupported in .NET for Windows Store appsRFC1123PatternGets the custom format string for a time value that is based on the Internet Engineering Task Force (IETF) Request for Comments (RFC) 1123 specification.
Public propertySupported by the XNA FrameworkSupported by Portable Class LibrarySupported in .NET for Windows Store appsShortDatePatternGets or sets the custom format string for a short date value.
Public propertySupported by the XNA FrameworkSupported by Portable Class LibrarySupported in .NET for Windows Store appsShortestDayNamesGets or sets a string array of the shortest unique abbreviated day names associated with the current DateTimeFormatInfo object.
Public propertySupported by the XNA FrameworkSupported by Portable Class LibrarySupported in .NET for Windows Store appsShortTimePatternGets or sets the custom format string for a short time value.
Public propertySupported by the XNA FrameworkSupported by Portable Class LibrarySupported in .NET for Windows Store appsSortableDateTimePatternGets the custom format string for a sortable date and time value.
Public propertySupported by the XNA FrameworkTimeSeparatorGets or sets the string that separates the components of time, that is, the hour, minutes, and seconds.
Public propertySupported by the XNA FrameworkSupported by Portable Class LibrarySupported in .NET for Windows Store appsUniversalSortableDateTimePatternGets the custom format string for a universal, sortable date and time string.
Public propertySupported by the XNA FrameworkSupported by Portable Class LibrarySupported in .NET for Windows Store appsYearMonthPatternGets or sets the custom format string for a year and month value.
Top

  NameDescription
Public methodSupported by the XNA FrameworkSupported by Portable Class LibrarySupported in .NET for Windows Store appsCloneCreates a shallow copy of the DateTimeFormatInfo.
Public methodSupported by the XNA FrameworkSupported by Portable Class LibrarySupported in .NET for Windows Store appsEquals(Object)Determines whether the specified object is equal to the current object. (Inherited from Object.)
Public methodSupported by the XNA FrameworkSupported by Portable Class LibrarySupported in .NET for Windows Store appsGetAbbreviatedDayNameReturns the culture-specific abbreviated name of the specified day of the week based on the culture associated with the current DateTimeFormatInfo object.
Public methodSupported by the XNA FrameworkSupported by Portable Class LibrarySupported in .NET for Windows Store appsGetAbbreviatedEraNameReturns the string containing the abbreviated name of the specified era, if an abbreviation exists.
Public methodSupported by the XNA FrameworkSupported by Portable Class LibrarySupported in .NET for Windows Store appsGetAbbreviatedMonthNameReturns the culture-specific abbreviated name of the specified month based on the culture associated with the current DateTimeFormatInfo object.
Public methodSupported by the XNA FrameworkGetAllDateTimePatterns()Returns all the standard patterns in which date and time values can be formatted.
Public methodSupported by the XNA FrameworkGetAllDateTimePatterns(Char)Returns all the patterns in which date and time values can be formatted using the specified standard format string.
Public methodSupported by the XNA FrameworkSupported by Portable Class LibrarySupported in .NET for Windows Store appsGetDayNameReturns the culture-specific full name of the specified day of the week based on the culture associated with the current DateTimeFormatInfo object.
Public methodSupported by the XNA FrameworkSupported by Portable Class LibrarySupported in .NET for Windows Store appsGetEraReturns the integer representing the specified era.
Public methodSupported by the XNA FrameworkSupported by Portable Class LibrarySupported in .NET for Windows Store appsGetEraNameReturns the string containing the name of the specified era.
Public methodSupported by the XNA FrameworkSupported by Portable Class LibrarySupported in .NET for Windows Store appsGetFormatReturns an object of the specified type that provides a date and time formatting service.
Public methodSupported by the XNA FrameworkSupported by Portable Class LibrarySupported in .NET for Windows Store appsGetHashCodeServes as the default hash function. (Inherited from Object.)
Public methodStatic memberSupported by the XNA FrameworkSupported by Portable Class LibrarySupported in .NET for Windows Store appsGetInstanceReturns the DateTimeFormatInfo object associated with the specified IFormatProvider.
Public methodSupported by the XNA FrameworkSupported by Portable Class LibrarySupported in .NET for Windows Store appsGetMonthNameReturns the culture-specific full name of the specified month based on the culture associated with the current DateTimeFormatInfo object.
Public methodGetShortestDayNameObtains the shortest abbreviated day name for a specified day of the week associated with the current DateTimeFormatInfo object.
Public methodSupported by the XNA FrameworkSupported by Portable Class LibrarySupported in .NET for Windows Store appsGetTypeGets the Type of the current instance. (Inherited from Object.)
Public methodStatic memberSupported by the XNA FrameworkSupported by Portable Class LibrarySupported in .NET for Windows Store appsReadOnlyReturns a read-only DateTimeFormatInfo wrapper.
Public methodSetAllDateTimePatternsSets the custom date and time format strings that correspond to a specified standard format string.
Public methodSupported by the XNA FrameworkSupported by Portable Class LibrarySupported in .NET for Windows Store appsToStringReturns a string that represents the current object. (Inherited from Object.)
Top

The properties of the DateTimeFormatInfo class contain culture-specific information for formatting or parsing date and time values such as the following:

  • The patterns used to format date values.

  • The patterns used to format time values.

  • The names of the days of the week.

  • The names of the months of the year.

  • The A.M. and P.M. designators used in time values.

  • The calendar in which dates are expressed.

In this section:

Instantiating a DateTimeFormatInfo object

A DateTimeFormatInfo object can represent the formatting conventions of the invariant culture, a specific culture, a neutral culture, or the current culture. This section discusses how to instantiate each type of DateTimeFormatInfo object.

The invariant culture represents a culture that is culture-insensitive. It is based on the English language, but not on any specific English-speaking country/region. Although the data of specific cultures can be dynamic and can change to reflect new cultural conventions or user preferences, the data of the invariant culture does not change. You can instantiate a DateTimeFormatInfo object that represents the formatting conventions of the invariant culture in the following ways:

  • By retrieving the value of the InvariantInfo property. The returned DateTimeFormatInfo object is read-only.

  • By calling the parameterless DateTimeFormatInfo constructor. The returned DateTimeFormatInfo object is read/write.

  • By retrieving the value of the DateTimeFormat property from the CultureInfo object that is returned by the CultureInfo.InvariantCulture property. The returned DateTimeFormatInfo object is read-only.

The following example uses each of these methods to instantiate a DateTimeFormatInfo object that represents the invariant culture. It then indicates whether the object is read-only.

System.Globalization.DateTimeFormatInfo dtfi; 

dtfi = System.Globalization.DateTimeFormatInfo.InvariantInfo;
Console.WriteLine(dtfi.IsReadOnly);               

dtfi = new System.Globalization.DateTimeFormatInfo();
Console.WriteLine(dtfi.IsReadOnly);               

dtfi = System.Globalization.CultureInfo.InvariantCulture.DateTimeFormat;
Console.WriteLine(dtfi.IsReadOnly);                
// The example displays the following output: 
//       True 
//       False 
//       True      

A specific culture represents a language that is spoken in a particular country/region. For example, en-US is a specific culture that represents the English language spoken in the United States, and en-CA is a specific culture that represents the English language spoken in Canada. You can instantiate a DateTimeFormatInfo object that represents the formatting conventions of a specific culture in the following ways:

The following example illustrates each of these ways to instantiate a DateTimeFormatInfo object and indicates whether the resulting object is read-only.

System.Globalization.CultureInfo ci = null;
System.Globalization.DateTimeFormatInfo dtfi = null;

// Instantiate a culture using CreateSpecificCulture.
ci = System.Globalization.CultureInfo.CreateSpecificCulture("en-US");
dtfi = ci.DateTimeFormat;
Console.WriteLine("{0} from CreateSpecificCulture: {1}", ci.Name, dtfi.IsReadOnly);

// Instantiate a culture using the CultureInfo constructor.
ci = new System.Globalization.CultureInfo("en-CA"); 
dtfi = ci.DateTimeFormat;
Console.WriteLine("{0} from CultureInfo constructor: {1}", ci.Name, dtfi.IsReadOnly);

// Retrieve a culture by calling the GetCultureInfo method.
ci = System.Globalization.CultureInfo.GetCultureInfo("en-AU");
dtfi = ci.DateTimeFormat;
Console.WriteLine("{0} from GetCultureInfo: {1}", ci.Name, dtfi.IsReadOnly);

// Instantiate a DateTimeFormatInfo object by calling DateTimeFormatInfo.GetInstance.  
ci = System.Globalization.CultureInfo.CreateSpecificCulture("en-GB");
dtfi = System.Globalization.DateTimeFormatInfo.GetInstance(ci);
Console.WriteLine("{0} from GetInstance: {1}", ci.Name, dtfi.IsReadOnly);

// The example displays the following output: 
//      en-US from CreateSpecificCulture: False 
//      en-CA from CultureInfo constructor: False 
//      en-AU from GetCultureInfo: True 
//      en-GB from GetInstance: False

A neutral culture represents a culture or language that is independent of a country/region; it is typically the parent of one or more specific cultures. For example, Fr is a neutral culture for the French language and the parent of the fr-FR culture. You can instantiate a DateTimeFormatInfo object that represents the formatting conventions of a neutral culture in the same ways that you create a DateTimeFormatInfo object that represents the formatting conventions of a specific culture. In addition, you can retrieve a neutral culture's DateTimeFormatInfo object by retrieving a neutral culture from a specific culture's CultureInfo.Parent property and retrieving the DateTimeFormatInfo object returned by its CultureInfo.DateTimeFormat property. Unless the parent culture represents the invariant culture, the returned DateTimeFormatInfo object is read/write. The following example illustrates these ways of instantiating a DateTimeFormatInfo object that represents a neutral culture.

System.Globalization.CultureInfo specific, neutral;
System.Globalization.DateTimeFormatInfo dtfi;

// Instantiate a culture by creating a specific culture and using its Parent property.
specific = System.Globalization.CultureInfo.GetCultureInfo("fr-FR");
neutral = specific.Parent;
dtfi = neutral.DateTimeFormat;
Console.WriteLine("{0} from Parent property: {1}", neutral.Name, dtfi.IsReadOnly);

dtfi = System.Globalization.CultureInfo.GetCultureInfo("fr-FR").Parent.DateTimeFormat;
Console.WriteLine("{0} from Parent property: {1}", neutral.Name, dtfi.IsReadOnly);

// Instantiate a neutral culture using the CultureInfo constructor.
neutral = new System.Globalization.CultureInfo("fr");
dtfi = neutral.DateTimeFormat;
Console.WriteLine("{0} from CultureInfo constructor: {1}", neutral.Name, dtfi.IsReadOnly);

// Instantiate a culture using CreateSpecificCulture. 
neutral = System.Globalization.CultureInfo.CreateSpecificCulture("fr");
dtfi = neutral.DateTimeFormat;
Console.WriteLine("{0} from CreateSpecificCulture: {1}", neutral.Name, dtfi.IsReadOnly);

// Retrieve a culture by calling the GetCultureInfo method.
neutral = System.Globalization.CultureInfo.GetCultureInfo("fr");
dtfi = neutral.DateTimeFormat;
Console.WriteLine("{0} from GetCultureInfo: {1}", neutral.Name, dtfi.IsReadOnly);

// Instantiate a DateTimeFormatInfo object by calling GetInstance.  
neutral = System.Globalization.CultureInfo.CreateSpecificCulture("fr");
dtfi = System.Globalization.DateTimeFormatInfo.GetInstance(neutral);
Console.WriteLine("{0} from GetInstance: {1}", neutral.Name, dtfi.IsReadOnly);

// The example displays the following output: 
//       fr from Parent property: False 
//       fr from Parent property: False 
//       fr from CultureInfo constructor: False 
//       fr-FR from CreateSpecificCulture: False 
//       fr from GetCultureInfo: True 
//       fr-FR from GetInstance: False      
NoteNote

In the .NET Framework versions 1.0 through .NET Framework 3.5, trying to retrieve a DateTimeFormatInfo object that reflects the formatting conventions of a neutral culture throws a NotSupportedException exception.

However, a neutral culture lacks culture-specific formatting information, because it is independent of a specific country/region. Instead of populating the DateTimeFormatInfo object with generic values, the .NET Framework returns a DateTimeFormatInfo object that reflects the formatting conventions of a specific culture that is a child of the neutral culture. For example, the DateTimeFormatInfo object for the neutral en culture reflects the formatting conventions of the en-US culture, and the DateTimeFormatInfo object for the fr culture reflects the formatting conventions of the fr-FR culture.

You can use code like the following to determine which specific culture's formatting conventions a neutral culture represents. The example uses reflection to compare the DateTimeFormatInfo properties of a neutral culture with the properties of a specific child culture. It considers two calendars to be equivalent if they are the same calendar type and, for Gregorian calendars, if their GregorianCalendar.CalendarType properties have identical values.

using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Reflection;

public class Example
{
   public static void Main()
   {
      // Get all the neutral cultures
      List<String> names = new List<String>();
      Array.ForEach(CultureInfo.GetCultures(CultureTypes.NeutralCultures),
                    culture => names.Add(culture.Name));
      names.Sort();
      foreach (var name in names) {
         // Ignore the invariant culture. 
         if (name == "") continue;

         ListSimilarChildCultures(name);        
      }
   }

   private static void ListSimilarChildCultures(String name)
   {
      // Create the neutral DateTimeFormatInfo object.
      DateTimeFormatInfo dtfi = CultureInfo.GetCultureInfo(name).DateTimeFormat;
      // Retrieve all specific cultures of the neutral culture.
      CultureInfo[] cultures = Array.FindAll(CultureInfo.GetCultures(CultureTypes.SpecificCultures), 
                               culture => culture.Name.StartsWith(name + "-", StringComparison.OrdinalIgnoreCase));
      // Create an array of DateTimeFormatInfo properties
      PropertyInfo[] properties = typeof(DateTimeFormatInfo).GetProperties(BindingFlags.Instance | BindingFlags.Public);
      bool hasOneMatch = false;

      foreach (var ci in cultures) {
         bool match = true;     
         // Get the DateTimeFormatInfo for a specific culture.
         DateTimeFormatInfo specificDtfi = ci.DateTimeFormat;
         // Compare the property values of the two. 
         foreach (var prop in properties) {
            // We're not interested in the value of IsReadOnly.      
            if (prop.Name == "IsReadOnly") continue;

            // For arrays, iterate the individual elements to see if they are the same. 
            if (prop.PropertyType.IsArray) { 
               IList nList = (IList) prop.GetValue(dtfi, null);
               IList sList = (IList) prop.GetValue(specificDtfi, null);
               if (nList.Count != sList.Count) {
                  match = false;
Console.WriteLine("   Different n in {2} array for {0} and {1}", name, ci.Name, prop.Name);
                  break;
               } 

               for (int ctr = 0; ctr < nList.Count; ctr++) {
                  if (! nList[ctr].Equals(sList[ctr])) { 
                     match = false;
Console.WriteLine("   {0} value different for {1} and {2}", prop.Name, name, ci.Name);                     
                     break;
                  }     
               }

               if (! match) break;
            }
            // Get non-array values. 
            else {
               Object specificValue = prop.GetValue(specificDtfi);
               Object neutralValue = prop.GetValue(dtfi);

               // Handle comparison of Calendar objects. 
               if (prop.Name == "Calendar") { 
                  // The cultures have a different calendar type. 
                  if (specificValue.ToString() != neutralValue.ToString()) {
Console.WriteLine("   Different calendar types for {0} and {1}", name, ci.Name);
                     match = false;
                     break;
                  }

                  if (specificValue is GregorianCalendar) {
                     if (((GregorianCalendar) specificValue).CalendarType != ((GregorianCalendar) neutralValue).CalendarType) {
Console.WriteLine("   Different Gregorian calendar types for {0} and {1}", name, ci.Name);
                        match = false;
                        break;
                     }
                  }
               }
               else if (! specificValue.Equals(neutralValue)) {
                  match = false;
Console.WriteLine("   Different {0} values for {1} and {2}", prop.Name, name, ci.Name);                  
                  break;   
               }
            }        
         }
         if (match) {
            Console.WriteLine("DateTimeFormatInfo object for '{0}' matches '{1}'", 
                              name, ci.Name);
            hasOneMatch = true;
         }                                       
      }
      if (! hasOneMatch)
         Console.WriteLine("DateTimeFormatInfo object for '{0}' --> No Match", name);            

      Console.WriteLine();
   }
}

You can instantiate a DateTimeFormatInfo object that represents the formatting conventions of the current culture in the following ways:

  • By retrieving the value of the CurrentInfo property. The returned DateTimeFormatInfo object is read-only.

  • By retrieving the value of the DateTimeFormat property from the CultureInfo object that is returned by the CultureInfo.CurrentCulture property. The returned DateTimeFormatInfo object is read-only.

  • By calling the GetInstance method with a CultureInfo object that represents the current culture. The returned DateTimeFormatInfo object is read-only.

The following example uses each of these methods to instantiate a DateTimeFormatInfo object that represents the formatting conventions of the current culture. It then indicates whether the object is read-only.

DateTimeFormatInfo dtfi;

dtfi = DateTimeFormatInfo.CurrentInfo;
Console.WriteLine(dtfi.IsReadOnly);

dtfi = CultureInfo.CurrentCulture.DateTimeFormat;
Console.WriteLine(dtfi.IsReadOnly);

dtfi = DateTimeFormatInfo.GetInstance(CultureInfo.CurrentCulture);
Console.WriteLine(dtfi.IsReadOnly);
// The example displays the following output: 
//     True 
//     True 
//     True

You can create a writable DateTimeFormatInfo object that represents the conventions of the current thread culture in one of these ways:

  • By retrieving a DateTimeFormatInfo object in any of the three previous ways and calling the Clone method on the returned DateTimeFormatInfo object. This creates a copy of the original DateTimeFormatInfo object, except that its IsReadOnly property is false.

  • By calling the CultureInfo.CreateSpecificCulture method to create a CultureInfo object that represents the current culture, and then using its CultureInfo.DateTimeFormat property to retrieve the DateTimeFormatInfo object.

The following example illustrates each way of instantiating a read/write DateTimeFormatInfo object and displays the value of its IsReadOnly property.

using System;
using System.Globalization;

public class Example
{
   public static void Main()
   {
      DateTimeFormatInfo current1 = DateTimeFormatInfo.CurrentInfo;
      current1 = (DateTimeFormatInfo) current1.Clone();
      Console.WriteLine(current1.IsReadOnly);

      CultureInfo culture2 = CultureInfo.CreateSpecificCulture(CultureInfo.CurrentCulture.Name);
      DateTimeFormatInfo current2 = culture2.DateTimeFormat;
      Console.WriteLine(current2.IsReadOnly);
   }
}
// The example displays the following output: 
//       False 
//       False

In Windows, the user can override some of the DateTimeFormatInfo property values used in formatting and parsing operations through the Region and Language application in Control Panel. For example, a user whose culture is English (United States) might choose to display long time values using a 24-hour clock (in the format HH:mm:ss) instead of the default 12-hour clock (in the format h:mm:ss tt). The DateTimeFormatInfo objects retrieved in the ways discussed previously all reflect these user overrides. If this is undesirable, you can create a NumberFormatInfo object that does not reflect user overrides (and is also read/write instead of read-only) by calling the CultureInfo.CultureInfo(String, Boolean) constructor and supplying a value of false for the useUserOverride argument. The following example illustrates this for a system whose current culture is English (United States) and whose long time pattern has been changed from the default of h:mm:ss tt to HH:mm:ss.

using System;
using System.Globalization;

public class Example
{
   public static void Main()
   {
      CultureInfo culture;
      DateTimeFormatInfo dtfi;

      culture = CultureInfo.CurrentCulture;
      dtfi = culture.DateTimeFormat;
      Console.WriteLine("Culture Name:      {0}", culture.Name);
      Console.WriteLine("User Overrides:    {0}", culture.UseUserOverride);
      Console.WriteLine("Long Time Pattern: {0}\n", culture.DateTimeFormat.LongTimePattern);

      culture = new CultureInfo(CultureInfo.CurrentCulture.Name, false);
      Console.WriteLine("Culture Name:      {0}",   culture.Name);
      Console.WriteLine("User Overrides:    {0}",   culture.UseUserOverride);
      Console.WriteLine("Long Time Pattern: {0}\n", culture.DateTimeFormat.LongTimePattern);
   }
}
// The example displays the following output: 
//       Culture Name:      en-US 
//       User Overrides:    True 
//       Long Time Pattern: HH:mm:ss 
//        
//       Culture Name:      en-US 
//       User Overrides:    False 
//       Long Time Pattern: h:mm:ss tt

DateTimeFormatInfo and dynamic data

The culture-specific data for formatting date and time values provided by the DateTimeFormatInfo class is dynamic, just like cultural data provided by the CultureInfo class. You should not make any assumptions about the stability of values for DateTimeFormatInfo objects that are associated with particular CultureInfo objects. Only the data provided by the invariant culture and its associated DateTimeFormatInfo object is stable. Other data can change between application sessions or even while your application is running. There are four major sources of change:

  • System updates. Cultural preferences such as the preferred calendar or customary date and time formats change over time. When this happens, Windows Update includes changes to the DateTimeFormatInfo property value for a particular culture.

  • Replacement cultures. The CultureAndRegionInfoBuilder class can be used to replace the data of an existing culture.

  • Cascading changes to property values. A number of culture-related properties can change at run time, which, in turn, causes DateTimeFormatInfo data to change. For example, the current culture can be changed either programmatically or through user action. When this happens, the DateTimeFormatInfo object returned by the CurrentInfo property changes to an object associated with the current culture. Similarly, a culture's calendar can change, which can result in changes to numerous DateTimeFormatInfo property values.

  • User preferences. Users of your application might choose to override some of the values associated with the current system culture through the regional and language options in Control Panel. For example, users might choose to display the date in a different format. If the CultureInfo.UseUserOverride property is set to true, the properties of the DateTimeFormatInfo object is also retrieved from the user settings. If the user settings are incompatible with the culture associated with the CultureInfo object (for example, if the selected calendar is not one of the calendars indicated by the OptionalCalendars property), the results of the methods and the values of the properties are undefined.

To minimize the possibility of inconsistent data, all user-overridable properties of a DateTimeFormatInfo object are initialized when the object is created. There is still a possibility of inconsistency, because neither object creation nor the user override process is atomic and the relevant values can change during object creation. However, this situation should be extremely rare.

You can control whether user overrides are reflected in DateTimeFormatInfo objects that represent the same culture as the system culture. The following table lists the ways in which a DateTimeFormatInfo object can be retrieved and indicates whether the resulting object reflects user overrides.

Source of CultureInfo and DateTimeFormatInfo object

Reflects user overrides

CultureInfo.CurrentCulture.DateTimeFormat property

Yes

DateTimeFormatInfo.CurrentInfo property

Yes

CultureInfo.CreateSpecificCulture method

Yes

CultureInfo.GetCultureInfo method

No

CultureInfo.CultureInfo(String) constructor

Yes

CultureInfo.CultureInfo(String, Boolean) constructor

Depends on value of useUserOverride parameter

Unless there is a compelling reason to do otherwise, you should respect user overrides when you use the DateTimeFormatInfo object in client applications to format and parse user input or to display data. For server applications or unattended applications, you should not. However, if you are using the DateTimeFormatInfo object either explicitly or implicitly to persist date and time data in string form, you should either use a DateTimeFormatInfo object that reflects the formatting conventions of the invariant culture, or you should specify a custom date and time format string that you use regardless of culture.

Formatting dates and times

A DateTimeFormatInfo object is used implicitly or explicitly in all date and time formatting operations. These include calls to the following methods:

All date and time formatting operations make use of an IFormatProvider implementation. The IFormatProvider interface includes a single method, IFormatProvider.GetFormat(Type). This callback method is passed a Type object that represents the type needed to provide formatting information. The method returns either an instance of that type or null if it cannot provide an instance of the type. The .NET Framework includes two IFormatProvider implementations for formatting dates and times:

  • The CultureInfo class, which represents a specific culture (or a specific language in a specific country/region). In a date and time formatting operation, the CultureInfo.GetFormat method returns the DateTimeFormatInfo object associated with its CultureInfo.DateTimeFormat property.

  • The DateTimeFormatInfo class, which provides information about the formatting conventions of its associated culture. The DateTimeFormatInfo.GetFormat method returns an instance of itself.

If an IFormatProvider implementation is not provided to a formatting method explicitly, the CultureInfo object returned by the CultureInfo.CurrentCulture property that represents the current thread culture is used.

The following example illustrates the relationship between the IFormatProvider interface and the DateTimeFormatInfo class in formatting operations. It defines a custom IFormatProvider implementation whose GetFormat method displays the type of the object requested by the formatting operation. If it is requesting a DateTimeFormatInfo object, the method provides the DateTimeFormatInfo object for the current thread culture. As the output from the example shows, the Decimal.ToString(IFormatProvider) method requests a DateTimeFormatInfo object to provide formatting information, whereas the String.Format(IFormatProvider, String, Object[]) method requests NumberFormatInfo and DateTimeFormatInfo objects as well as an ICustomFormatter implementation.

using System;
using System.Globalization;

public class CurrentCultureFormatProvider : IFormatProvider
{
   public Object GetFormat(Type formatType) 
   {
      Console.WriteLine("Requesting an object of type {0}", 
                        formatType.Name);
      if (formatType == typeof(NumberFormatInfo))
         return NumberFormatInfo.CurrentInfo;
      else if (formatType == typeof(DateTimeFormatInfo))
         return DateTimeFormatInfo.CurrentInfo;
      else 
         return null;
   }
}

public class Example
{
   public static void Main()
   {
      DateTime dateValue = new DateTime(2013, 5, 28, 12, 30, 0);
      string value = dateValue.ToString("F", new CurrentCultureFormatProvider());
      Console.WriteLine(value);
      Console.WriteLine();
      string composite = String.Format(new CurrentCultureFormatProvider(), 
                                       "Date: {0:d}   Amount: {1:C}   Description: {2}",
                                       dateValue, 1264.03m, "Service Charge");
      Console.WriteLine(composite);
      Console.WriteLine();
   }
}
// The example displays output like the following: 
//       Requesting an object of type DateTimeFormatInfo 
//       Tuesday, May 28, 2013 1:30:00 PM 
//        
//       Requesting an object of type ICustomFormatter 
//       Requesting an object of type DateTimeFormatInfo 
//       Requesting an object of type NumberFormatInfo 
//       Date: 5/28/2013   Amount: $1,264.03   Description: Service Charge

Format strings and DateTimeFormatInfo properties

The DateTimeFormatInfo object includes three kinds of properties that are used in formatting operations with date and time values:

The standard date and time format strings, such as "d", "D", "f", and "F", are aliases that correspond to particular DateTimeFormatInfo format pattern properties. Most of the custom date and time format specifiers are related to strings or substrings that a formatting operation inserts into the result stream. The following table lists the standard and custom date and time format specifiers and their associated DateTimeFormatInfo properties. For details about how to use these format specifiers, see Standard Date and Time Format Strings and Custom Date and Time Format Strings. Note that each standard format string corresponds to a DateTimeFormatInfo property whose value is a custom date and time format string. The individual specifiers in this custom format string in turn correspond to other DateTimeFormatInfo properties. The table lists only the DateTimeFormatInfo properties for which the standard format strings are aliases, and does not list properties that may be accessed by custom format strings assigned to those aliased properties. In addition, the table lists only custom format specifiers that correspond to DateTimeFormatInfo properties.

Format specifier

Associated properties

"d" (short date; standard format string)

ShortDatePattern, to define the overall format of the result string.

"D" (long date; standard format string)

LongDatePattern, to define the overall format of the result string.

"f" (full date / short time; standard format string)

LongDatePattern, to define the format of the date component of the result string.

ShortTimePattern, to define the format of the time component of the result string.

"F" (full date / long time; standard format string)

LongDatePattern, to define the format of the date component of the result string.

LongTimePattern, to define the format of the time component of the result string.

"g" (general date / short time; standard format string)

ShortDatePattern, to define the format of the date component of the result string.

ShortTimePattern, to define the format of the time component of the result string.

"G" (general date / long time; standard format string)

ShortDatePattern, to define the format of the date component of the result string.

LongTimePattern, to define the format of the time component of the result string.

"M", "m" (month/day; standard format string)

MonthDayPattern, to define the overall format of the result string.

"O", "o" (round-trip date/time; standard format string)

None.

"R", "r" (RFC1123; standard format string)

RFC1123Pattern, to define a result string that conforms to the RFC 1123 standard. The property is read-only.

"s" (sortable date/time; standard format string)

SortableDateTimePattern, to define a result string that conforms to the ISO 8601 standard. The property is read-only.

"t" (short time; standard format string)

ShortTimePattern, to define the overall format of the result string.

"T" (long time; standard format string)

LongTimePattern, to define the overall format of the result string.

"u" (universal sortable date/time; standard format string)

UniversalSortableDateTimePattern, to define a result string that conforms to the ISO 8601 standard for coordinated universal time. The property is read-only.

"U" (universal full date/time; standard format string)

FullDateTimePattern, to define the overall format of the result string.

"Y", "y" (year month; standard format string)

YearMonthPattern, to define the overall format of the result string.

"ddd" (custom format specifier)

AbbreviatedDayNames, to include the abbreviated name of the day of the week in the result string.

"g", "gg" (custom format specifier)

Calls the GetEraName method to insert the era name in the result string.

"MMM" (custom format specifier)

AbbreviatedMonthNames, to include the abbreviated month name in the result string.

"MMMM" (custom format specifier)

MonthNames or MonthGenitiveNames, to include the full month name in the result string.

"t" (custom format specifier)

AMDesignator or PMDesignator, to include the first character of the AM/PM designator in the result string.

"tt" (custom format specifier)

AMDesignator or PMDesignator, to include the full AM/PM designator in the result string.

":" (custom format specifier)

TimeSeparator, to include the time separator in the result string.

"/" (custom format specifier)

DateSeparator, to include the date separator in the result string.

Modifying DateTimeFormatInfo properties

You can change the result string produced by date and time format strings by modifying the associated properties of a writable DateTimeFormatInfo object. To determine if a DateTimeFormatInfo object is writable, use the IsReadOnly property. To customize a DateTimeFormatInfo object in this way:

  1. Create a read/write copy of a DateTimeFormatInfo object whose formatting conventions you want to modify. (See the Instantiating a DateTimeFormatInfo object section.)

  2. Modify the property or properties that are used to produce the desired result string. (For information about how formatting methods use DateTimeFormatInfo properties to define result strings, see the previous section, Format strings and DateTimeFormatInfo properties.)

  3. Use the custom DateTimeFormatInfo object you created as the IFormatProvider argument in calls to formatting methods.

There are two other ways to change the fomat of a result string:

  • You can use the CultureAndRegionInfoBuilder class to define either a custom culture (a culture that has a unique name and that supplements existing cultures) or a replacement culture (one that is used instead of a specific culture). You can save and access this culture programmatically as you would any CultureInfo object supported by the .NET Framework.

  • If the result string is not culture-sensitive and doesn't follow a predefined format, you can use a custom date and time format string. For example, if you are serializing date and time data in the format YYYYMMDDHHmmss, you can generate the result string by passing the custom format string to the DateTime.ToString(String) method, and you can convert the result string back to a DateTime value by calling the DateTime.ParseExact method.

The following example changes the format of a result string produced by the "d" (short date) standard format string. It changes the associated ShortDatePattern property for the en-US or English (United States) culture from its default of "M/d/yyyy" to "yyyy'-"MM"-"dd" and uses the "d" standard format string to display the date both before and after the ShortDatePattern property is changed.

using System;
using System.Globalization;

public class Example
{
   public static void Main()
   {
      DateTime dateValue = new DateTime(2013, 8, 18); 
      CultureInfo enUS = CultureInfo.CreateSpecificCulture("en-US");
      DateTimeFormatInfo dtfi = enUS.DateTimeFormat;

      Console.WriteLine("Before modifying DateTimeFormatInfo object: ");
      Console.WriteLine("{0}: {1}\n", dtfi.ShortDatePattern, 
                                    dateValue.ToString("d", enUS));

      // Modify the short date pattern.
      dtfi.ShortDatePattern = "yyyy-MM-dd";
      Console.WriteLine("After modifying DateTimeFormatInfo object: ");
      Console.WriteLine("{0}: {1}", dtfi.ShortDatePattern, 
                                    dateValue.ToString("d", enUS));
   }
}
// The example displays the following output: 
//       Before modifying DateTimeFormatInfo object: 
//       M/d/yyyy: 8/18/2013 
//        
//       After modifying DateTimeFormatInfo object: 
//       yyyy-MM-dd: 2013-08-18

The following example changes the date separator character in a DateTimeFormatInfo object that represents the formatting conventions of the fr-FR culture. The example uses the "g" standard format string to display the date both before and after the DateSeparator property is changed.

using System;
using System.Globalization;

public class Example
{
   public static void Main()
   {
      DateTime dateValue = new DateTime(2013, 08, 28); 
      CultureInfo frFR = CultureInfo.CreateSpecificCulture("fr-FR");
      DateTimeFormatInfo dtfi = frFR.DateTimeFormat;

      Console.WriteLine("Before modifying DateSeparator property: {0}",
                        dateValue.ToString("g", frFR));

      // Modify the date separator.
      dtfi.DateSeparator = "-";
      Console.WriteLine("After modifying the DateSeparator property: {0}",
                        dateValue.ToString("g", frFR));
   }
}
// The example displays the following output: 
//       Before modifying DateSeparator property: 18/08/2013 00:00 
//       After modifying the DateSeparator property: 18-08-2013 00:00

In some cases, the long date pattern, which typically displays the full day and month name along with the number of the day of the month and the year, may be too long. The following example shortens the long date pattern for the en-US culture to return a one-character or two-character day name abbreviation followed by the day number, the month name abbreviation, and the year. It does this by assigning shorter day name abbreviations to the AbbreviatedDayNames array, and by modifying the custom format string assigned to the LongDatePattern property. This affects the result strings returned by the "D" and "f" standard format strings.

using System;
using System.Globalization;

public class Example
{
   public static void Main()
   {
      DateTime value = new DateTime(2013, 7, 9);
      CultureInfo enUS = CultureInfo.CreateSpecificCulture("en-US");
      DateTimeFormatInfo dtfi = enUS.DateTimeFormat;
      String[] formats = { "D", "F", "f" };

      // Display date before modifying properties. 
      foreach (var fmt in formats)
         Console.WriteLine("{0}: {1}", fmt, value.ToString(fmt, dtfi));

      Console.WriteLine();

      // We don't want to change the FullDateTimePattern, so we need to save it.
      String originalFullDateTimePattern = dtfi.FullDateTimePattern;

      // Modify day name abbreviations and long date pattern.
      dtfi.AbbreviatedDayNames = new String[] { "Su", "M", "Tu", "W", "Th", "F", "Sa" };
      dtfi.LongDatePattern = "ddd dd-MMM-yyyy";
      dtfi.FullDateTimePattern = originalFullDateTimePattern;
      foreach (var fmt in formats)
         Console.WriteLine("{0}: {1}", fmt, value.ToString(fmt, dtfi));

   }
}
// The example displays the following output: 
//       D: Tuesday, July 09, 2013 
//       F: Tuesday, July 09, 2013 12:00:00 AM 
//       f: Tuesday, July 09, 2013 12:00 AM 
//        
//       D: Tu 09-Jul-2013 
//       F: Tuesday, July 09, 2013 12:00:00 AM 
//       f: Tu 09-Jul-2013 12:00 AM

Ordinarily, the change to the LongDatePattern property also affects the FullDateTimePattern property, which in turn defines the result string returned by the "F" standard format string. To preserve the original full date and time pattern, the example reassigns the original custom format string assigned to the FullDateTimePattern property after the LongDatePattern property is modified.

For many cultures in the .NET Framework, the time is expressed by using a 12-hour clock and an AM/PM designator. The following example defines a ReplaceWith24HourClock method that replaces any time format that uses a 12-hour clock with a format that uses a 24-hour clock.

using System;
using System.Globalization;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      CultureInfo enUS = CultureInfo.CreateSpecificCulture("en-US");
      DateTimeFormatInfo dtfi = enUS.DateTimeFormat;

      Console.WriteLine("Original Property Values:");
      Console.WriteLine("ShortTimePattern: " + dtfi.ShortTimePattern);
      Console.WriteLine("LongTimePattern: " + dtfi.LongTimePattern);
      Console.WriteLine("FullDateTimePattern: " + dtfi.FullDateTimePattern);
      Console.WriteLine();

      dtfi.LongTimePattern = ReplaceWith24HourClock(dtfi.LongTimePattern);
      dtfi.ShortTimePattern = ReplaceWith24HourClock(dtfi.ShortTimePattern);

      Console.WriteLine("Modififed Property Values:");
      Console.WriteLine("ShortTimePattern: " + dtfi.ShortTimePattern);
      Console.WriteLine("LongTimePattern: " + dtfi.LongTimePattern);
      Console.WriteLine("FullDateTimePattern: " + dtfi.FullDateTimePattern);
   }     

   private static string ReplaceWith24HourClock(string fmt)
   {
      string pattern = @"^(?<openAMPM>\s*t+\s*)? " +
                       @"(?(openAMPM) h+(?<nonHours>[^ht]+)$ " +
                       @"| \s*h+(?<nonHours>[^ht]+)\s*t+)";
      return Regex.Replace(fmt, pattern, "HH${nonHours}", 
                           RegexOptions.IgnorePatternWhitespace);   
   }
}
// The example displays the following output: 
//       Original Property Values: 
//       ShortTimePattern: h:mm tt 
//       LongTimePattern: h:mm:ss tt 
//       FullDateTimePattern: dddd, MMMM dd, yyyy h:mm:ss tt 
//        
//       Modififed Property Values: 
//       ShortTimePattern: HH:mm 
//       LongTimePattern: HH:mm:ss 
//       FullDateTimePattern: dddd, MMMM dd, yyyy HH:mm:ss

The example uses a regular expression to modify the format string. The regular expression pattern @"^(?<openAMPM>\s*t+\s*)? (?(openAMPM) h+(?<nonHours>[^ht]+)$ | \s*h+(?<nonHours>[^ht]+)\s*t+) is defined as follows:

Pattern

Description

^

Begin the match at the beginning of the string.

(?<openAMPM>\s*t+\s*)?

Match zero or one occurrence of zero or more white-space characters, followed by the letter "t" one or more times, followed by zero or more white-space characters. This capturing group is named openAMPM.

(?(openAMPM) h+(?<nonHours>[^ht]+)$

If the openAMPM group has a match, match the letter "h" one or more times, followed by one or more characters that are neither "h" nor "t". The match ends at the end of the string. All characters captured after "h" are included in a capturing group named nonHours.

| \s*h+(?<nonHours>[^ht]+)\s*t+)

If the openAMPM group does not have a match, match the letter "h" one or more times, followed by one or more characters that are neither "h" nor "t", followed by zero or more white-space characters. Finally, match one or more occurrences of the letter "t". All characters captured after "h" and before the white-spaces and "t" are included in a capturing group named nonHours.

The nonHours capturing group contains the minute and possibly the second component of a custom date and time format string, along with any time separator symbols. The replacement pattern HH${nonHours} prepends the substring "HH" to these elements.

The following example adds the "g" custom format specifier to the LongDatePattern property of an object that represents the formatting conventions of the en-US culture. This addition affects the following three standard format strings:

  • The "D" (long date) standard format string, which maps directly to the LongDatePattern property.

  • The "f" (full date / short time) standard format string, which produces a result string that concatenates the substrings produced by the LongDatePattern and ShortTimePattern properties.

  • The "F" (full date / long time) standard format string, which maps directly to the FullDateTimePattern property. Because we have not explicitly set this property value, it is generated dynamically by concatenating the LongDatePattern and LongTimePattern properties.

The example also shows how to change the era name for a culture whose calendar has a single era. In this case, the en-US culture uses the Gregorian calendar, which is represented by a GregorianCalendar object. The GregorianCalendar class supports a single era, which it names A.D. (Anno Domini). The example changes the era name to C.E. (Common Era) by replacing the "g" custom format specifier in the format string assigned to the FullDateTimePatternproperty with a literal string. The use of a literal string is necessary, because the era name is typically returned by the GetEraName method from private data in the culture tables supplied by either the .NET Framework or the Windows operating system.

using System;
using System.Globalization;

public class Example
{
   public static void Main()
   {
      DateTime dateValue = new DateTime(2013, 5, 18, 13, 30, 0);
      String[] formats = { "D", "f", "F" };      

      CultureInfo enUS = CultureInfo.CreateSpecificCulture("en-US");
      DateTimeFormatInfo dtfi = enUS.DateTimeFormat;
      String originalLongDatePattern = dtfi.LongDatePattern;

      // Display the default form of three long date formats. 
      foreach (var fmt in formats)
         Console.WriteLine(dateValue.ToString(fmt, dtfi));

      Console.WriteLine();

      // Modify the long date pattern.
      dtfi.LongDatePattern = originalLongDatePattern + " g";
      foreach (var fmt in formats)
         Console.WriteLine(dateValue.ToString(fmt, dtfi));

      Console.WriteLine();

      // Change A.D. to C.E. (for Common Era)
      dtfi.LongDatePattern = originalLongDatePattern + @" 'C.E.'";
      foreach (var fmt in formats)
         Console.WriteLine(dateValue.ToString(fmt, dtfi));

   }
}
// The example displays the following output: 
//       Saturday, May 18, 2013 
//       Saturday, May 18, 2013 1:30 PM 
//       Saturday, May 18, 2013 1:30:00 PM 
//        
//       Saturday, May 18, 2013 A.D. 
//       Saturday, May 18, 2013 A.D. 1:30 PM 
//       Saturday, May 18, 2013 A.D. 1:30:00 PM 
//        
//       Saturday, May 18, 2013 C.E. 
//       Saturday, May 18, 2013 C.E. 1:30 PM 
//       Saturday, May 18, 2013 C.E. 1:30:00 PM

Parsing date and time strings

Parsing involves converting the string representation of a date and time to a DateTime or DateTimeOffset value. Both of these types include the Parse, TryParse, ParseExact, and TryParseExact methods to support parsing operations. The Parse and TryParse methods convert a string that can have a variety of formats, whereas ParseExact and TryParseExact require that the string have a defined format or formats. If the parsing operation fails, Parse and ParseExact throw an exception, whereas TryParse and TryParseExact return false.

The parsing methods implicitly or explicitly use a DateTimeStyles enumeration value to determine which style elements (such as leading, trailing, or inner white space) can be present in the string to be parsed, and how to interpret the parsed string or any missing elements. If you don't provide a DateTimeStyles value when you call the Parse or TryParse method, the default is DateTimeStyles.AllowWhiteSpaces, which is a composite style that includes the DateTimeStyles.AllowLeadingWhite, DateTimeStyles.AllowTrailingWhite, and DateTimeStyles.AllowInnerWhite flags. For the ParseExact and TryParseExact methods, the default is DateTimeStyles.None; the input string must correspond precisely to a particular custom date and time format string.

The parsing methods also implicitly or explicitly use a DateTimeFormatInfo object that defines the specific symbols and patterns that can occur in the string to be parsed. If you don't provide a DateTimeFormatInfo object, the DateTimeFormatInfo object for the current thread culture is used by default. For more information about parsing date and time strings, see the individual parsing methods, such as DateTime.Parse, DateTime.TryParse, DateTimeOffset.ParseExact, and DateTimeOffset.TryParseExact.

The following example illustrates the culture-sensitive nature of parsing date and time strings. It tries to parse two date strings by using the conventions of the en-US, en-GB, fr-FR, and fi-FI cultures. The date that is interpreted as 8/18/2014 in the en-US culture throws a FormatException exception in the other three cultures because 18 is interpreted as the month number. 1/2/2015 is parsed as the second day of the first month in the en-US culture, but as the first day of the second month in the remaining cultures.

using System;
using System.Globalization;

public class Example
{
   public static void Main()
   {
      string[] dateStrings = { "08/18/2014", "01/02/2015" };
      string[] cultureNames = { "en-US", "en-GB", "fr-FR", "fi-FI" };

      foreach (var cultureName in cultureNames) {
         CultureInfo culture = CultureInfo.CreateSpecificCulture(cultureName);
         Console.WriteLine("Parsing strings using the {0} culture.", 
                           culture.Name);
         foreach (var dateStr in dateStrings) {
            try {
               Console.WriteLine(String.Format(culture, 
                                 "   '{0}' --> {1:D}", dateStr, 
                                 DateTime.Parse(dateStr, culture)));
            }
            catch (FormatException) {
               Console.WriteLine("   Unable to parse '{0}'", dateStr);
            }
         }
      }
   }
}
// The example displays the following output: 
//       Parsing strings using the en-US culture. 
//          '08/18/2014' --> Monday, August 18, 2014 
//          '01/02/2015' --> Friday, January 02, 2015 
//       Parsing strings using the en-GB culture. 
//          Unable to parse '08/18/2014' 
//          '01/02/2015' --> 01 February 2015 
//       Parsing strings using the fr-FR culture. 
//          Unable to parse '08/18/2014' 
//          '01/02/2015' --> dimanche 1 février 2015 
//       Parsing strings using the fi-FI culture. 
//          Unable to parse '08/18/2014' 
//          '01/02/2015' --> 1. helmikuuta 2015

Date and time strings are typically parsed for two reasons:

  • To convert user input into a date and time value.

  • To round-trip a date and time value; that is, to deserialize a date and time value that was previously serialized as a string.

The following sections discuss these two operations in greater detail.

When you parse date and time strings input by the user, you should always instantiate a DateTimeFormatInfo object that reflects the user's cultural settings, including any customizations the user may have made. Otherwise, the date and time object may have incorrect values. For information about how to instantiate a DateTimeFormatInfo object that reflects user cultural customizations, see the DateTimeFormatInfo and dynamic data section.

The following example illustrates the difference between a parsing operation that reflects user cultural settings and one that does not. In this case, the default system culture is en-US, but the user has used Control Panel, Region and Language to change the short date pattern from its default of "M/d/yyyy" to "yy/MM/dd". When the user enters a string that reflects user settings, and the string is parsed by a DateTimeFormatInfo object that also reflects user settings (overrides), the parsing operation returns a correct result. However, when the string is parsed by a DateTimeFormatInfo object that reflects standard en-US cultural settings, the parsing method throws a FormatException exception because it interprets 14 as the number of the month, not the last two digits of the year.

using System;
using System.Globalization;

public class Example
{
   public static void Main()
   {
      string inputDate = "14/05/10";

      CultureInfo[] cultures = { CultureInfo.GetCultureInfo("en-US"), 
                                 CultureInfo.CreateSpecificCulture("en-US") };

      foreach (var culture in cultures) {
         try {
            Console.WriteLine("{0} culture reflects user overrides: {1}", 
                              culture.Name, culture.UseUserOverride);
            DateTime occasion = DateTime.Parse(inputDate, culture);
            Console.WriteLine("'{0}' --> {1}", inputDate, 
                              occasion.ToString("D", CultureInfo.InvariantCulture));
         }
         catch (FormatException) {
            Console.WriteLine("Unable to parse '{0}'", inputDate);                           
         }   
         Console.WriteLine();  
      }
   }
}
// The example displays the following output: 
//       en-US culture reflects user overrides: False 
//       Unable to parse '14/05/10' 
//        
//       en-US culture reflects user overrides: True 
//       '14/05/10' --> Saturday, 10 May 2014

Serialized date and time data are expected to round-trip; that is, all serialized and deserialized values should be identical. If a date and time value represents a single moment in time, the deserialized value should represent the same moment in time regardless of the culture or time zone of the system on which it was restored. To round-trip date and time data successfully, you must use the conventions of the invariant culture, which is returned by the InvariantInfo property, to generate and parse the data. The formatting and parsing operations should never reflect the conventions of the default culture. If you use default cultural settings, the portability of the data is strictly limited; it can be successfully deserialized only on a thread whose cultural-specific settings are identical to those of the thread on which it was serialized. In some cases, this means that the data cannot even be successfully serialized and deserialized on the same system.

If the time component of a date and time value is significant, it should also be converted to UTC and serialized by using the "o" or "r" standard format string. The time data can then be restored by calling a parsing method and passing it the appropriate format string along with the invariant culture as the provider argument.

The following example illustrates the process of round-tripping a date and time value. It serializes a date and time on a system that observes U.S. Pacific time and whose current culture is en-US.

using System;
using System.Globalization;
using System.IO;

public class Example
{
   public static void Main()
   {
      StreamWriter sw = new StreamWriter(@".\DateData.dat");
      // Define a date and time to serialize.
      DateTime originalDate = new DateTime(2014, 08, 18, 08, 16, 35);
      // Display information on the date and time.
      Console.WriteLine("Date to serialize: {0:F}", originalDate);
      Console.WriteLine("Current Culture:   {0}", 
                        CultureInfo.CurrentCulture.Name);
      Console.WriteLine("Time Zone:         {0}", 
                        TimeZoneInfo.Local.DisplayName);
      // Convert the date value to UTC.
      DateTime utcDate = originalDate.ToUniversalTime();
      // Serialize the UTC value.
      sw.Write(utcDate.ToString("o", DateTimeFormatInfo.InvariantInfo));
      sw.Close();
   }
}
// The example displays the following output: 
//       Date to serialize: Monday, August 18, 2014 8:16:35 AM 
//       Current Culture:   en-US 
//       Time Zone:         (UTC-08:00) Pacific Time (US & Canada)

It deserializes the data on a system in the Brussels, Copenhagen, Madrid and Paris time zone and whose current culture is fr-FR. The restored date is nine hours later than the original date, which reflects the time zone adjustment from eight hours behind UTC to one hour ahead of UTC. Both the original date and the restored date represent the same moment in time.

using System;
using System.Globalization;
using System.IO;

public class Example
{
   public static void Main()
   {
      // Open the file and retrieve the date string.
      StreamReader sr = new StreamReader(@".\DateData.dat");             
      String dateValue = sr.ReadToEnd();

      // Parse the date.
      DateTime parsedDate = DateTime.ParseExact(dateValue, "o", 
                            DateTimeFormatInfo.InvariantInfo);
      // Convert it to local time.                             
      DateTime restoredDate = parsedDate.ToLocalTime();
      // Display information on the date and time.
      Console.WriteLine("Deserialized date: {0:F}", restoredDate);
      Console.WriteLine("Current Culture:   {0}", 
                        CultureInfo.CurrentCulture.Name);
      Console.WriteLine("Time Zone:         {0}", 
                        TimeZoneInfo.Local.DisplayName);
   }
}
// The example displays the following output: 
//    Deserialized date: lundi 18 août 2014 17:16:35 
//    Current Culture:   fr-FR 
//    Time Zone:         (UTC+01:00) Brussels, Copenhagen, Madrid, Paris

The following example uses reflection to get the properties of the DateTimeFormatInfo object for the English (United States) culture. It displays the value of those properties that contain custom format strings and uses those strings to display formatted dates.

using System;
using System.Globalization;
using System.Reflection;

public class Example
{
   public static void Main()
   {
      // Get the properties of an en-US DateTimeFormatInfo object.
      DateTimeFormatInfo dtfi = CultureInfo.GetCultureInfo("en-US").DateTimeFormat;
      Type typ = dtfi.GetType();
      PropertyInfo[] props = typ.GetProperties();
      DateTime value = new DateTime(2012, 5, 28, 11, 35, 0); 

      foreach (var prop in props) {
         // Is this a format pattern-related property? 
         if (prop.Name.Contains("Pattern")) {
            string fmt = prop.GetValue(dtfi, null).ToString();
            Console.WriteLine("{0,-33} {1} \n{2,-37}Example: {3}\n", 
                              prop.Name + ":", fmt, "",
                              value.ToString(fmt)); 
         }
      }
   }
}
// The example displays the following output: 
//    FullDateTimePattern:              dddd, MMMM dd, yyyy h:mm:ss tt 
//                                         Example: Monday, May 28, 2012 11:35:00 AM 
//     
//    LongDatePattern:                  dddd, MMMM dd, yyyy 
//                                         Example: Monday, May 28, 2012 
//     
//    LongTimePattern:                  h:mm:ss tt 
//                                         Example: 11:35:00 AM 
//     
//    MonthDayPattern:                  MMMM dd 
//                                         Example: May 28 
//     
//    RFC1123Pattern:                   ddd, dd MMM yyyy HH':'mm':'ss 'GMT' 
//                                         Example: Mon, 28 May 2012 11:35:00 GMT 
//     
//    ShortDatePattern:                 M/d/yyyy 
//                                         Example: 5/28/2012 
//     
//    ShortTimePattern:                 h:mm tt 
//                                         Example: 11:35 AM 
//     
//    SortableDateTimePattern:          yyyy'-'MM'-'dd'T'HH':'mm':'ss 
//                                         Example: 2012-05-28T11:35:00 
//     
//    UniversalSortableDateTimePattern: yyyy'-'MM'-'dd HH':'mm':'ss'Z' 
//                                         Example: 2012-05-28 11:35:00Z 
//     
//    YearMonthPattern:                 MMMM, yyyy 
//                                         Example: May, 2012

.NET Framework

Supported in: 4.5, 4, 3.5, 3.0, 2.0, 1.1, 1.0

.NET Framework Client Profile

Supported in: 4, 3.5 SP1

Portable Class Library

Supported in: Portable Class Library

.NET for Windows Store apps

Supported in: Windows 8

Supported in: Windows Phone 8.1

Supported in: Windows Phone Silverlight 8.1

Supported in: Windows Phone Silverlight 8

Windows Phone 8.1, Windows Phone 8, Windows 8.1, Windows Server 2012 R2, Windows 8, Windows Server 2012, Windows 7, Windows Vista SP2, Windows Server 2008 (Server Core Role not supported), Windows Server 2008 R2 (Server Core Role supported with SP1 or later; Itanium not supported)

The .NET Framework does not support all versions of every platform. For a list of the supported versions, see .NET Framework System Requirements.

Any public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe.
Show:
© 2014 Microsoft