我正在尝试解析DateTime,并从客户端输入接受一个确切的格式。
哪一个更好
bool success = DateTime.TryParseExact(value, "dd-MMM-yyyy",
DateTimeFormatInfo.InvariantInfo, DateTimeStyles.None, out dateTime);
OR
bool success = DateTime.TryParseExact(value, "dd-MMM-yyyy",
CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime);
当然,这段代码在一个常见的静态方法中,在需要解析日期的地方调用。
答案 0 :(得分:8)
如果查看DateTime.TryParseExact
的签名,则需要IFormatProvider作为第三个参数。 DateTimeFormatInfo.InvariantInfo
和CultureInfo.InvariantCulture
都实现了此接口,因此在两种情况下,您实际上都在DateTime
上调用相同的方法。
在内部,如果您使用CultureInfo.InvariantCulture
,则会调用其DateTimeFormat属性来获取DateTimeFormatInfo
实例。如果您使用DateTimeFormatInfo.InvariantInfo
,则会直接使用。 DateTimeFormatInfo
调用将稍微更快,因为它必须执行较少的指令,但这将是如此微不足道,以至于(几乎)所有情况都没有区别。
这两种方法的主要区别在于语法。使用你发现最清楚的那个。
答案 1 :(得分:3)
他们会给出相同的结果 并且性能不太可能存在任何差异。
因此,请使用您认为最具可读性的内容。我的选择是DateTimeFormatInfo.InvariantInfo
稍微多一点。
答案 2 :(得分:0)
对于像我这样从Google毕业的人来说,我发现Matt Weber的以下帖子对于理解实施细节非常有用:
让我在这里引用大部分文章,以防链接在某些时候中断:
DateTimeFormatInfo.CurrentInfo
这将直接返回另一个DateTimeFormatInfo实例,该实例是 适应当前的文化。为此,它执行以下操作:
- 从当前线程的CurrentCulture属性(Thread.CurrentThread.CurrentCulture)获取CultureInfo。请注意,当您 访问当前线程的CurrentCulture属性,您正在 基本上访问CultureInfo.CurrentCulture属性(其中 只需返回Thread.CurrentThread.CurrentCulture)。
- 如果线程的当前区域性实例本身是基本CultureInfo类型本身,则不是直接返回日期时间格式的引用 推导。 CultureInfo对象的DateTimeFormat属性 在这里没有发挥作用;相反,我们直接阅读的是 来自CultureInfo对象的dateTimeInfo私有字段。
- 如果线程的当前区域性实例在其日期时间信息字段中分配了null,则CultureInfo的GetFormat方法 被调用,它返回一个DateTimeFormatInfo实例,然后 返回。
- 如果当前线程的区域性实例实际上是从CultureInfo派生的对象类型,则它将始终调用 CultureInfo.GetFormat,并且从不读取 CultureInfo.dateTimeInfo字段。
因此,如果您要处理来自CultureInfo和 设置线程的当前文化以使用它们,请注意, 可以通过重写来修改DateTimeFormatInfo返回的方式 CultureInfo的GetFormat方法。
DateTimeFormatInfo.InvariantInfo
这将返回另一个DateTimeFormatInfo实例,该实例设置为 对文化不敏感的文化。为此,它执行以下操作:
- 如果当前的应用程序域已经创建了不区分文化的DateTimeFormatInfo实例,则返回该实例。
- 否则,将使用DateTimeFormatInfo的公共默认构造函数创建一个新实例。
- 新的DateTimeFormatInfo实例公开的日历设置为只读。
- 新的DateTimeFormatInfo实例本身设置为只读,然后返回。
因此,与DateTimeFormatInfo.CurrentInfo不同,InvariantInfo属性 每个应用程序域而不是每个线程初始化一次。不是很 大惊喜,但重要的是要知道 做任何冒险的(很可能)不负责任的事情。
CultureInfo.CurrentCulture.DateTimeFormat
这将返回一个DateTimeFormatInfo对象,设置为使用当前对象 文化。这可以通过以下方式实现:
- 因为我们正在访问CultureInfo.CurrentCulture,所以将当前线程的CurrentCulture用作区域性 (Thread.CurrentThread.CurrentCulture)。
- 如果当前线程的区域性实例已经初始化了DateTimeFormatInfo实例,则将其返回(即,如果 dateTimeInfo不为null,则返回该值。)
- 否则,通过直接初始化新的DateTimeFormatInfo实例并传递区域性来创建新的DateTimeFormatInfo对象。 数据传递给构造函数。
- DateTimeFormatInfo实例设置为只读。
- 调用Thread.MemoryBarrier,然后将新初始化的DateTimeFormatInfo实例分配给 dateTimeInfo字段。
CultureInfo.CurrentCulture.DateTimeFormat与如何相关 DateTimeFormat.CurrentInfo?
- CultureInfo.CurrentCulture.DateTimeFormat属性是负责实际初始化DateTimeFormatInfo实例的内容 得到退还;调用DateTimeFormat.CurrentInfo会导致 对区域性的GetFormat方法的调用,该方法本身将返回 它自己的CultureInfo.DateTimeFormat属性。所以,无论在哪里 开始时,您似乎最终会在同一个地方。从技术上讲, CultureInfo.CurrentCulture.DateTimeFormat比调用更直接 DateTimeFormat.CurrentInfo,最终将仅调用该时间。
- 当人们开始谈论从CultureInfo派生的对象类型时,就会出现分歧。假设我们希望自己的习惯 CultureInfo类返回一个DateTimeFormatInfo实例,该实例是 以与规范不同的方式进行了修改。通过覆盖 CultureInfo.GetFormat,这是一个虚拟方法,我们可以实现 用于对DateTimeFormat.CurrentInfo的调用,它将调用此方法 方法。
- 但是,因为CultureInfo.DateTimeFormat是静态属性,并且因为完成了DateTimeFormatInfo对象的实例化 直接在此属性内,无法覆盖此属性 行为。因此,我们很容易会遇到以下情况 DateTimeFormatInfo.CurrentInfo返回一个不同的组成 DateTimeFormatInfo实例比我们得到的 CultureInfo.CurrentCulture.DateTimeFormat(假设当前 文化是我们的习俗文化课。
- 这使我们对我们的愿望可能无法实现(在定制之后定制与创建相关的逻辑) 文化的日期时间格式)。希望那里没有人需要做 这个。
CultureInfo.InvariantCulture.DateTimeFormat
- 这将返回不区分文化的DateTimeFormatInfo。
- 不变文化在每个应用程序域中一个(在CultureInfo类的静态构造函数内部)创建。
- 创建不变的CultureInfo实例后,创建DateTimeFormatInfo的其余过程将与 上一节。
CultureInfo.InvariantCulture.DateTimeFormat与如何相关 DateTimeFormat.InvariantInfo?
- 这两个属性与它们的CurrentCulture型兄弟不同,它们在初始化DateTimeFormatInfo的方式上是完全无关的 他们返回的实例。
- DateTimeFormat.InvariantInfo属性实际上根本不处理区域性。它只是初始化一个新的DateTimeFormatInfo 实例使用该类的默认构造函数。
- 尽管它们的创建机制是不相关的,但它们的相似之处在于它们无法在创建这些机制时施加任何影响 据我所知,是从派生类构造的。