Classe DateTimeFormatInfo

Este artigo fornece observações complementares à documentação de referência para esta API.

As propriedades da classe DateTimeFormatInfo contêm informações específicas da cultura para formatar ou analisar valores de data e hora, como os seguintes:

  • Os padrões usados para formatar valores de data.
  • Os padrões usados para formatar valores de hora.
  • Os nomes dos dias da semana.
  • Os nomes dos meses do ano.
  • Os designadores A.M. e P.M. usados em valores de hora.
  • O calendário em que as datas são expressas.

Criar uma instância de um objeto DateTimeFormatInfo

Um objeto DateTimeFormatInfo pode representar as convenções de formatação da cultura invariável, de uma cultura específica, de uma cultura neutra ou da cultura atual. Esta seção discute como instanciar cada tipo de objeto DateTimeFormatInfo.

Criar uma instância de um objeto DateTimeFormatInfo para a cultura invariável

A cultura invariável representa uma cultura insensível. Baseia-se na língua inglesa, mas não em nenhum país/região de língua inglesa específico. Embora os dados de culturas específicas possam ser dinâmicos e possam mudar para refletir novas convenções culturais ou preferências do usuário, os dados da cultura invariável não mudam. Você pode criar uma instância de um objeto DateTimeFormatInfo que represente as convenções de formatação da cultura invariável das seguintes maneiras:

O exemplo a seguir usa cada um desses métodos para instanciar um objeto DateTimeFormatInfo que representa a cultura invariável. Depois, ele indica se o objeto é somente leitura.

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

Criar uma instância de um objeto DateTimeFormatInfo para uma cultura específica

Uma cultura específica representa um idioma que é falado em um determinado país/região. Por exemplo, en-US é uma cultura específica que representa o idioma inglês falado nos Estados Unidos, e en-CA é uma cultura específica que representa o idioma inglês falado no Canadá. Você pode criar uma instância de um objeto DateTimeFormatInfo que represente as convenções de formatação de uma cultura específica das seguintes maneiras:

O exemplo a seguir ilustra cada uma dessas maneiras de criar uma instância de um objeto DateTimeFormatInfo e indica se o objeto resultante é somente leitura.

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

Criar uma instância de um objeto DateTimeFormatInfo para uma cultura neutra

Uma cultura neutra representa uma cultura ou língua que é independente de um país/região e é tipicamente o pai de uma ou mais culturas específicas. Por exemplo, Fr é uma cultura neutra para a língua francesa e é o pai da cultura fr-FR. Você pode criar uma instância de um objeto DateTimeFormatInfo que representa as convenções de formatação de uma cultura neutra da mesma forma que cria um objeto DateTimeFormatInfo que representa as convenções de formatação de uma cultura específica. Além disso, você pode recuperar o objeto DateTimeFormatInfo de uma cultura neutra recuperando uma cultura neutra da propriedade CultureInfo.Parent de uma cultura específica e recuperando o objeto DateTimeFormatInfo retornado pela respectiva propriedade CultureInfo.DateTimeFormat. A menos que a cultura pai represente a cultura invariável, o objeto DateTimeFormatInfo retornado é de leitura/gravação. O exemplo a seguir ilustra essas maneiras de instanciar um objeto DateTimeFormatInfo que representa uma cultura neutra.

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

No entanto, uma cultura neutra carece de informações de formatação específica a uma cultura, porque é independente de um país/região específico. Em vez de preencher o objeto DateTimeFormatInfo com valores genéricos, o .NET retorna um objeto DateTimeFormatInfo que reflete as convenções de formatação de uma cultura específica que é filha da cultura neutra. Por exemplo, o objeto DateTimeFormatInfo para a cultura neutra en reflete as convenções de formatação da cultura en-US, e o objeto DateTimeFormatInfo para a cultura fr reflete as convenções de formatação da cultura fr-FR.

Você pode usar um código como o mostrado a seguir para determinar qual é a cultura específica cujas convenções de formatação são representadas por uma determinada cultura neutra. O exemplo usa a reflexão para comparar as propriedades DateTimeFormatInfo de uma cultura neutra com as propriedades de uma cultura filho específica. Ele considera dois calendários equivalentes se forem do mesmo tipo de calendário e, para calendários gregorianos, se as respectivas propriedades GregorianCalendar.CalendarType tiverem valores idênticos.

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

