![](/img/trans.png)
[英]DateTime.Parse fails when hyphen is used as the separator in the time format
[英]Is there a bug in the DateTime.Parse method when UTC is used with time zone offsets?
Microsoft 文檔指出,在 DateTime 結構的其他字符串表示形式中,DateTime.Parse(string) 符合 ISO 8601 並接受用於時區偏移的協調世界時 (UTC) 格式。
當我運行以下單元測試用例時, DateTime.Parse(string) 和 DateTime.TryParse(string, out DateTime) 接受源字符串末尾的附加字符。 這似乎是一個錯誤。 當追加了多個附加字符時,該方法無法正確解析字符串。
[Theory]
[InlineData("2020-5-7T09:37:00.0000000-07:00")]
[InlineData("2020-5-7T09:37:00.0000000-07:00x")]
[InlineData("2020-5-7T09:37:00.0000000-07:00xx")]
[InlineData("2020-5-7T09:37:00.0000000Z")]
[InlineData("2020-5-7T09:37:00.0000000Zx")]
public void TestParse(string source)
{
DateTime dt = DateTime.Parse(source);
Assert.True(dt != null);
bool b = DateTime.TryParse(source, out dt);
Assert.True(b);
}
編寫此單元測試用例是為了簡化我的代碼並說明我所看到的行為(我認識到預期的失敗應該以不同的方式處理)。
測試 1 和 2 通過,而第三個測試(帶有“xx”后綴)失敗。 在我看來,第二個測試(帶有“x”后綴)應該會失敗。
如果未提供時區指示符,則測試 4 通過而測試 5 失敗。 這似乎是正確的行為。
我想知道是否有人遇到過這個問題,如果遇到過,是否普遍認為這是一個錯誤?
就個人而言,這對我來說似乎是一個錯誤......
2020-5-7T09:37:00.0000000-07:00x
是一個有效的 ISO 8601 日期,末尾有一個無效的任意字符,它在沒有錯誤的情況下錯誤地解析,其中兩個任意字符似乎正確地失敗了。
似乎正在發生的事情如下
ParseISO8601
ParseTimeZone
獲取正確的時區信息-07:00
str
有 1 個最后索引str.Match('#')
哪個前綴增加了索引(我認為這是錯誤)。比賽節選
評論我的
internal bool Match(char ch)
{
if (++Index >= Length) // reaches the end of the string here
{
return false;
}
...
}
上面的方法返回false
,但是它增加了索引。 這在事物的計划中似乎非常奇怪。
看起來它的設計目的是檢查 hash 的當前字符,然后是null 終止,如果還有其他任何內容,則失敗。
摘自 ParseISO8601
str.SkipWhiteSpaces();
if (str.Match('#')) // mine... check hash ... no
{
if (!VerifyValidPunctuation(ref str))
{
result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
return false;
}
str.SkipWhiteSpaces();
}
if (str.Match('\0')) // mine... check null termination ... no
{
if (!VerifyValidPunctuation(ref str))
{
result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
return false;
}
}
if (str.GetNext()) // mine... get anything else, if found fail
{
// If this is true, there were non-white space characters remaining in the DateTime
result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
return false;
}
注意:這似乎發生在我測試過的每個框架中。
簡而言之,它會完全忽略日期末尾的任何任意字符,但是如果還剩下 2 個字符,它會按預期運行,因為它會遞減匹配檢查中的索引。
internal bool Match(char ch) {
if (++Index >= len) {
return (false);
}
if (Value[Index] == ch) {
m_current = ch;
return (true);
}
Index--;
return (false);
}
我已將此報告為 GitHub 上的運行時錯誤,可以在此處進行跟蹤
DateTime.Parse ISO 8601 允許在日期末尾使用額外的任意字符 #46477
這已被正式標記為運行時錯誤,並且已為 .Net 6 修復
我還沒有時間構建運行時來檢查它實際在做什么,但是從評論看來,當它拉出時區時,當前索引遞增 1 太多,並且匹配錯誤地檢查了下一個字符。
有一個PR可以解決這個問題。 修復應該在未來的 .NET 版本 (6.0) 中。 感謝您報告問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.