将字符串转换为日期时出现奇怪的错误?

7
当我尝试解析日期时,就像这样:
DateTime t1 = DateTime.ParseExact("August 11, 2013, 11:00:00 PM", "MMMM dd, yyyy, hh:mm:ss tt", System.Globalization.CultureInfo.InvariantCulture);

它能正常运行,但当我像这样做时:

string s ="‎August ‎11, ‎2013, ‏‎11:00:00 PM";
DateTime t = DateTime.ParseExact(s, "MMMM dd, yyyy, hh:mm:ss tt", System.Globalization.CultureInfo.InvariantCulture);

我遇到了这个错误:

在用户代码中未能处理的“System.FormatException”类型的异常在 mscorlib.ni.dll 中发生。

4个回答

12

因为你的字符串

string s = "‎August ‎11, ‎2013, ‏‎11:00:00 PM";

在“八月”单词的开头和结尾包含一个0x200e(8206)字符。你可以通过以下方式轻松查看它:

var chars = s.ToCharArray();

看起来是复制粘贴问题。

您可以通过以下方式删除这些字符:

var newstr = new string(s.Where(c => c <128).ToArray())

那么我该如何删除它呢?因为我已经从模型中获取了它。 - Ahmed Emad
2
@AhmedEmad var newstr = new string(s1.Where(c => c <128).ToArray()) -> @AhmedEmad var newstr = new string(s1.Where(c => c <128).ToArray()) - I4V
@AhmedEmad 左到右和右到左标记存在的原因可能是字符串来自一些包含英文月份名称和从左到右排序的数字组的阿拉伯文本。您可以像答案中那样删除非 ASCII 字符,但如果它们总是出现在相同的位置,为什么不解析它们,例如 DateTime.ParseExact(s, "\u200EMMMM \u200Edd, \u200Eyyyy, \u200F\u200Ehh:mm:ss tt", CultureInfo.InvariantCulture) - Jeppe Stig Nielsen

3

哈哈,我找到了它。

首先,你们两个的代码都没有问题。都可以正常工作。只是你第二个字符串中有一些隐藏的字符,导致字符串不相等。

你的第一个字符串 "August 11, 2013, 11:00:00 PM".Length 是28

但是第二个字符串 "‎August ‎11, ‎2013, ‏‎11:00:00 PM".Length 是33

让我们尝试这段代码;

string s = "August 11, 2013, 11:00:00 PM";
string s1 = "‎August ‎11, ‎2013, ‏‎11:00:00 PM";

char[] c = s.ToCharArray();
char[] c1 = s1.ToCharArray();

foreach (var ch in c)
{
    Console.WriteLine(ch);
}

foreach (var ch1 in c1)
{
    Console.WriteLine(ch1);
}

输出结果将会是:

A
u
g
u
s
t

1
1
,

2
0
1
3
,

1
1
:
0
0
:
0
0

P
M
? // <-- What the hell?
A
u
g
u
s
t

? // <-- What the hell?
1
1
,

? // <-- What the hell?
2
0
1
3
,

? // <-- What the hell?
? // <-- What the hell?
1
1
:
0
0
:
0
0

P
M

作为解决方案,不要将任何字符串复制粘贴到您的代码中 :).

@Downvoter,您能否至少评论一下,这样我就可以看到我可能错在哪里了? - Soner Gönül
你知道每次都拼错了 length 吗? :) - SmartDev
@SmartDev 很抱歉,这是一个7年前的错误,已经修复 (: - Soner Gönül

2

我也遇到过这个问题。在我的情况下,一个UI自动化测试失败了,因为IE似乎会自动添加这个LRM(从左到右)标记(Firefox和Chrome不会)。可以使用一行代码快速去除它:

Regex.Replace(date, @"\u200e", string.Empty)

2

您的第二个字符串中有隐藏字符。

运行以下命令:

string s1 = "August 11, 2013, 11:00:00 PM";
string s2 = "‎August ‎11, ‎2013, ‏‎11:00:00 PM";

Console.WriteLine(s1.Length); // 28
Console.WriteLine(s2.Length); // 33

具体来说,作为字符数组,第二个如下所示:
s2.ToCharArray();
{char[33]}
[0]: 8206 '‎' // ????
[1]: 65 'A'
[2]: 117 'u'
[3]: 103 'g'
[4]: 117 'u'
[5]: 115 's'
[6]: 116 't'
[7]: 32 ' '
[8]: 8206 '‎' // ????
[9]: 49 '1'
[10]: 49 '1'
[11]: 44 ','
[12]: 32 ' '
[13]: 8206 '‎' // ????
[14]: 50 '2'
[15]: 48 '0'
[16]: 49 '1'
[17]: 51 '3'
[18]: 44 ','
[19]: 32 ' '
[20]: 8207 '‏' // ????
[21]: 8206 '‎' // ????
[22]: 49 '1'
[23]: 49 '1'
[24]: 58 ':'
[25]: 48 '0'
[26]: 48 '0'
[27]: 58 ':'
[28]: 48 '0'
[29]: 48 '0'
[30]: 32 ' '
[31]: 80 'P'
[32]: 77 'M'

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