- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有以下代码,它有效。
string testDateStr = "2009.7.28 05:23:15";
DateTime testDateObj = Convert.ToDateTime(testDateStr, CultureInfo.GetCultureInfo("fr-FR"));
然后我检查了适合我的文化的有效格式:
string[] validFormats = testDateObj.GetDateTimeFormats(CultureInfo.GetCultureInfo("fr-FR"));
并且它们都不符合“2009.7.28 05:23:15”格式。我想知道如何在不抛出格式异常的情况下解析它,以及当我们调用 Convert.ToDateTime() 时进行了什么样的隐藏解析。
更新:在 LakshmiNarayanan 的回答之后,我尝试了以下操作。
foreach(var culture in CultureInfo.GetCultures(CultureTypes.AllCultures))
{
foreach(var format in testDateObj.GetDateTimeFormats(culture))
{
if (format == testDateStr)
{
Console.WriteLine(culture.DisplayName);
}
}
}
有些文化实际上包含我的字符串的格式,但它仍然无法解释为什么当我们要求它使用特定文化进行转换时它不会抛出异常,而该文化不知道字符串的格式中。
最佳答案
Convert.ToDateTime
方法内部使用了DateTime.Parse
方法,该方法基于内部复杂的Lex
方法。有一堆规则适用于传递的字符串。它被分成 token ,每个 token 都被分析。分析非常复杂,我将只展示几条规则。
如果token由数字组成,长度为3~8,那么这个token就是年份,所以可以解析01.2014.01
字符串,得到2014 年 1 月 1 日
结果。请注意,您还可以解析类似 01 2014 01
或 01\n2014\n01
的字符串,得到相同的结果。您可以使用空格或 、
或 .
符号分隔标记。
如果 token 是月份的名称,那么它将是月份(表或 token 在内部 DateTimeFormatInfo.CreateTokenHashTable
方法中构建)。因此,将 Feb
或 February
定位在何处并不重要。您同样可以解析 2014 1 Jan
或 2014.Jan.1
、2014...,Jan..,..1
甚至 5Jan2014
字符串(最后一个不使用任何分隔符,但会检查数字在哪里结束,因此成功拆分为5
、Jan
和 2014
代币)。
如果我们有不明确的字符串 01/04
,那么将使用文化中的信息来解析日/月的顺序。订单摘自DateTimeFormatInfo.MonthDayPattern .例如,对于 en-US
,它是 MMMM dd
,对于 en-GB
,它是 dd MMMM
。内部System.DateTimeParse
类中有private static bool GetMonthDayOrder(string pattern, DateTimeFormatInfo dtfi, out int order)
方法,用于提取顺序。如果order
变量取值为6
,则为MM/dd
,如果取值为7
,则它是 dd/MM
。请注意,它不会尝试对 01/31
进行一些试探,只会考虑从文化中提取的顺序。下面是测试代码:
CultureInfo ci = CultureInfo.GetCultureInfo("en-US");
DateTimeFormatInfo dtfi = ci.DateTimeFormat;
Assembly coreAssembly = Assembly.ReflectionOnlyLoad("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
Type dateTimeParseType = coreAssembly.GetType("System.DateTimeParse");
MethodInfo getMonthDayOrderMethodInfo = dateTimeParseType.GetMethod("GetMonthDayOrder", BindingFlags.Static | BindingFlags.NonPublic);
object[] parameters = new object[] { dtfi.MonthDayPattern, dtfi, null };
getMonthDayOrderMethodInfo.Invoke(null, parameters);
int order = (int)parameters[2];
switch (order)
{
case -1:
Console.WriteLine("Cannot extract information");
break;
case 6:
Console.WriteLine("MM/dd");
break;
case 7:
Console.WriteLine("dd/MM");
break;
}
还有许多其他针对 AM/PM 模式、星期几、时间后缀(例如,对于韩语,考虑了 시
后缀,意思是小时)等的检查。
以下代码将生成有关文化特定标记的信息:
DateTimeFormatInfo dti = CultureInfo.InvariantCulture.DateTimeFormat;
dynamic hashes = dti.GetType().GetMethod("CreateTokenHashTable", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(dti, null);
var tokens = Enumerable.Repeat(new { str = "", type = "", value = "" }, 0).ToList();
foreach (dynamic hash in hashes)
if (hash != null)
{
Type hashType = hash.GetType();
tokens.Add(new { str = (string)hashType.GetField("tokenString", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(hash).ToString(),
type = (string)hashType.GetField("tokenType", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(hash).ToString(),
value = (string)hashType.GetField("tokenValue", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(hash).ToString() });
}
foreach (var token in tokens.Distinct().OrderBy(t => t.type).ThenBy(t => t.value))
Console.WriteLine("{0,10} {1} {2}", token.str, token.type, token.value);
对于InvariantCulture
,输出是:
AM 1027 0
PM 1284 1
Sunday DayOfWeekToken 0
Sun DayOfWeekToken 0
Monday DayOfWeekToken 1
Mon DayOfWeekToken 1
Tuesday DayOfWeekToken 2
Tue DayOfWeekToken 2
Wednesday DayOfWeekToken 3
Wed DayOfWeekToken 3
Thu DayOfWeekToken 4
Thursday DayOfWeekToken 4
Friday DayOfWeekToken 5
Fri DayOfWeekToken 5
Sat DayOfWeekToken 6
Saturday DayOfWeekToken 6
AD EraToken 1
A.D. EraToken 1
, IgnorableSymbol 0
. IgnorableSymbol 0
January MonthToken 1
Jan MonthToken 1
October MonthToken 10
Oct MonthToken 10
November MonthToken 11
Nov MonthToken 11
December MonthToken 12
Dec MonthToken 12
February MonthToken 2
Feb MonthToken 2
March MonthToken 3
Mar MonthToken 3
Apr MonthToken 4
April MonthToken 4
May MonthToken 5
June MonthToken 6
Jun MonthToken 6
Jul MonthToken 7
July MonthToken 7
Aug MonthToken 8
August MonthToken 8
September MonthToken 9
Sep MonthToken 9
/ SEP_Date 0
- SEP_DateOrOffset 0
日 SEP_DaySuff 0
일 SEP_DaySuff 0
时 SEP_HourSuff 0
時 SEP_HourSuff 0
T SEP_LocalTimeMark 0
分 SEP_MinuteSuff 0
月 SEP_MonthSuff 0
월 SEP_MonthSuff 0
秒 SEP_SecondSuff 0
: SEP_Time 0
년 SEP_YearSuff 0
年 SEP_YearSuff 0
GMT TimeZoneToken 0
Z TimeZoneToken 0
对于 fr-FR
文化(请注意 July
以及来自 InvariantCulture
的其他标记都包含在列表中)
AM 1027 0
PM 1284 1
h DateWordToken 0
dimanche DayOfWeekToken 0
Sun DayOfWeekToken 0
dim. DayOfWeekToken 0
Sunday DayOfWeekToken 0
lundi DayOfWeekToken 1
Monday DayOfWeekToken 1
lun. DayOfWeekToken 1
Mon DayOfWeekToken 1
Tuesday DayOfWeekToken 2
Tue DayOfWeekToken 2
mardi DayOfWeekToken 2
mar. DayOfWeekToken 2
mercredi DayOfWeekToken 3
Wednesday DayOfWeekToken 3
mer. DayOfWeekToken 3
Wed DayOfWeekToken 3
jeudi DayOfWeekToken 4
Thursday DayOfWeekToken 4
Thu DayOfWeekToken 4
jeu. DayOfWeekToken 4
ven. DayOfWeekToken 5
vendredi DayOfWeekToken 5
Friday DayOfWeekToken 5
Fri DayOfWeekToken 5
samedi DayOfWeekToken 6
sam. DayOfWeekToken 6
Sat DayOfWeekToken 6
Saturday DayOfWeekToken 6
ap. J.-C. EraToken 1
, IgnorableSymbol 0
. IgnorableSymbol 0
January MonthToken 1
janv. MonthToken 1
janvier MonthToken 1
Jan MonthToken 1
oct. MonthToken 10
Oct MonthToken 10
octobre MonthToken 10
October MonthToken 10
nov. MonthToken 11
Nov MonthToken 11
novembre MonthToken 11
November MonthToken 11
déc. MonthToken 12
December MonthToken 12
Dec MonthToken 12
décembre MonthToken 12
févr. MonthToken 2
février MonthToken 2
February MonthToken 2
Feb MonthToken 2
mars MonthToken 3
March MonthToken 3
Mar MonthToken 3
Apr MonthToken 4
avr. MonthToken 4
avril MonthToken 4
April MonthToken 4
mai MonthToken 5
May MonthToken 5
June MonthToken 6
juin MonthToken 6
Jun MonthToken 6
July MonthToken 7
juil. MonthToken 7
juillet MonthToken 7
Jul MonthToken 7
Aug MonthToken 8
août MonthToken 8
August MonthToken 8
sept. MonthToken 9
Sep MonthToken 9
septembre MonthToken 9
September MonthToken 9
/ SEP_Date 0
- SEP_DateOrOffset 0
日 SEP_DaySuff 0
일 SEP_DaySuff 0
时 SEP_HourSuff 0
時 SEP_HourSuff 0
T SEP_LocalTimeMark 0
分 SEP_MinuteSuff 0
月 SEP_MonthSuff 0
월 SEP_MonthSuff 0
秒 SEP_SecondSuff 0
: SEP_Time 0
년 SEP_YearSuff 0
年 SEP_YearSuff 0
GMT TimeZoneToken 0
Z TimeZoneToken 0
关于c# - 当给定的区域性不知道格式时,Convert.ToDateTime() 如何解析给定的字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22809884/
我创建了一个本地化的 wpf 应用程序。为了在系统中安装应用程序,我使用了 visual studio 提供的 msi 安装程序。安装完成后,我通过运行 commit custom action 命令
我有英语 Windows 版本,目前无法调试它,但我正在将应用程序本地化为俄语和英语两种语言。 据我了解,在 App 构造函数中,以下代码应该足够了: if (Language
我的应用程序在 web.config 中设置了 pt-BR 区域性(日期为 dd-mm-yyyy): 在我的系统上创建的所有日期时间都是正确的格式,但我创建了一个像这样的 Controller 方法
我是一名优秀的程序员,十分优秀!