101

我在玩 Datetime.ParseExact 方法,它需要一个 IFormatProvider ......

它可以输入null,但它到底是做什么的?

4

9 回答 9

65

除了伊恩博伊德的回答:

CultureInfo实现了这个接口,可以在你的情况下使用。例如,您可以解析法语日期字符串;你可以使用

var ci = new CultureInfo("fr-FR");
DateTime dt = DateTime.ParseExact(yourDateInputString, yourFormatString, ci);
于 2009-02-04T13:13:48.340 回答
50

IFormatProvider接口通常由一个CultureInfo类为您实现,例如:

  • CultureInfo.CurrentCulture
  • CultureInfo.CurrentUICulture
  • CultureInfo.InvariantCulture
  • CultureInfo.CreateSpecificCulture("de-CA") //German (Canada)

该接口是一个函数的网关,用于从一种文化中获取一组特定于文化的数据。IFormatProvider可以查询的两个常用区域性对象是:

它通常的工作方式是你要求IFormatProvider给你一个DateTimeFormatInfo对象:

DateTimeFormatInfo? format;
format = (DateTimeFormatInfo)provider.GetFormat(typeof(DateTimeFormatInfo));
if (format != null)
   DoStuffWithDatesOrTimes(format);

还有内部知识,任何IFormatProvider接口都可能由继承自CultureInfo或 继承自的类实现DateTimeFormatInfo,因此您可以直接转换接口:

CultureInfo? info = provider as CultureInfo;
if (info != null)
   format = info.DateTimeInfo;
else
{
   DateTimeFormatInfo? dtfi = provider as DateTimeFormatInfo;
   if (dtfi != null)
       format = dtfi;
   else
       format = (DateTimeFormatInfo)provider.GetFormat(typeof(DateTimeFormatInfo));
}

if (format != null)
   DoStuffWithDatesOrTimes(format);

但不要那样做

所有辛苦的工作都已经为您编写好了:

DateTimeFormatInfo从a 中获取 aIFormatProvider

DateTimeFormatInfo format = DateTimeFormatInfo.GetInstance(provider);

NumberFormatInfo从a 中获取 aIFormatProvider

NumberFormatInfo format = NumberFormatInfo.GetInstance(provider);

的优点IFormatProvider是您可以创建自己的文化对象。只要他们实现IFormatProvider并返回他们被要求的对象,你就可以绕过内置的文化。

您还可以使用IFormatProvider传递任意文化对象的方式 - 通过IFormatProvider. 例如不同文化中神的名字

  • 上帝
  • 上帝
  • 约娃
  • 耶和华
  • 耶和华
  • אהיה אשר אהיה

这可以让您的自定义LordsNameFormatInfo类在IFormatProvider.

实际上,您永远不需要调用自己GetFormat的方法IFormatProvider

每当您需要时,IFormatProvider您都可以传递一个CultureInfo对象:

DateTime.Now.ToString(CultureInfo.CurrentCulture);

endTime.ToString(CultureInfo.InvariantCulture);

transactionID.toString(CultureInfo.CreateSpecificCulture("qps-ploc"));

注意:任何代码都会发布到公共领域。无需归属。

于 2013-08-12T19:41:57.147 回答
18

将 null 作为 the 传递IFormatProvider不是正确的方法。如果用户在其 PC 上具有自定义日期/时间格式,您将在解析和转换为字符串时遇到问题。我刚刚修复了一个错误,即有人在转换为字符串时将 null 作为 IFormatProvider 传递。

相反,您应该使用CultureInfo.InvariantCulture

错误的:

string output = theDate.ToString("dd/MM/yy HH:mm:ss.fff", null);

正确的:

string output = theDate.ToString("dd/MM/yy HH:mm:ss.fff", CultureInfo.InvariantCulture);
于 2013-01-07T11:26:42.860 回答
5

IFormatProvider为相关方法提供文化信息。DateTimeFormatInfo实现 IFormatProvider,并允许您指定希望日期/时间显示的格式。示例可以在相关的 MSDN 页面上找到。

于 2009-02-03T11:09:51.757 回答
4

你可以在这里看到http://msdn.microsoft.com/en-us/library/system.iformatprovider.aspx

请参阅那里的备注和示例部分。

于 2009-02-03T10:49:32.967 回答
2

检查API 的http://msdn.microsoft.com/en-us/library/system.iformatprovider.aspx

于 2009-02-03T10:49:49.287 回答
2

通过MSDN

.NET Framework 包括以下三个预定义的 IFormatProvider 实现,以提供用于格式化或解析数字和日期和时间值的区域性特定信息:

  1. 该类NumberFormatInfo提供用于格式化数字的信息,例如特定文化的货币、千位分隔符和小数分隔符。有关NumberFormatInfo对象识别并用于数字格式化操作的预定义格式字符串的信息,请参阅标准数字格式字符串和自定义数字格式字符串。
  2. 该类DateTimeFormatInfo提供用于格式化日期和时间的信息,例如特定文化的日期和时间分隔符或日期的年、月和日组件的顺序和格式。有关DateTimeFormatInfo对象识别并用于数字格式化操作的预定义格式字符串的信息,请参阅标准日期和时间格式字符串和自定义日期和时间格式字符串。
  3. CultureInfo代表特定文化的类。它的GetFormat方法返回一个特定于文化的对象NumberFormatInfoDateTimeFormatInfo对象,具体取决于该CultureInfo对象是否用于涉及数字或日期和时间的格式化或解析操作。

.NET Framework 还支持自定义格式。这通常涉及创建实现 IFormatProvider 和 ICustomFormatter 的格式化类。然后将此类的实例作为参数传递给执行自定义格式化操作的方法,例如String.Format(IFormatProvider, String, Object[]).

于 2017-02-02T03:05:31.057 回答
1

DateTimeFormatInfo类实现了这个接口,因此它允许您控制 DateTime 字符串的格式。

于 2009-02-03T10:50:54.960 回答
1

该问题询问 IFormatProvider 和 DateTime,但您也可以在 .NET 的其他上下文中使用 IFormatProvider,例如用于 string.Format。

然后传入 IFormatProvider 实例,您可以通过实现 IFormatProvider 指定字符串如何为对象格式化。因此,IFormatProvider 和相关 ICustomFormatter 接口的使用在 .NET 中比仅用于日期更广泛。

例如考虑这个实现:

using System;

namespace ConsoleApp
{
    class EmployeeProductivityFormatProvider : IFormatProvider, ICustomFormatter
    {
        public string Format(string format, object arg, IFormatProvider formatProvider)
        {
            int rating = (int)arg;

            if (rating == 0)
            {
                return $"{rating} (new employee)";
            }

            if (rating > 0)
            {
                return $"{rating} (good employee)";
            }

            return $"{rating} (bad employee)";
        }

        public object GetFormat(Type formatType)
        {
            if (formatType == typeof(ICustomFormatter))
            {
                return this;
            }

            return null;
        }
    }
}

现在我们可以通过指定这样的 int 值来获取员工的字符串表示形式:

    string prod = string.Format(new EmployeeProductivityFormatProvider(),
                                "Productivity rating: {0}",
                                employee.ProductivityRating);

对于 DateTime,有很多已经创建的 IFormatProvider 实现可供选择。这是将对象表示为字符串并在 .NET 中指定其格式的一种非常灵活的方法,是一个非常笼统的概念。

于 2021-08-08T20:24:33.030 回答