public class InstantiateEx6
{
    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();
    }
}

Criar uma instância de um objeto DateTimeFormatInfo para a cultura atual

Você pode criar uma instância de um objeto DateTimeFormatInfo que representa as convenções de formatação da cultura invariável das seguintes maneiras:

O exemplo a seguir usa cada um desses métodos para criar uma instância de um objeto DateTimeFormatInfo que representa as convenções de formatação da cultura atual. Depois, ele indica se o objeto é somente leitura.

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

Você pode criar um objeto gravável DateTimeFormatInfo que represente as convenções da cultura atual de uma destas maneiras:

O exemplo a seguir ilustra cada maneira de instanciar um objeto DateTimeFormatInfo de leitura/gravação e exibe o valor da respectiva propriedade IsReadOnly.

using System;
using System.Globalization;

public class InstantiateEx1
{
    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

No Windows, o usuário pode substituir alguns dos valores da propriedade DateTimeFormatInfo usados em operações de formatação e análise por meio do aplicativo Região e Idioma no Painel de Controle. Por exemplo, um usuário cuja cultura é Inglês (Estados Unidos) pode optar por exibir valores de hora longos usando um relógio de 24 horas (no formato HH:mm:ss) em vez do relógio padrão de 12 horas (no formato h:mm:ss tt). Os objetos DateTimeFormatInfo recuperados das formas discutidas anteriormente refletem essas substituições do usuário. Se isso não for desejável, é possível criar um objeto NumberFormatInfo que não reflita as substituições do usuário (e que também seja de leitura/gravação em vez de somente leitura) chamando o construtor CultureInfo.CultureInfo(String, Boolean) e fornecendo um valor false para o argumento useUserOverride. O exemplo a seguir ilustra isso para um sistema cuja cultura atual é Inglês (Estados Unidos) e cujo padrão de hora longa foi alterado do padrão h:mm:ss tt para HH:mm:ss.

using System;
using System.Globalization;

public class InstantiateEx3
{
    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 e dados dinâmicos

Os dados específicos da cultura para a formatação de valores numéricos fornecidos pela classe DateTimeFormatInfo são dinâmicos, assim como os dados culturais fornecidos pela classe CultureInfo. Você não deve fazer nenhuma suposição sobre a estabilidade dos valores dos objetos DateTimeFormatInfo que estão associados a objetos CultureInfo específicos. Somente os dados fornecidos pela cultura invariável e seu objeto DateTimeFormatInfo associado são estáveis. Outros dados podem ser alterados entre sessões do aplicativo ou até mesmo enquanto o aplicativo está em execução. Existem quatro fontes principais de mudança:

  • Atualizações do sistema. As preferências culturais, como o calendário preferido ou os formatos habituais de data e hora, mudam com o tempo. Quando isso acontece, o Windows Update inclui alterações no valor da propriedade DateTimeFormatInfo para uma cultura específica.

  • Culturas de substituição. A classe CultureAndRegionInfoBuilder pode ser usada para substituir os dados de uma cultura existente.

  • Alterações em cascata nos valores das propriedades. Várias propriedades relacionadas à cultura podem ser alteradas em tempo de execução, o que, por sua vez, faz com que os dados DateTimeFormatInfo sejam alterados. Por exemplo, a cultura atual pode ser alterada de maneira programática ou por meio da ação do usuário. Quando isso acontece, o objeto DateTimeFormatInfo retornado pela propriedade CurrentInfo é alterado para um objeto associado à cultura atual. Da mesma forma, o calendário de uma cultura pode mudar, o que pode resultar em alterações em vários valores de propriedade DateTimeFormatInfo.

