DateTime.ToString("MM/dd/yyyy HH:mm:ss.fff") 的结果类似于 "09/14/2013 07.20.31.371"。

144
我有一个WP8应用程序,需要将当前时间发送到网络服务。我通过调用下面的方法获取日期时间字符串:
DateTime.ToString("MM/dd/yyyy HH:mm:ss.fff")

对于大多数用户,它运行良好并给出了正确的字符串,例如"09/10/2013 04:04:31.415"。但是对于某些用户,结果字符串类似于"09/14/2013 07.20.31.371",这在我的Web服务中会引起问题。

这是否是由于某些文化格式问题?我该如何确保结果字符串用冒号代替点来分隔?


2
唯一的区别是冒号和点。 - Eldorado
请参考 .Net Standard 2 示例 - Sina Lotfi
6个回答

261

是因为某个文化格式的问题吗?

是的。您的用户必须处于时间分隔符为点号的文化环境中。在自定义日期和时间格式中,冒号和斜杠都会根据文化环境以敏感的方式进行解释。

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

我建议指定CultureInfo.InvariantCulture

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

或者,你可以只引用时间和日期分隔符:

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

......但是如果你在默认日历系统不是公历的文化环境中运行用户,那么这将给你带来“有趣”的结果,这可能会让你感到意外。例如,看看以下代码:

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"));
    }
} 

这将产生输出结果(于2013年9月18日):

11/12/1434 15:04:31.750

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

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

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

这是一种更受全球认可的格式 - 它也可以排序,并且使月份和日期顺序显而易见。(而“06/07/2013”可能会根据读者文化的不同被解释为6月7日或7月6日。)


谢谢Jon。我以为结果字符串会与格式字符串完全一样。我会尝试你的建议。 - Eldorado
3
只有一个小建议。当从特定代码加载CultureInfo对象时,我建议将"useUserOverride"参数设置为false,否则某些用户设置可能会覆盖文化设置。例如,在您的情况下,我建议使用新的CultureInfo("ar-SA", false) - Davide Icardi
@DavideIcardi:有趣,谢谢 - 尽管在这种情况下使用沙特阿拉伯的目的是特别说明为什么使用不变文化可能是正确的。不过将来的帖子中会记住这一点。 - Jon Skeet
8
在这个详尽的回答中,我中途开始想:这又是Jon吗?没错。 - Grimace of Despair
如何使用Html.TextBoxFor(x=>x.Date,"{0:MM/dd/yyyy}")进行管理? - VISHMAY
显示剩余2条评论

13

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

使用\进行转义:

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

或者使用 CultureInfo.InvariantCulture

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

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


2
不仅仅是日期分隔符成为问题 - 请参考我的答案,了解文化对实际数字的影响的例子... - Jon Skeet
1
不要转义反斜杠! - Shereef Marzouk

9

您可以使用InvariantCulture,因为您的用户必须处于使用点而不是冒号的文化中:

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

8

最近,我在使用Windows 10时遇到了一个问题,从另一个角度找到了JonSkeet的答案对解决我的问题非常有帮助。

此外,我还进行了一些测试,并发现当运行时将当前文化设置为"no""nb-NO"(Thread.CurrentThread.CurrentCulture = new CultureInfo("no");), 在Windows 7和Windows 10中,ToString("yyyy-MM-dd HH:mm:ss")调用会有不同的响应。在Windows 7中返回我期望的结果,在Windows 10中返回HH.mm.ss!

我认为这有点可怕!因为我至少认为在任何Windows版本中都是相同的文化。


我非常好奇是什么导致了这个问题。 - Lauri Peltonen
2
已经确认并修复为Windows 10本地化Bug。因此,客户端机器上的Windows更新将解决此问题。有关更多详细信息,请参阅以下博客文章: http://www.heikniemi.net/hardcoded/2015/08/windows-10-breaks-net-date-parsing-in-certain-locales/ - Håkon Seljåsen
我上面链接的Jouni Heikniemi的博客似乎已经无法访问了。相关的Windows更新程序已在该博客中列出,其中修复了一些问题:2015-10-09: KB3093266 - Windows 10 KB3088956 - Windows Server 2012 R2和Windows 8.1 KB3088955 - Windows Server 2012和Windows 8 KB3088957 - Windows 7 SP1、Windows Server 2008 SP2、Windows Server 2008 R2 SP1和Windows Vista SP2尝试再次链接到该博客,这次使用archive.org: http://web.archive.org/web/20161030193739/http://www.heikniemi.net/hardcoded/2015/08/windows-10-breaks-net-date-parsing-in-certain-locales/ - Håkon Seljåsen

5
您可以使用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"

1
将日期转换为字符串
使用命名空间
using System.Globalization;

代码

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

这不是将日期转换为字符串的方法。解析才是相反的过程! - Vincent Vancalbergh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接