关于 c#:DateTimeFormat 问题

DateTimeFormat Issue

我没有从 DateTime-Object 获得以下所需的输出:

2010-03-29 13:15:00

我的默认本地化是 de-DE,所以一个简单的 ToString 给了我:

29.03.2010 13:15:00

我尝试的是从 US-Culture 创建一个 DateTimeFormatInfo 对象并使用它的 DateTimePatterns 但没有成功:

1
2
3
Dim usDateFormat As Globalization.DateTimeFormatInfo = New Globalization.CultureInfo("en-US", False).DateTimeFormat
usDateFormat.DateSeparator ="-"
ruleResult.Claim.Last_Updated_Date.ToString(usDateFormat.ShortDatePattern)

输出:3.29.2010

什么是获得我想要的 DateTimeFormat 的最佳方式(可读、最快)(我有时需要短日期,有时需要日期和时间,就像我上面的例子一样)?

感谢您的期待,
蒂姆

编辑:为什么我的 DateTimeFormatInfo 方法不起作用,并且在使用 String.Format 或 ToString("yyyy-MM-dd HH:mm:ss") 解决方案而不是私有共享(静态) DateTimeFormatInfo 时会产生性能差异-目的?我至少调用了这个函数 30k 次,里面有很多日期要格式化。


我认为您正在寻找的是:

1
DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");

这里有一些例子,我想如果你看一下你就可以理解它是如何工作的:

1
2
3
4
5
6
7
8
9
10
11
12
13
// create date time 2008-03-09 16:05:07.123
DateTime dateTime = new DateTime(2008, 3, 9, 16, 5, 7, 123);

dateTime.ToString("y yy yyy yyyy");  //"8 08 008 2008"   year
dateTime.ToString("M MM MMM MMMM");  //"3 03 Mar March"  month
dateTime.ToString("d dd ddd dddd");  //"9 09 Sun Sunday" day
dateTime.ToString("h hh H HH"    );  //"4 04 16 16"      hour 12/24
dateTime.ToString("m mm"         );  //"5 05"            minute
dateTime.ToString("s ss"         );  //"7 07"            second
dateTime.ToString("f ff fff ffff");  //"1 12 123 1230"   sec.fraction
dateTime.ToString("F FF FFF FFFF");  //"1 12 123 123"    without zeroes
dateTime.ToString("t tt"         );  //"P PM"            A.M. or P.M.
dateTime.ToString("z zz zzz"     );  //"-6 -06 -06:00"   time zone

要获得 2010-03-29 13:15:00 我会使用自定义模式。在这种情况下:

1
DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");

有关详细信息,请参阅此 MSDN 文章


这个解决方案怎么样:

1
2
3
4
5
6
7
8
// Get a default DateTimeFormat
var dateTimeFormat = CultureInfo.GetCultureInfo("en-US").DateTimeFormat;
// Clone it to make it writeable
dateTimeFormat = (DateTimeFormatInfo)dateTimeFormat.Clone();
// Change the DateSeparator
dateTimeFormat.DateSeparator ="-";
// Output it as normal
var output = DateTime.Now.ToString("g", dateTimeFormat);

我认为大多数人不知道你可以通过调用 Clone() 方法创建一个新对象来获得文化的可写版本。

更新

正如蒂姆所说,你也可以这样称呼它:

1
2
3
4
5
6
// Get a default DateTimeFormat
var dateTimeFormat = new CultureInfo("en-US").DateTimeFormat;
// Change the DateSeparator
dateTimeFormat.DateSeparator ="-";
// Output it as normal
var output = DateTime.Now.ToString("g", dateTimeFormat);

这行得通,因为我们创建了一个源自给定文化的新 CultureInfo。第一个是只读的,原因在于,在第一种情况下,我们将在框架深处的某处获得对某个静态创建的实例的引用,并通过 Clone() 调用创建一个新类具有相同的设置。在第二种方法中,我们直接创建了新的类,但是说我们希望从特定文化中获取所有设置。

所以说到底,两个版本都在做同样的事情,换句话说。如果两个版本之间存在性能差异,我无法判断,但我认为这可以忽略不计。

更新 2

在阅读了汤姆斯的最后一条评论后,他尝试了这样的事情:

1
2
3
4
5
6
// Get a default DateTimeFormat
var dateTimeFormat = new CultureInfo("en-US").DateTimeFormat;
// Change the DateSeparator
dateTimeFormat.DateSeparator ="-";
// Output it as normal
var output = DateTime.Now.ToString(dateTimeFormat.ShortDatePattern);

这会导致错误的输出。这是因为在 dateTimeFormat.ShortDatePattern 中只是一个包含 M/d/yyyy 的普通字符串。所以和调用 DateTime.Now.ToString("M/d/yyyy").

是一样的

由于事实上, / 将被 DateSeparator 替换,并且当前没有给出 IFormatProvider ,它将采用当前的文化,在您的情况下是德语。所以要解决这个问题,你应该试试下面的代码:

1
2
3
4
5
6
// Get a default DateTimeFormat
var dateTimeFormat = new CultureInfo("en-US").DateTimeFormat;
// Change the DateSeparator
dateTimeFormat.DateSeparator ="-";
// Output it as normal
var output = DateTime.Now.ToString(dateTimeFormat.ShortDatePattern, dateTimeFormat);

通过这些信息,您还应该能够对更快的情况做出一些假设:

1
2
var output = DateTime.Now.ToString(dateTimeFormat.ShortDatePattern, dateTimeFormat);
var output = DateTime.Now.ToString("M/d/yyyy", dateTimeFormat);

由于它们完全相同,因此性能应该没有差异


您可以像这样在 DateTime 的 ToString 中使用格式化选项

1
DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");

1
DateTime.Now.ToString("yyyy-MM-dd");

1
2
3
DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")

DateTime.Now.ToString("yyyy-MM-dd")

你也可以试试format(date.now,"yyyy-MM-dd HH:mm:ss)


1
string.Format("{0:yyyy-MM-dd HH:mm:ss}", DateTime.Now)

对于预定义的模式检查这个:
http://alexonasp.net/samples/stringformatting/