如何将包含长毫秒(纳秒)部分的字符串解析为DateTime?

5

我正在尝试弄清楚以下给定日期时间文字的正确字符串格式:

18-JUN-13 12.17.36.000000000

通过使用MSDN,我成功地编写了以下格式:

"d'-'MMM'-'y'T'h'.'m'.'s'.'fff"

但是使用DateTime.ParseExact时,解析失败并出现FormatException字符串未被识别为有效的日期时间

我的代码:

DateTime.ParseExact("18-JUN-13 12.17.36.000000000", "d'-'MMM'-'y'T'h'.'m'.'s'.'fff", null);
3个回答

4

您可以使用

dd-MMM-yy hh.mm.ss.fffffff

使用像 InvariantCulture 这样基于英语的文化。例如,我现在正在使用移动设备,所以无法尝试它:(

AFAIK, 毫秒部分解析限制为7,这就是为什么你无法解析字符串而不进行操作的原因。你可以像这样使用它;

var dt = DateTime.ParseExact("18-JUN-13 12.17.36.0000000",
                             "dd-MMM-yy HH.mm.ss.fffffff",
                             CultureInfo.InvariantCulture);

看起来可能正是为什么我们将 "fffffff" 自定义格式 作为毫秒的顶部字符。根据文档;
尽管可以显示时间值的十分之一微秒分量,但该值可能没有意义。日期和时间值的精度取决于系统时钟的分辨率。在Windows NT 3.5(及更高版本)和Windows Vista操作系统上,时钟的分辨率约为10-15毫秒。
你问过;
如何操纵字符串?
嗯,一种方法是获取逗号的最后一个索引,并将其子字符串到其后8个索引,例如;
string s = "18-JUN-13 12.17.36.000000000";
var dateString = s.Substring(0, s.LastIndexOf(".") + 8);

“f”格式化程序的重要之处在于它表示一位次秒精度。它必须与输入小数位数匹配,才能与ParseExact匹配。 - Berin Loritsch
1
你试过了吗?似乎不能使用9f。输入字符串的长度也必须匹配。 - Tim Schmelter
@TimSchmelter 您是正确的。我现在正在使用手机,所以无法正确尝试它。看起来毫秒解析的限制是7。我认为我的第二个例子会起作用。 - Soner Gönül
@BerinLoritsch 是的,你说得对。因为我在移动设备上,第一次没法写出来。谢谢。 - Soner Gönül
@YairNevet 编辑了我的答案。请看一下。 - Soner Gönül
显示剩余2条评论

0

如果你想解析一个小数点后有七位以上数字的时间字符串,除非你像juharr's commentDateTime format throws exception中所建议的那样,将多余的数字解析为literal characters,否则你不能直接解析(即ParseExact())。

string before = "18-JUN-13 12.17.36.000000000";
string format = "d'-'MMM'-'y' 'h'.'m'.'s'.'fffffff'00'";
DateTime value = DateTime.ParseExact(before, format, null);
string after = value.ToString(format);

Console.WriteLine(before);// 18-JUN-13 12.17.36.000000000
Console.WriteLine(after); // 18-Jun-13 12.17.36.000000000

否则,您需要截断多余的数字,就像Soner Gönül's answer中所述。
不幸的是,异常消息和文档都没有说明为什么fffffff/FFFFFFF是限制,因为原因很简单,但很容易被忽视。 0.0000001秒是:
  • 一秒的千万分之一,或...
  • 100纳秒,或...
  • 一个tick
一个tick是一个DateTime可以表示的最小间隔。格式字符串,如ffffffff(八个有效数字)及以上不能是有效的,因为这将要求DateTime能够存储一部分tick。虽然“字符串无法识别为有效的DateTime”确实描述了问题,但在这种情况下,问题不仅在于输入与指定格式不匹配,而且还在于输入无法被DateTime精确地表示。

-1

你的代码里有很多单引号,这不是正确的格式。试试这个:

DateTime.ParseExact("18-JUN-13 12.17.36.000000000", "d-MMM-yTh.m.s.fff", null);

注意:除非使用单引号,否则日期时间格式化程序可能会将破折号更改为不同的区域设置特定分隔符,如斜杠。当某人更改其默认语言环境后,我曾经因此受到过影响,解析器开始失败。 - Berin Loritsch
单引号是有效的,是转义字符“\”的替代品;请参见标准日期和时间格式字符串,其中有几个模式使用引号表示。 - Lance U. Matthews

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