DateTime.ToString("MM/dd/yyyy HH:mm:ss.fff")导致类似"09/14/2013 07.20.31.371"

Eld*_*ado 127 c# windows-phone-8

我有一个WP8应用程序,它将当前时间发送到Web服务.

我通过调用获取日期时间字符串

DateTime.ToString("MM/dd/yyyy HH:mm:ss.fff")
Run Code Online (Sandbox Code Playgroud)

对于大多数用户来说,它工作得很好,并给我正确的字符串"09/10/2013 04:04:31.415".但是对于某些用户而言,结果字符串就是这样"09/14/2013 07.20.31.371",这会导致我的Web服务出现问题.

是因为某些文化格式问题?如何确保结果字符串由冒号而不是点分隔?

Jon*_*eet 237

是因为某些文化格式问题?

是.您的用户必须处于时间分隔符为点的区域中.":"和"/"都以自定义日期和时间格式的文化敏感方式进行解释.

如何确保结果字符串由冒号而不是点分隔?

我建议指定CultureInfo.InvariantCulture:

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

另外,您也可以只报价时间和日期分隔符:

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

...但是,如果您让用户在默认日历系统不是公历的文化中运行,那么这将给您带来"有趣"的结果.例如,请使用以下代码:

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"));
    }
} 
Run Code Online (Sandbox Code Playgroud)

这产生了(2013年9月18日)的产量:

11/12/1434 15:04:31.750
Run Code Online (Sandbox Code Playgroud)

我的猜测是你的网络服务会对此感到惊讶!

我实际上建议不仅使用不变文化,还要改为ISO-8601日期格式:

string text = dateTime.ToString("yyyy-MM-ddTHH:mm:ss.fff");
Run Code Online (Sandbox Code Playgroud)

这是一种更全球公认的格式 - 它也是可排序的,并使月和日订单显而易见.(根据读者的文化,06/07/2013可以解释为6月7日或7月6日.)

  • 通过这个广泛的答案中途,我开始疑惑:这会再次成为乔恩吗?是的. (7认同)
  • 只是一个小问题.从特定代码加载CultureInfo对象时,我总是建议将`useUserOverride`参数设置为false,否则某些用户设置可以覆盖文化设置.例如,在你的情况下,我建议使用新的`CultureInfo("ar-SA",false)`. (3认同)

Mar*_*zek 9

:有特殊意义:它是时间分隔符.(自定义日期和时间格式字符串).

使用\逃脱它:

DateTime.ToString(@"MM/dd/yyyy HH\:mm\:ss.fff")
Run Code Online (Sandbox Code Playgroud)

或使用CultureInfo.InvariantCulture:

DateTime.ToString("MM/dd/yyyy HH:mm:ss.fff", CultureInfo.InvariantCulture)
Run Code Online (Sandbox Code Playgroud)

我建议使用第二个,因为它/具有特殊含义(它是日期分隔符.),所以你也可能遇到问题.

  • 这不仅仅是日期分隔符的问题 - 请参阅我的答案,了解影响实际数字的文化示例...... (2认同)
  • \ 没有逃脱它! (2认同)

Jon*_*arr 7

您可以使用InvariantCulture,因为您的用户必须位于使用点而不是冒号的区域中:

DateTime.ToString("MM/dd/yyyy HH:mm:ss.fff", CultureInfo.InvariantCulture);
Run Code Online (Sandbox Code Playgroud)


Håk*_*sen 6

我最近从另一个方向使用Windows 10遇到了这个问题,并且发现@JonSkeet的答案对解决我的问题很有帮助.

我还用测试表进行了进一步的研究,发现当当前文化被设置为"no""nb-NO"在运行时(Thread.CurrentThread.CurrentCulture = new CultureInfo("no");)时,ToString("yyyy-MM-dd HH:mm:ss")调用在Windows 7和Windows 7中的响应方式不同Windows 10.它返回了我在Windows 7中的预期和Windows 10中的HH.mm.ss!

我觉得这有点吓人!因为我认为文化至少在任何Windows版本中都是一种文化.

  • 它已被识别并修复为Windows 10 locaization Bug.因此,客户端计算机上的Windows更新将解决此问题.有关详细信息,请参阅此博客文章:http://www.heikniemi.net/hardcoded/2015/08/windows-10-breaks-net-date-parsing-in-certain-locales/ (2认同)