DateTimeFormatInfo.InvariantInfo vs CultureInfo.InvariantCulture

时间:2009-10-08 07:29:00

标签: c# .net optimization datetime

我正在尝试解析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);

当然,这段代码在一个常见的静态方法中,在需要解析日期的地方调用。

3 个答案:

答案 0 :(得分:8)

如果查看DateTime.TryParseExact的签名,则需要IFormatProvider作为第三个参数。 DateTimeFormatInfo.InvariantInfoCultureInfo.InvariantCulture都实现了此接口,因此在两种情况下,您实际上都在DateTime上调用相同的方法。

在内部,如果您使用CultureInfo.InvariantCulture,则会调用其DateTimeFormat属性来获取DateTimeFormatInfo实例。如果您使用DateTimeFormatInfo.InvariantInfo,则会直接使用。 DateTimeFormatInfo调用将稍微更快,因为它必须执行较少的指令,但这将是如此微不足道,以至于(几乎)所有情况都没有区别。

这两种方法的主要区别在于语法。使用你发现最清楚的那个。

答案 1 :(得分:3)

他们会给出相同的结果 并且性能不太可能存在任何差异。

因此,请使用您认为最具可读性的内容。我的选择是DateTimeFormatInfo.InvariantInfo稍微多一点。

答案 2 :(得分:0)

对于像我这样从Google毕业的人来说,我发现Matt Weber的以下帖子对于理解实施细节非常有用:

http://badecho.com/2011/07/datetimeformatinfo-currentinfo-vs-cultureinfo-currentculture-datetimeformat-vs/

让我在这里引用大部分文章,以防链接在某些时候中断:

DateTimeFormatInfo.CurrentInfo

这将直接返回另一个DateTimeFormatInfo实例,该实例是 适应当前的文化。为此,它执行以下操作:

  1. 从当前线程的CurrentCulture属性(Thread.CurrentThread.CurrentCulture)获取CultureInfo。请注意,当您 访问当前线程的CurrentCulture属性,您正在 基本上访问CultureInfo.CurrentCulture属性(其中 只需返回Thread.CurrentThread.CurrentCulture)。
  2. 如果线程的当前区域性实例本身是基本CultureInfo类型本身,则不是直接返回日期时间格式的引用 推导。 CultureInfo对象的DateTimeFormat属性 在这里没有发挥作用;相反,我们直接阅读的是 来自CultureInfo对象的dateTimeInfo私有字段。
  3. 如果线程的当前区域性实例在其日期时间信息字段中分配了null,则CultureInfo的GetFormat方法 被调用,它返回一个DateTimeFormatInfo实例,然后 返回。
  4. 如果当前线程的区域性实例实际上是从CultureInfo派生的对象类型,则它将始终调用 CultureInfo.GetFormat,并且从不读取 CultureInfo.dateTimeInfo字段。

因此,如果您要处理来自CultureInfo和 设置线程的当前文化以使用它们,请注意, 可以通过重写来修改DateTimeFormatInfo返回的方式 CultureInfo的GetFormat方法。

DateTimeFormatInfo.InvariantInfo

这将返回另一个DateTimeFormatInfo实例,该实例设置为 对文化不敏感的文化。为此,它执行以下操作:

  1. 如果当前的应用程序域已经创建了不区分文化的DateTimeFormatInfo实例,则返回该实例。
  2. 否则,将使用DateTimeFormatInfo的公共默认构造函数创建一个新实例。
  3. 新的DateTimeFormatInfo实例公开的日历设置为只读。
  4. 新的DateTimeFormatInfo实例本身设置为只读,然后返回。

因此,与DateTimeFormatInfo.CurrentInfo不同,InvariantInfo属性 每个应用程序域而不是每个线程初始化一次。不是很 大惊喜,但重要的是要知道 做任何冒险的(很可能)不负责任的事情。

CultureInfo.CurrentCulture.DateTimeFormat

这将返回一个DateTimeFormatInfo对象,设置为使用当前对象 文化。这可以通过以下方式实现:

  1. 因为我们正在访问CultureInfo.CurrentCulture,所以将当前线程的CurrentCulture用作区域性 (Thread.CurrentThread.CurrentCulture)。
  2. 如果当前线程的区域性实例已经初始化了DateTimeFormatInfo实例,则将其返回(即,如果 dateTimeInfo不为null,则返回该值。)
  3. 否则,通过直接初始化新的DateTimeFormatInfo实例并传递区域性来创建新的DateTimeFormatInfo对象。 数据传递给构造函数。
  4. DateTimeFormatInfo实例设置为只读。
  5. 调用Thread.MemoryBarrier,然后将新初始化的DateTimeFormatInfo实例分配给 dateTimeInfo字段。

CultureInfo.CurrentCulture.DateTimeFormat与如何相关 DateTimeFormat.CurrentInfo?

  1. CultureInfo.CurrentCulture.DateTimeFormat属性是负责实际初始化DateTimeFormatInfo实例的内容 得到退还;调用DateTimeFormat.CurrentInfo会导致 对区域性的GetFormat方法的调用,该方法本身将返回 它自己的CultureInfo.DateTimeFormat属性。所以,无论在哪里 开始时,您似乎最终会在同一个地方。从技术上讲, CultureInfo.CurrentCulture.DateTimeFormat比调用更直接 DateTimeFormat.CurrentInfo,最终将仅调用该时间。
  2. 当人们开始谈论从CultureInfo派生的对象类型时,就会出现分歧。假设我们希望自己的习惯 CultureInfo类返回一个DateTimeFormatInfo实例,该实例是 以与规范不同的方式进行了修改。通过覆盖 CultureInfo.GetFormat,这是一个虚拟方法,我们可以实现 用于对DateTimeFormat.CurrentInfo的调用,它将调用此方法 方法。
  3. 但是,因为CultureInfo.DateTimeFormat是静态属性,并且因为完成了DateTimeFormatInfo对象的实例化 直接在此属性内,无法覆盖此属性 行为。因此,我们很容易会遇到以下情况 DateTimeFormatInfo.CurrentInfo返回一个不同的组成 DateTimeFormatInfo实例比我们得到的 CultureInfo.CurrentCulture.DateTimeFormat(假设当前 文化是我们的习俗文化课。
  4. 这使我们对我们的愿望可能无法实现(在定制之后定制与创建相关的逻辑) 文化的日期时间格式)。希望那里没有人需要做 这个。

CultureInfo.InvariantCulture.DateTimeFormat

  1. 这将返回不区分文化的DateTimeFormatInfo。
  2. 不变文化在每个应用程序域中一个(在CultureInfo类的静态构造函数内部)创建。
  3. 创建不变的CultureInfo实例后,创建DateTimeFormatInfo的其余过程将与 上一节。

CultureInfo.InvariantCulture.DateTimeFormat与如何相关 DateTimeFormat.InvariantInfo?

  1. 这两个属性与它们的CurrentCulture型兄弟不同,它们在初始化DateTimeFormatInfo的方式上是完全无关的 他们返回的实例。
  2. DateTimeFormat.InvariantInfo属性实际上根本不处理区域性。它只是初始化一个新的DateTimeFormatInfo 实例使用该类的默认构造函数。
  3. 尽管它们的创建机制是不相关的,但它们的相似之处在于它们无法在创建这些机制时施加任何影响 据我所知,是从派生类构造的。