2010-03-04 13 views
19

मैं IFormatProvider कार्यान्वयन बनाने की कोशिश कर रहा था जो डेटटाइम ऑब्जेक्ट्स के लिए कस्टम प्रारूप स्ट्रिंग को पहचान लेगा।डेटटाइम के लिए कस्टम IFormatProvider कैसे बनाएं और उपयोग करें?

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(); 
    } 
    } 

मैं बहुत तरह DateTime.ToString(string format, IFormatProvider provider) विधि में इसका इस्तेमाल करने में सक्षम होने की उम्मीद कर रहा था, लेकिन: अमेरिका संस्कृति में चल

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

कि उदाहरण में,, परिणाम है यहाँ मेरी कार्यान्वयन है "00cu0Ao00or0aA", जाहिर है क्योंकि मानक डेटटाइम प्रारूप तारों का व्याख्या किया जा रहा है।

हालांकि, जब मैं निम्नलिखित तरीके से एक ही कक्षा का उपयोग करें:

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

मुझे लगता है मैं क्या उम्मीद हो, अर्थात् "Sun Jan 02"

मैं अलग परिणाम समझ में नहीं आता। क्या कोई समझा सकता है?

धन्यवाद!

उत्तर

9

प्रतिबिंबक के साथ DateTime.ToString विधि की जांच से पता चलता है कि DateTime संरचना स्वरूपण के लिए प्रदाता को प्रयुक्त करने के लिए DateTimeFormatInfo.GetInstance विधि का उपयोग करती है। DateTimeFormatInfo.GetInstance प्रदाता से DateTimeFormatInfo प्रकार के प्रपत्रक से अनुरोध करता है, कभी भी ICustomFormmater के लिए, इसलिए यह केवल DateTimeFormatInfo या CultureInfo का कोई उदाहरण नहीं देता है यदि कोई प्रदाता नहीं मिलता है। ऐसा लगता है कि DateTime.ToString विधि ICustomFormatter इंटरफ़ेस का सम्मान नहीं करती है जैसे StringBuilder.Format विधि करता है, क्योंकि आपके String.Format उदाहरण दिखाता है।

मैं मानता हूं कि DateTime.ToString विधि ICustomFormatter इंटरफ़ेस का समर्थन करना चाहिए, लेकिन वर्तमान में ऐसा प्रतीत नहीं होता है। यह सब बदल गया है या .NET 4.0 में बदल जाएगा।

+0

विस्तृत उत्तर के लिए धन्यवाद। मैं सोच रहा था कि मैं इंटरफ़ेस और अपेक्षित कार्यान्वयन को गलत समझ रहा था, इसलिए यह जानना अच्छा है कि यह डेटटाइम कार्यान्वयन है जो निराशाजनक है :-) –

3

उपयोग विस्तार विधि :)

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); 
     } 
    } 
+0

हाँ, ऐसा लगता है कि विस्तार विधियां यहां मेरा एकमात्र विकल्प हैं। उत्तर के लिए धन्यवाद! –

17

संक्षिप्त विवरण है कि जब

DateTime.ToString(string format, IFormatProvider provider) 

आप इसे से एक के रूप IFormatProvider को लागू करने के लिए कुछ भी पारित की सुविधा देता है पैरामीटर, यह वास्तव में केवल IFormatProvider को लागू 2 संभव प्रकार का समर्थन करता है इसके अंदर कोड:

DateTimeFormatInfo या CultureInfo

यदि आपका पैरामीटर नहीं लगाया जा सकता है (as का उपयोग करके) या तो, यह विधि CurrentCulture पर डिफ़ॉल्ट हो जाएगी।

String.Format ऐसी सीमाओं से सीमित नहीं है।

संबंधित मुद्दे