如何将DateTime转换为具有小数秒的本地化字符串

本文关键字:小数 本地化 字符串 DateTime 转换 | 更新日期: 2023-09-27 18:28:21

我有一个DateTime对象,我想将小时、分钟、秒和小数秒输出为针对当前区域性本地化的字符串。

这有两个问题。

第一个问题是没有标准的DateTime格式来显示小数秒。我主要想知道如何获得长时间DateTime格式,但使用小数秒。

当然,我可以获得DateTimeFormatInfo.LongTimePattern并在其上附加".fff",然后将其传递给DateTime.ToString(),但一些特定于区域性的格式,特别是US,以AM/PM结尾。所以事情并没有那么简单。

第二个问题是DateTime.ToString()似乎没有本地化数字十进制分隔符。如果我决定只强制每个区域性使用硬编码的自定义时间格式,它仍然不会创建本地化字符串,因为数字十进制分隔符不会特定于区域性。

更为复杂的是,有些区域性的日期-时间格式将句点作为其格式的一部分。这使得很难放置占位符,例如句点,并将其替换为区域性特定的十进制分隔符。

目前,我采用了这种变通方法:

string format = string.Format("HH:mm:ss{0}fff",
    CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator);
string time = DateTime.Now.ToString(format);

我认为这应该适用于每个没有与时间分隔符相同的十进制分隔符的文化,但这是一个假设。

注意:虽然这两个问题都有解决方案会很好,但对于我的特定应用程序,我更感兴趣的是用小数秒本地化自定义日期时间格式,而不是使用标准日期时间格式。

如何将DateTime转换为具有小数秒的本地化字符串

第一个问题是没有标准的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

我怀疑这就是为什么没有使用特定于区域性的小数分隔符的原因。我自己也觉得很奇怪——事实上,我让《野田时间》也有同样的行为,尽管我不相信这是正确的。

最终,很多这样的问题都是有根本问题的:如果一个文化没有固定的方式来表示"分秒时间",而你有来表示分秒,那么你能做的最好的事情就是有点草率。

我认为这将为您提供接近要求的东西

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

例如

  • fr:2012年3月20日10:20:10088
  • en GB:2012年3月20日10:21:08.724
  • 美国:2012年3月20日10:21:24.470

一般来说,我会更改当前的区域性,并执行我需要的操作。

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