DateTime.ToString ("MM / dd / aaaa HH: mm: ss.fff") resultou em algo como "14/09/2013 07.20.31.371"


131

Eu tenho um aplicativo WP8, que enviará o horário atual para um serviço da web.

Eu recebo a string datetime chamando

DateTime.ToString("MM/dd/yyyy HH:mm:ss.fff")

Para a maioria dos usuários, funciona muito bem e me dá a string correta "09/10/2013 04:04:31.415". Mas para alguns usuários, a sequência resultante é algo como "09/14/2013 07.20.31.371", o que causa problemas no meu serviço da web.

É porque algum problema de formato de cultura? Como garantir que a sequência de resultados seja delimitada por dois pontos em vez de ponto?


2
a única diferença é dois pontos vs ponto.
Eldorado

Respostas:


244

É porque algum problema de formato de cultura?

Sim. Seu usuário deve estar em uma cultura em que o separador de tempo seja um ponto. ":" E "/" são interpretados de maneira sensível à cultura em formatos de data e hora personalizados .

Como garantir que a sequência de resultados seja delimitada por dois pontos em vez de ponto?

Eu sugiro especificar CultureInfo.InvariantCulture:

string text = dateTime.ToString("MM/dd/yyyy HH:mm:ss.fff",
                                CultureInfo.InvariantCulture);

Como alternativa, você pode apenas citar os separadores de hora e data:

string text = dateTime.ToString("MM'/'dd'/'yyyy HH':'mm':'ss.fff");

... mas isso fornecerá resultados "interessantes" que você provavelmente não espera se conseguir usuários executando em uma cultura em que o sistema de calendário padrão não seja o calendário gregoriano. Por exemplo, use o seguinte código:

using System;
using System.Globalization;
using System.Threading;

class Test
{
    static void Main()        
    {
        DateTime now = DateTime.Now;
        CultureInfo culture = new CultureInfo("ar-SA"); // Saudi Arabia
        Thread.CurrentThread.CurrentCulture = culture;
        Console.WriteLine(now.ToString("yyyy-MM-ddTHH:mm:ss.fff"));
    }
} 

Que produz a produção (em 18 de setembro de 2013) de:

11/12/1434 15:04:31.750

Meu palpite é que seu serviço da web ficaria surpreso com isso!

Na verdade, sugiro não apenas usar a cultura invariável, mas também mudar para um formato de data ISO-8601:

string text = dateTime.ToString("yyyy-MM-ddTHH:mm:ss.fff");

Esse é um formato mais aceito globalmente - também é classificável e torna a ordem do mês e do dia óbvia. (Considerando que 06/07/2013 pode ser interpretado como 7 de junho ou 6 de julho, dependendo da cultura do leitor.)


obrigado Jon. Eu pensei que a sequência de resultados seria exatamente como a sequência de formato. Vou tentar sua sugestão.
Eldorado

3
Apenas uma pequena consideração. Ao carregar um objeto CultureInfo a partir de um código específico, sugiro sempre definir o useUserOverrideparâmetro como false, caso contrário, algumas configurações do usuário podem substituir as configurações da cultura. Por exemplo, no seu caso, sugiro usar novo CultureInfo("ar-SA", false).
Davide Icardi 29/10

@DavideIcardi: Interessante, obrigado - embora, neste caso, o objetivo do uso da Arábia Saudita fosse especificamente dizer por que o uso da cultura invariável provavelmente está certo. Terá isso em mente para posts futuros.
quer

7
No meio dessa resposta extensa, comecei a pensar: seria Jon de novo? Sim.
Careta do Desespero

Como gerenciar o mesmo com Html.TextBoxFor (x => x.Date, "{0: MM / dd / aaaa}")?
VISHMAY

9

:tem um significado especial: é o separador de tempo. ( Sequências personalizadas de formato de data e hora ).

Use \para escapar:

DateTime.ToString(@"MM/dd/yyyy HH\:mm\:ss.fff")

Ou use CultureInfo.InvariantCulture:

DateTime.ToString("MM/dd/yyyy HH:mm:ss.fff", CultureInfo.InvariantCulture)

Eu sugeriria ir com o segundo, porque também /tem um significado especial (é o separador de datas. ), Para que você possa ter problemas com isso também.


2
Não é apenas o separador de data de ser um problema - veja a minha resposta para um exemplo da cultura afetando os números reais, também ...
Jon Skeet

1
\ não escapa!
Shereef Marzouk

8

Você pode usar InvariantCulture porque seu usuário deve estar em uma cultura que use um ponto em vez de dois pontos:

DateTime.ToString("MM/dd/yyyy HH:mm:ss.fff", CultureInfo.InvariantCulture);

7

Ultimamente, deparei-me com esse problema com o Windows 10 de outra direção e achei a resposta do @ JonSkeet muito útil para resolver o meu problema.

Também fiz algumas pesquisas adicionais com um formulário de teste e constatei que quando a cultura atual era definida como "no"ou "nb-NO"em tempo de execução ( Thread.CurrentThread.CurrentCulture = new CultureInfo("no");), a chamada ToString ("aaaa-MM-dd HH: mm: ss") respondeu de maneira diferente no Windows 7 e Windows 10. Ele retornou o que eu esperava no Windows 7 e HH.mm.ss no Windows 10!

Eu acho que isso é um pouco assustador! Desde que eu acreditava que uma cultura era uma cultura em qualquer versão do Windows, pelo menos.


Eu ficaria muito curioso para descobrir o que realmente causa isso.
Lauri Peltonen

2
Foi reconhecido e corrigido como um bug de localização do Windows 10. Portanto, uma atualização do Windows na máquina cliente corrigirá o problema. Mais detalhes estão disponíveis neste blog: heikniemi.net/hardcoded/2015/08/...
Håkon Seljåsen

O blog de Jouni Heikniemi, ao qual vinculei acima, parece estar quebrado. As atualizações relevantes do Windows onde os problemas foram corrigidos foram listadas lá: 2015-10-09: KB3093266 - Windows 10 KB3088956 - Windows Server 2012 R2 e Windows 8.1 KB3088955 - Windows Server 2012 e Windows 8 KB3088957 - Windows 7 SP1, Windows Server 2008 SP2 , Windows Server 2008 R2 SP1 e Windows Vista SP2 Tentando criar um link para o blog novamente, desta vez através do archive.org: web.archive.org/web/20161030193739/http://www.heikniemi.net/…
Håkon Seljåsen

4

Você pode usar String.Format:

DateTime d = DateTime.Now;
string str = String.Format("{0:00}/{1:00}/{2:0000} {3:00}:{4:00}:{5:00}.{6:000}", d.Month, d.Day, d.Year, d.Hour, d.Minute, d.Second, d.Millisecond);
// I got this result: "02/23/2015 16:42:38.234"

0

Converter data em sequência

Use o nome Espaço

using System.Globalization;

Código

string date = DateTime.ParseExact(datetext.Text, "dd-MM-yyyy", CultureInfo.InstalledUICulture).ToString("yyyy-MM-dd");

Isto não é como converter uma data em uma string. A análise é o inverso!
Vincent Vancalbergh
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.