So erstellen und einen benutzerdefinierten IFormatProvider für Datetime verwenden?

StackOverflow https://stackoverflow.com/questions/2382154

  •  24-09-2019
  •  | 
  •  

Frage

Ich habe versucht, eine IFormatProvider Implementierung zu erstellen, die benutzerdefinierten Formatstrings für Datetime-Objekte erkennen würde. Hier ist meine Implementierung:

 public class MyDateFormatProvider : IFormatProvider, ICustomFormatter
 {
  public object GetFormat(Type formatType)
  {
   if (formatType == typeof(ICustomFormatter))
   {
    return this;
   }
   return null;
  }

  public string Format(string format, object arg, IFormatProvider formatProvider)
  {
   if(arg == null) throw new ArgumentNullException("arg");
   if (arg.GetType() != typeof(DateTime)) return arg.ToString();
   DateTime date = (DateTime)arg;
   switch(format)
   {
    case "mycustomformat":
     switch(CultureInfo.CurrentCulture.Name)
     {
      case "en-GB":
       return date.ToString("ddd dd MMM");
      default:
       return date.ToString("ddd MMM dd");
     }
    default:
     throw new FormatException();
   }
  } 

Ich hatte erwartet, wie so in der Lage sein es in der DateTime.ToString(string format, IFormatProvider provider) Methode zu verwenden, aber:

DateTime d = new DateTime(2000, 1, 2);
string s = d.ToString("mycustomformat", new MyDateFormatProvider());

In diesem Beispiel in der US-Kultur läuft, ist das Ergebnis "00cu0Ao00or0aA", offenbar weil die Standard-Datetime-Format-Strings interpretiert werden.

Allerdings, wenn ich die gleiche Klasse wie folgt verwendet werden:

DateTime d = new DateTime(2000, 1, 2);
string s = String.Format(new MyDateFormatProvider(), "{0:mycustomformat}", d);

Ich bekomme, was ich erwarte, nämlich "Sun Jan 02"

Ich verstehe nicht, die unterschiedlichen Ergebnisse. Könnte jemand erklären?

Danke!

War es hilfreich?

Lösung

Überprüfen der DateTime.ToString Methode mit Reflector zeigt, dass die DateTime Struktur der DateTimeFormatInfo.GetInstance Methode verwendet den Anbieter zu bekommen, um für die Formatierung verwendet werden. Die DateTimeFormatInfo.GetInstance fordert einen Formatierer vom Typ DateTimeFormatInfo vom Provider übergeben, nie für ICustomFormmater, so dass es nur eine Instanz eines DateTimeFormatInfo oder CultureInfo zurückgibt, wenn kein Anbieter gefunden wird. Es scheint, dass die DateTime.ToString Methode nicht die ICustomFormatter Schnittstelle nicht einlöst wie die StringBuilder.Format Verfahren der Fall ist, wie Ihr String.Format Beispiel zeigt.

Ich bin damit einverstanden, dass die DateTime.ToString Methode, um die ICustomFormatter Schnittstelle unterstützen soll, aber es scheint nicht zu aktuell. Das alles kann sich geändert haben oder wird in .NET 4.0 ändern.

Andere Tipps

Die kurze Erklärung ist, dass während

DateTime.ToString(string format, IFormatProvider provider)

können Sie etwas passieren Umsetzung IFormatProvider als eines seiner Parameter, es tatsächlich unterstützt nur zwei mögliche Arten der Umsetzung IFormatProvider Inneren Code:

DateTimeFormatInfo oder CultureInfo

Wenn Ihr Parameter kann nicht gegossen werden (mit as) als entweder oder denjenigen, wird das Verfahren auf CurrentCulture Standard.

String.Format wird durch solche Grenzen nicht darauf beschränkt.

Mit Erweiterungsmethode:)

public static class FormatProviderExtension
    {
        public static string FormatIt(string format, object arg, IFormatProvider formatProvider)
        {
            if (arg == null) throw new ArgumentNullException("arg");
            if (arg.GetType() != typeof(DateTime)) return arg.ToString();
            DateTime date = (DateTime)arg;
            switch (format)
            {
                case "mycustomformat":
                    switch (CultureInfo.CurrentCulture.Name)
                    {
                        case "en-GB":
                            return date.ToString("ddd dd MMM");
                        default:
                            return date.ToString("ddd MMM dd");
                    }
                default:
                    throw new FormatException();
            }
        }

        public static string ToString(this DateTime d, IFormatProvider formatProvider, string format)
        {
            return FormatIt(format, d, formatProvider);
        }
    }
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top