如何将 DateTime 转换为本地化的小数秒字符串?
Posted
技术标签:
【中文标题】如何将 DateTime 转换为本地化的小数秒字符串?【英文标题】:How can I convert a DateTime to a string with fractional seconds that is localized? 【发布时间】:2012-04-05 09:12:33 【问题描述】:我有一个 DateTime 对象,我想将小时、分钟、秒和小数秒输出为针对当前区域性进行本地化的字符串。
这有两个问题。
第一个问题是没有标准的DateTime
格式可以显示小数秒。我基本上想知道如何获得long time DateTime 格式,但使用小数秒。
我当然可以获取DateTimeFormatInfo.LongTimePattern
并将“.fff”附加到它并将其传递给DateTime.ToString()
,但某些特定于文化的格式,特别是美国,以 AM/PM 结尾。所以没那么简单。
第二个问题是DateTime.ToString()
似乎没有本地化数字小数分隔符。如果我决定只强制每种文化使用硬编码的自定义时间格式,它仍然不会创建本地化字符串,因为数字小数分隔符不是特定于文化的。
更复杂的是,一些文化的日期时间格式使用句点作为其格式的一部分。这使得放置占位符(例如句点)并用文化特定的小数分隔符替换它变得很困难。
目前我已经采用了这种解决方法:
string format = string.Format("HH:mm:ss0fff",
CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator);
string time = DateTime.Now.ToString(format);
我认为这应该适用于没有与时间分隔符相同的小数分隔符的每种文化,但这是一个假设。
注意:虽然解决这两个问题会很好,但对于我的特定应用程序,我更感兴趣的是使用小数秒来本地化自定义日期时间格式,而不是使用标准日期时间格式。
【问题讨论】:
我认为任何文化惯例都不包括小数秒。您的方法看起来不错,但我会得到 LongTimePattern 并替换ss
,以克服 AM/PM 与 HH 问题。
【参考方案1】:
第一个问题是没有标准的 DateTime 格式可以显示小数秒。我基本上想知道如何获得长时间的 DateTime 格式,但使用小数秒。
您可以考虑采用长格式并将“:ss”替换为“:ss.fff”,可能使用文化特定的小数分隔符:
string longPattern = culture.DateTimeFormat.LongTimePattern;
if (!longPattern.Contains(":ss"))
// ???? Throw an exception? Test this with all system cultures, but be aware
// that you might see custom ones...
// Only do it if the long pattern doesn't already contain .fff... although if
// it does, you might want to replace it using the culture's decimal separator...
if (!longPattern.Contains(".fff"))
longPattern = longPattern.Replace(":ss",
":ss" + culture.NumberFormat.DecimalSeparator + "fff");
string timeText = time.ToString(longPattern, culture);
更复杂的是,一些文化的日期时间格式使用句点作为其格式的一部分。这使得放置占位符(例如句点)并用文化特定的小数分隔符替换它变得很困难。除此之外,它应该最终将价值放在正确的位置。你确定总是想要三位数,即使该值是精确的秒(或半秒等)?如果没有,请使用
.FFF
。
我怀疑这是为什么不使用特定于文化的小数分隔符。我自己也觉得很奇怪 - 事实上,我让 Noda Time 的行为方式相同,尽管我是 not convinced it's right。
归根结底,很多这样的问题从根本上是有问题的:如果一种文化没有没有固定的方式来表示“带有小数秒的时间”并且你已经得到来表示小数秒,那么你能做的最好的事情就是有点杂乱无章。
【讨论】:
假设所有文化都使用 :ss 而不是 :s 是否安全?不过,我认为这会通过抛出异常来处理。 @jcmcbeth:通过。可能是。您可以相当轻松地检查所有 系统 文化,但这并不能阻止有人提出他们自己的疯狂文化设置。【参考方案2】:我认为这会给你一些接近你需要的东西
var now = DateTime.Now;
var seconds = now.TimeOfDay.TotalSeconds % 60;
var timeText = string.Format(CultureInfo.GetCultureInfo("fr-FR"),
"0:d 0:hh:mm:1:00.000", now, seconds);
或者直接使用
var timeText = string.Format(CultureInfo.CurrentCulture,
"0:d 0:hh:mm:1:00.000", now, seconds);
例如
法国-法国:20/03/2012 10:20:10,088 zh-CN:20/03/2012 10:21:08.724 zh-CN:2012 年 3 月 20 日 10:21:24.470【讨论】:
我认为这个解决方案比我为自定义格式化字符串提供的解决方案更有说服力。【参考方案3】:通常我会改变当前的文化,然后做我需要的操作。
System.Globalization.CultureInfo before = System.Threading.Thread.CurrentThread.CurrentCulture;
try
System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-US");
string timestr = DateTime.Now.ToString();
catch (Exception ex)
Console.WriteLine(ex.Message);
finally
System.Threading.Thread.CurrentThread.CurrentUICulture = before;
【讨论】:
1) 这到底是如何解决问题的? 2) 为什么你认为这比将文化作为参数传递给ToString
更好?
我认为通过这种方法,您选择了文化,之后您只能专注于格式问题。是的,您可以在 ToString() 中传递文化,但是如果您有更多的格式化操作要做,我喜欢使用我的方式。只是意见不同
问题在于 DateTime.ToString() 没有本地化小数点分隔符或具有显示小数秒的标准格式。以上是关于如何将 DateTime 转换为本地化的小数秒字符串?的主要内容,如果未能解决你的问题,请参考以下文章
琐事:如何将 JSON2.org DateTime 字符串转换为 C# DateTime
如何将表单(国家/城市)中的字符串时区转换为 datetime.tzinfo