  • Preferências do usuário. Os usuários do seu aplicativo podem optar por substituir alguns dos valores associados à cultura atual do sistema por meio das opções de região e idioma no Painel de Controle. Por exemplo, os usuários podem optar por exibir a data em um formato diferente. Se a propriedade CultureInfo.UseUserOverride for definida como true, as propriedades do objeto DateTimeFormatInfo também serão recuperadas das configurações do usuário. Se as configurações do usuário forem incompatíveis com a cultura associada ao objeto CultureInfo (por exemplo, se o calendário selecionado não for um dos calendários indicados pela propriedade OptionalCalendars), os resultados dos métodos e os valores das propriedades serão indefinidos.

Para minimizar a possibilidade de dados inconsistentes, todas as propriedades substituíveis pelo usuário de um objeto DateTimeFormatInfo são inicializadas quando o objeto é criado. Ainda existe a possibilidade de inconsistência, pois nem a criação do objeto nem o processo de substituição do usuário são atômicos, e os valores relevantes podem ser alterados durante a criação do objeto. No entanto, essa situação deve ser extremamente rara.

É possível controlar se as substituições do usuário são refletidas em objetos DateTimeFormatInfo que representam a mesma cultura que a cultura do sistema. A tabela a seguir lista as maneiras pelas quais um objeto DateTimeFormatInfo pode ser recuperado e indica se o objeto resultante reflete as substituições do usuário.

Origem do objeto CultureInfo e DateTimeFormatInfo Reflete as substituições do usuário
Propriedade CultureInfo.CurrentCulture.DateTimeFormat Sim
Propriedade DateTimeFormatInfo.CurrentInfo Sim
Método CultureInfo.CreateSpecificCulture Sim
Método CultureInfo.GetCultureInfo Não
Construtor CultureInfo.CultureInfo(String) Sim
Construtor CultureInfo.CultureInfo(String, Boolean) Depende do valor do parâmetro useUserOverride

A menos que haja um motivo convincente para fazer o contrário, você deve respeitar as substituições do usuário ao usar o objeto DateTimeFormatInfo em aplicativos clientes para formatar e analisar a entrada do usuário ou exibir dados. Para aplicativos de servidor ou aplicativos não supervisionados, você não deve fazê-lo. No entanto, se você estiver usando o objeto DateTimeFormatInfo explícita ou implicitamente para manter dados de data e hora em forma de cadeia de caracteres, você deverá usar um objeto DateTimeFormatInfo que reflita as convenções de formatação da cultura invariável ou especificar uma cadeia de formato de data e hora personalizado que será usada independentemente da cultura.

Formatar datas e horários

Um objeto DateTimeFormatInfo é usado implícita ou explicitamente em todas as operações de formatação de data e hora. Isso inclui as chamadas para os seguintes métodos:

Todas as operações de formatação de data e hora fazem uso de uma implementação de IFormatProvider. A interface IFormatProvider inclui apenas um método, IFormatProvider.GetFormat(Type). Esse é um método de retorno de chamada que recebe um objeto Type que representa o tipo necessário para fornecer informações de formatação. O método retornará uma instância desse tipo ou então null, se ele não puder fornecer uma instância do tipo. O .NET inclui duas IFormatProvider implementações para formatar datas e horários:

Se uma implementação IFormatProvider não for fornecida explicitamente a um método de formatação, será usado o objeto CultureInfo retornado pela propriedade CultureInfo.CurrentCulture que representa a cultura atual.

O exemplo a seguir ilustra a relação entre a interface IFormatProvider e a classe DateTimeFormatInfo em operações de formatação. Ele define uma implementação personalizada de IFormatProvider cujo método GetFormat exibe o tipo do objeto solicitado pela operação de formatação. Se a interface estiver solicitando um objeto DateTimeFormatInfo, esse método fornecerá o objeto DateTimeFormatInfo para a cultura atual. Como mostra a saída do exemplo, o método Decimal.ToString(IFormatProvider) solicita um objeto DateTimeFormatInfo para fornecer informações de formatação, enquanto o método String.Format(IFormatProvider, String, Object[]) solicita objetos NumberFormatInfo e DateTimeFormatInfo, bem como uma implementação de ICustomFormatter.

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 FormatProviderEx1
{
    public static void Main()
    {
        DateTime dateValue = new DateTime(2013, 5, 28, 13, 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

Cadeias de caracteres de formato e propriedades DateTimeFormatInfo

O objeto DateTimeFormatInfo inclui três tipos de propriedades que são usadas em operações de formatação com valores de data e hora:

As cadeias de caracteres de formato de data e hora padrão, como "d", "D", "f" e "F", são aliases que correspondem a propriedades de padrão de formato DateTimeFormatInfo específicas. A maioria das cadeias de caracteres de formato de data e hora personalizado estão relacionadas a cadeias de caracteres ou substrings que uma operação de formatação insere no fluxo de resultados. A tabela a seguir lista os especificadores de formato de data e hora padrão e personalizado e as respectivas propriedades DateTimeFormatInfo associadas. Para obter detalhes sobre como usar esses especificadores de formato, confira Cadeias de caracteres de formato de data e hora padrão e Cadeias de caracteres de formato de data e hora personalizado. Observe que cada cadeia de caracteres de formato padrão corresponde a uma propriedade DateTimeFormatInfo cujo valor é uma cadeia de caracteres de formato de data e hora personalizado. Os especificadores individuais nessa cadeia de caracteres de formato personalizado, por sua vez, correspondem a outras propriedades DateTimeFormatInfo. A tabela lista apenas as propriedades DateTimeFormatInfo para as quais as cadeias de caracteres de formato padrão são aliases. Ela não lista propriedades que podem ser acessadas por cadeias de caracteres de formato personalizado atribuídas a essas propriedades com alias. Além disso, a tabela lista apenas especificadores de formato personalizados que correspondem às propriedades DateTimeFormatInfo.

Especificador de formato Propriedades associadas
"d" (data abreviada; cadeia de caracteres de formato padrão) ShortDatePattern, para definir o formato geral da cadeia de caracteres de resultado.
"D" (data longa; cadeia de caracteres de formato padrão) LongDatePattern, para definir o formato geral da cadeia de caracteres de resultado.
"f" (data completa/hora abreviada; cadeia de caracteres de formato padrão) LongDatePattern, para definir o formato do componente de data da cadeia de caracteres de resultado.

ShortTimePattern, para definir o formato do componente de hora da cadeia de caracteres de resultado.
"F" (data completa/hora longa; cadeia de caracteres de formato padrão) LongDatePattern, para definir o formato do componente de data da cadeia de caracteres de resultado.

LongTimePattern, para definir o formato do componente de hora da cadeia de caracteres de resultado.
"g" (data geral/hora abreviada; cadeia de caracteres de formato padrão) ShortDatePattern, para definir o formato do componente de data da cadeia de caracteres de resultado.

ShortTimePattern, para definir o formato do componente de hora da cadeia de caracteres de resultado.
"G" (data geral/hora longa; cadeia de caracteres de formato padrão) ShortDatePattern, para definir o formato do componente de data da cadeia de caracteres de resultado.

LongTimePattern, para definir o formato do componente de hora da cadeia de caracteres de resultado.
"M", "m" (mês/dia; cadeia de caracteres de formato padrão) MonthDayPattern, para definir o formato geral da cadeia de caracteres de resultado.
"O", "o" (data/hora enviadas e recebidas de volta; cadeia de caracteres de formato padrão) Nenhum.
"R", "r" (RFC1123; cadeia de caracteres de formato padrão) RFC1123Pattern, para definir uma cadeia de caracteres de resultado que esteja em conformidade com o padrão RFC 1123. a propriedade é somente leitura.
"s" (data/hora classificável; cadeia de caracteres de formato padrão) SortableDateTimePattern, para definir uma cadeia de caracteres de resultado que esteja em conformidade com o padrão ISO 8601. a propriedade é somente leitura.
"t" (hora abreviada; cadeia de caracteres de formato padrão) ShortTimePattern, para definir o formato geral da cadeia de caracteres de resultado.
"T" (hora longa; cadeia de caracteres de formato padrão) LongTimePattern, para definir o formato geral da cadeia de caracteres de resultado.
"u" (data/hora universal classificável; cadeia de caracteres de formato padrão) UniversalSortableDateTimePattern, para definir uma cadeia de caracteres de resultado que esteja em conformidade com o padrão ISO 8601 para tempo universal coordenado. a propriedade é somente leitura.
"U" (data/hora universais completas; cadeia de caracteres de formato padrão) FullDateTimePattern, para definir o formato geral da cadeia de caracteres de resultado.
"Y", "y" (ano, mês; cadeia de caracteres de formato padrão) YearMonthPattern, para definir o formato geral da cadeia de caracteres de resultado.
"ddd" (especificador de formato personalizado) AbbreviatedDayNames, para incluir o nome abreviado do dia da semana na cadeia de caracteres de resultados.
"g", "gg" (especificador de formato personalizado) Chama o método GetEraName para inserir o nome da era na cadeia de caracteres de resultado.
"MMM" (especificador de formato personalizado) AbbreviatedMonthNames, para incluir o nome abreviado do mês na cadeia de caracteres de resultado.
"MMMM" (especificador de formato personalizado) MonthNames ou MonthGenitiveNames, para incluir o nome completo do mês na cadeia de caracteres de resultado.
"t" (especificador de formato personalizado) AMDesignator ou PMDesignator, para incluir o primeiro caractere do designador AM/PM na cadeia de caracteres de resultado.
"tt" (especificador de formato personalizado) AMDesignator ou PMDesignator, para incluir o designador AM/PM completo na cadeia de caracteres de resultados.
":" (especificador de formato personalizado) TimeSeparator, para incluir o separador de hora na cadeia de caracteres de resultado.
"/" (especificador de formato personalizado) DateSeparator, para incluir o separador de data na cadeia de caracteres de resultado.

Modificar as propriedades DateTimeFormatInfo

Você pode alterar a cadeia de caracteres de resultado produzida por cadeias de caracteres de formato de data e hora modificando as propriedades associadas de um objeto gravável DateTimeFormatInfo. Para determinar se um objeto DateTimeFormatInfo é gravável, use a propriedade IsReadOnly. Para personalizar um objeto DateTimeFormatInfo desta maneira:

  1. Crie uma cópia de leitura/gravação de um objeto DateTimeFormatInfo cujas convenções de formatação você deseja modificar.

  2. Modificar a propriedade ou as propriedades usadas para produzir a cadeia de caracteres do resultado desejado. (Para obter informações sobre como os métodos de formatação usam propriedades DateTimeFormatInfo para definir cadeias de resultados, confira a seção anterior, Formatar cadeias de caracteres e propriedades DateTimeFormatInfo.)

  3. Use o objeto DateTimeFormatInfo personalizado que você criou como o argumento IFormatProvider nas chamadas para métodos de formatação.

Há duas outras maneiras de alterar o formato de uma cadeia de caracteres de resultado:

  • Você pode usar a classe CultureAndRegionInfoBuilder para definir uma cultura personalizada (uma cultura que tem um nome exclusivo e que complementa as culturas existentes) ou uma cultura de substituição (uma que é usada em vez de uma cultura específica). Você pode salvar e acessar essa cultura programaticamente como faria com qualquer objeto CultureInfo compatível com o .NET.

  • Se a cadeia de caracteres de resultado não diferenciar a cultura e não seguir um formato predefinido, você poderá usar uma cadeia de caracteres de formato de data e hora personalizado. Por exemplo, se você estiver serializando dados de data e hora no formato AAAAMMDDHHmmss, poderá gerar a cadeia de caracteres de resultado passando a cadeia de caracteres de formato personalizado para o método DateTime.ToString(String) e poderá converter a cadeia de caracteres de resultado de volta em um valor DateTime chamando o método DateTime.ParseExact.

Alterando o padrão de data abreviada

O exemplo a seguir altera o formato de uma cadeia de caracteres de resultado produzida pela cadeia de caracteres de formato padrão "d" (data abreviada). Ele altera a propriedade associada ShortDatePattern para a cultura en-US ou Inglês (Estados Unidos) de seu padrão de "M/d/aaaa" para "aaaa'-"MM"-"dd" e usa a cadeia de caracteres de formato padrão "d" para exibir a data antes e depois que a propriedade ShortDatePattern é alterada.

using System;
using System.Globalization;

public class Example1
{
    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

Alterar o caractere separador de data

O exemplo a seguir altera o caractere separador de data em um objeto DateTimeFormatInfo que representa as convenções de formatação da cultura fr-FR. O exemplo usa a cadeia de caracteres de formato padrão "g" para exibir a data antes e depois que a propriedade DateSeparator é alterada.

using System;
using System.Globalization;

public class Example3
{
    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: 28/08/2013 00:00
//       After modifying the DateSeparator property: 28-08-2013 00:00

Alterar abreviações do nome do dia e o padrão de data longa

Em alguns casos, o padrão de data longa, que normalmente exibe o nome completo do dia e do mês junto com o número do dia do mês e do ano, pode ser longo demais. O exemplo a seguir encurta o padrão de data longa para a cultura en-US para retornar uma abreviação de nome de dia de um ou dois caracteres seguida pelo número do dia, a abreviação do nome do mês e o ano. Ele faz isso atribuindo abreviações de nome de dia mais curtas à matriz e modificando a cadeia de caracteres de formato personalizado AbbreviatedDayNames atribuída à propriedade LongDatePattern. Isso afeta as cadeias de caracteres de resultado retornadas pelas cadeias de caracteres de formato padrão "D" e "f".

using System;
using System.Globalization;

public class Example2
{
    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 9, 2013
//       F: Tuesday, July 9, 2013 12:00:00 AM
//       f: Tuesday, July 9, 2013 12:00 AM
//
//       D: Tu 09-Jul-2013
//       F: Tuesday, July 9, 2013 12:00:00 AM
//       f: Tu 09-Jul-2013 12:00 AM

Normalmente, a alteração na propriedade LongDatePattern também afeta a propriedade FullDateTimePattern, que por sua vez define a cadeia de caracteres de resultado retornada pela cadeia de caracteres de formato padrão "F". Para preservar o padrão de data e hora completas original, o exemplo reatribui a cadeia de caracteres de formato personalizado original atribuída à propriedade FullDateTimePattern depois que a propriedade LongDatePattern é modificada.

Alterar de um relógio de 12 horas para um relógio de 24 horas

Para muitas culturas no .NET, a hora é expressa usando um relógio de 12 horas e um designador AM/PM. O exemplo a seguir define um método ReplaceWith24HourClock que substitui qualquer formato de hora que usa um relógio de 12 horas por um formato que usa um relógio de 24 horas.

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

public class Example5
{
    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

O exemplo usa uma expressão regular para modificar a cadeia de caracteres de formato. O padrão de expressão regular, @"^(?<openAMPM>\s*t+\s*)? (?(openAMPM) h+(?<nonHours>[^ht]+)$ | \s*h+(?<nonHours>[^ht]+)\s*t+), é definido da seguinte forma:

Padrão Descrição
^ Começar a correspondência no início da cadeia de caracteres.
(?<openAMPM>\s*t+\s*)? Corresponder zero ou uma ocorrência de zero ou mais caracteres de espaço em branco, seguido pela letra "t" uma ou mais vezes, seguido por zero ou mais caracteres de espaço em branco. Esse grupo de captura é denominado openAMPM.
(?(openAMPM) h+(?<nonHours>[^ht]+)$ Se o grupo openAMPM tiver uma correspondência, corresponda a letra "h" uma ou mais vezes, seguida por um ou mais caracteres que não são nem "h" nem "t". Encerrar a correspondência ao final da cadeia de caracteres. Todos os caracteres capturados após "h" são incluídos em um grupo de captura chamado nonHours.
&#124; \s*h+(?<nonHours>[^ht]+)\s*t+) Se o grupo openAMPM não tiver uma correspondência, corresponda à letra "h" uma ou mais vezes, seguida por um ou mais caracteres que não são nem "h" nem "t", seguidos por zero ou mais caracteres de espaço em branco. Por fim, combine uma ou mais ocorrências da letra "t". Todos os caracteres capturados após "h" e antes dos espaços em branco e "t" são incluídos em um grupo de captura chamado nonHours.

O grupo de captura nonHours contém o minuto e, possivelmente, o segundo componente de uma cadeia de caracteres de formato de data e hora personalizado, juntamente com quaisquer símbolos de separador de hora. O padrão HH${nonHours} de substituição precede a substring "HH" a esses elementos.

Exibir e alterar a era em uma data

O exemplo a seguir adiciona o especificador de formato personalizado "g" à propriedade LongDatePattern de um objeto que representa as convenções de formatação da cultura en-US. Essa adição afeta as três seguintes cadeias de caracteres de formato padrão:

  • A cadeia de caracteres de formato padrão "D" (data longa), que mapeia diretamente para a propriedade LongDatePattern.

  • A cadeia de caracteres de formato padrão "f" (data completa/hora abreviada), que produz uma cadeia de caracteres de resultado que concatena as substrings produzidas pelas propriedades LongDatePattern e ShortTimePattern.

  • A cadeia de caracteres de formato padrão "F" (data completa/hora longa), que mapeia diretamente para a propriedade FullDateTimePattern. Como não definimos explicitamente esse valor da propriedade, ele é gerado dinamicamente concatenando as propriedades LongDatePattern e LongTimePattern.

O exemplo também mostra como alterar o nome da era de uma cultura cujo calendário tem apenas uma era. Nesse caso, a cultura en-US usa o calendário gregoriano, que é representado por um objeto GregorianCalendar. A classe GregorianCalendar dá suporte a apenas uma era, que ela chama de A.D. (Anno Domini). O exemplo altera o nome da era para C.E. (Era Comum) substituindo o especificador de formato personalizado "g" na cadeia de caracteres de formato atribuída à propriedade FullDateTimePattern por uma cadeia de caracteres literal. O uso de uma cadeia de caracteres literal é necessário, porque o nome da era normalmente é retornado pelo método GetEraName de dados particulares nas tabelas de cultura fornecidas pelo .NET ou pelo sistema operacional.

using System;
using System.Globalization;

public class Example4
{
    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

Analisar as cadeias de caracteres de data e hora

A análise envolve a conversão da representação da cadeia de caracteres de uma data e hora em um valor DateTime ou DateTimeOffset. Ambos os tipos incluem os métodos Parse, TryParse, ParseExact e TryParseExact para dar suporte a operações de análise. Os métodos Parse e TryParse convertem uma cadeia de caracteres que pode ter uma variedade de formatos, enquanto ParseExact e TryParseExact exigem que a cadeia de caracteres tenha um formato ou formatos definidos. Se a operação de análise falha, Parse e ParseExact geram ma exceção, enquanto TryParse e TryParseExact retornam false.

Os métodos de análise usam implícita ou explicitamente um valor de enumeração DateTimeStyles para determinar quais elementos de estilo (como espaços à direita, à esquerda ou espaço em branco interno) podem estar presentes na cadeia de caracteres a ser analisada e como interpretar a cadeia de caracteres analisada ou quaisquer elementos ausentes. Se você não fornecer um valor DateTimeStyles ao chamar o método Parse ou TryParse, o valor será DateTimeStyles.AllowWhiteSpaces, que é um estilo composto que inclui os sinalizadores DateTimeStyles.AllowLeadingWhite, DateTimeStyles.AllowTrailingWhite e DateTimeStyles.AllowInnerWhite. Para os métodos ParseExact e TryParseExact, o padrão é DateTimeStyles.None; a cadeia de caracteres de entrada precisa corresponder precisamente a uma determinada cadeia de caracteres de formato de data e hora personalizado.

Os métodos de análise também usam, implícita ou explicitamente, um objeto DateTimeFormatInfo que define os símbolos e padrões específicos que podem ocorrer na cadeia de caracteres a ser analisada. Se você não fornecer um objeto DateTimeFormatInfo, o objeto DateTimeFormatInfo para a cultura atual será usado por padrão. Para obter mais informações sobre análise de cadeias de caracteres de data e hora, confira os métodos de análise individuais, como DateTime.Parse, DateTime.TryParse, DateTimeOffset.ParseExact e DateTimeOffset.TryParseExact.

O exemplo a seguir ilustra a natureza da análise de cadeias de caracteres, que diferencia culturas. Ele tenta analisar duas cadeias de caracteres de data usando as convenções das culturas en-US, en-GB, fr-FR e fi-FI. A data que é interpretada como 18/8/2014 na cultura en-US gera uma exceção FormatException nas outras três culturas porque 18 é interpretado como o número do mês. 2/1/2015 é analisado como o segundo dia do primeiro mês na cultura en-US, mas como o primeiro dia do segundo mês nas culturas restantes.

using System;
using System.Globalization;

public class ParseEx1
{
    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

As cadeias de caracteres de data e hora são normalmente analisadas por dois motivos:

  • Para converter a entrada do usuário em um valor de data e hora.
  • Para um valor de data e hora enviado e recebido de volta; ou seja, para desserializar um valor de data e hora que foi serializado anteriormente como uma cadeia de caracteres.

As seções a seguir discutem essas duas operações em mais detalhes.

Analisar cadeias de caracteres do usuário

Ao analisar cadeias de caracteres de data e hora inseridas pelo usuário, você deve sempre criar uma instância de um objeto DateTimeFormatInfo que reflita as configurações culturais do usuário, incluindo quaisquer personalizações que o usuário possa ter feito. Caso contrário, o objeto de data e hora pode ter valores incorretos. Para obter informações sobre como criar uma instância de um objeto DateTimeFormatInfo que reflita as personalizações culturais do usuário, consulte a seção DateTimeFormatInfo e dados dinâmicos.

O exemplo a seguir ilustra a diferença entre uma operação de análise que reflete as configurações culturais do usuário e uma que não reflete. Nesse caso, a cultura padrão do sistema é en-US, mas o usuário usou o Painel de Controle, Região e Idioma para alterar o padrão de data abreviada do respectivo padrão de "M/d/aaaa" para "aaa/MM/dd". Quando o usuário digita uma cadeia de caracteres que reflete as configurações do usuário e a cadeia de caracteres é analisada por um objeto DateTimeFormatInfo que também reflete as configurações do usuário (substituições), a operação de análise retorna um resultado correto. No entanto, quando a cadeia de caracteres é analisada por um objeto DateTimeFormatInfo que reflete as configurações culturais padrão en-US, o método de análise gera uma exceção FormatException porque interpreta 14 como o número do mês, não os dois últimos dígitos do ano.

using System;
using System.Globalization;

public class ParseEx2
{
    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

Serializar e desserializar dados de data e hora

Espera-se que os dados serializados de data e hora façam uma viagem de ida e volta; ou seja, todos os valores serializados e desserializados devem ser idênticos. Se um valor de data e hora representar apenas um momento no tempo, o valor desserializado deverá representar o mesmo momento no tempo, independentemente da cultura ou do fuso horário do sistema no qual foi restaurado. Para enviar e receber de volta dados de data e hora com êxito, você precisa usar as convenções da cultura invariável, que é retornada pela propriedade InvariantInfo, para gerar e analisar os dados. As operações de formatação e análise nunca devem refletir as convenções da cultura padrão. Se você usar configurações de cultura padrão, a portabilidade dos dados será estritamente limitada; eles só poderão ser desserializados com sucesso em um thread cujas configurações específicas a uma cultura sejam idênticas às do thread em que foram serializados. Em alguns casos, isso significa que os dados não podem nem mesmo ser serializados e desserializados com êxito no mesmo sistema.

Se o componente de hora de um valor de data e hora for significativo, ele também deverá ser convertido em UTC e serializado usando a cadeia de caracteres de formato padrão "o" ou "r". Os dados de hora podem ser restaurados chamando um método de análise e passando-lhe a cadeia de caracteres de formato apropriada junto com a cultura invariável como o argumento provider.

O exemplo a seguir ilustra o processo de enviar e receber de volta um valor de data e hora. Ele serializa uma data e hora em um sistema que observa a hora do Pacífico dos EUA e cuja cultura atual é en-US.

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

public class SerializeEx1
{
    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)

Ele desserializa os dados de um sistema no fuso horário de Bruxelas, Copenhague, Madri e Paris e cuja cultura atual é fr-FR. A data restaurada é nove horas mais tarde do que a data original, o que reflete o ajuste de fuso horário de oito horas de atraso em relação ao UTC para uma hora de antecedência em relação ao UTC. Tanto a data original quanto a data restaurada representam o mesmo momento no tempo.

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

public class SerializeEx2
{
    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