Dátumok standard módon

Aki az életben már legalább egyszer megnyerte azt a nemes feladatot, hogy egy weboldalhoz RSS feedet készítsen, biztosan belefutott a dátumformázással kapcsolatos macerákba. Az RSS 2.0 szabvány szerint a dátumoknak, például a pubDate mezőnek az RFC 822 "szabványt" (ami 1982. augusztus 13. óta létezik!) kell követniük:

All date-times in RSS conform to the Date and Time Specification of RFC 822, with the exception that the year may be expressed with two characters or four characters (four preferred).

Azaz például (szintén a szabványból):

Sat, 07 Sep 2002 00:00:01 GMT

Nézzünk egy kicsit jobban utána ennek, konkrétan az RFC 822 (STANDARD FOR THE FORMAT OF ARPA INTERNET TEXT MESSAGES) ötödik, Date and Time Specification fejezete foglalkozik a dátum- és idő formátummal. Nem hoszzú, idemásolom:

     5.  DATE AND TIME SPECIFICATION

     5.1.  SYNTAX

     date-time   =  [ day "," ] date time        ; dd mm yy
                                                 ;  hh:mm:ss zzz

     day         =  "Mon"  / "Tue" /  "Wed"  / "Thu"
                 /  "Fri"  / "Sat" /  "Sun"

     date        =  1*2DIGIT month 2DIGIT        ; day month year
                                                 ;  e.g. 20 Jun 82

     month       =  "Jan"  /  "Feb" /  "Mar"  /  "Apr"
                 /  "May"  /  "Jun" /  "Jul"  /  "Aug"
                 /  "Sep"  /  "Oct" /  "Nov"  /  "Dec"

     time        =  hour zone                    ; ANSI and Military

     hour        =  2DIGIT ":" 2DIGIT [":" 2DIGIT]
                                                 ; 00:00:00 - 23:59:59

     zone        =  "UT"  / "GMT"                ; Universal Time
                                                 ; North American : UT
                 /  "EST" / "EDT"                ;  Eastern:  - 5/ - 4
                 /  "CST" / "CDT"                ;  Central:  - 6/ - 5
                 /  "MST" / "MDT"                ;  Mountain: - 7/ - 6
                 /  "PST" / "PDT"                ;  Pacific:  - 8/ - 7
                 /  1ALPHA                       ; Military: Z = UT;
                                                 ;  A:-1; (J not used)
                                                 ;  M:-12; N:+1; Y:+12
                 / ( ("+" / "-") 4DIGIT )        ; Local differential
                                                 ;  hours+min. (HHMM)

     5.2.  SEMANTICS

          If included, day-of-week must be the day implied by the date
     specification.

          Time zone may be indicated in several ways.  "UT" is Univer-
     sal  Time  (formerly called "Greenwich Mean Time"); "GMT" is per-
     mitted as a reference to Universal Time.  The  military  standard
     uses  a  single  character for each zone.  "Z" is Universal Time.
     "A" indicates one hour earlier, and "M" indicates 12  hours  ear-
     lier;  "N"  is  one  hour  later, and "Y" is 12 hours later.  The
     letter "J" is not used.  The other remaining two forms are  taken
     from ANSI standard X3.51-1975.  One allows explicit indication of
     the amount of offset from UT; the other uses  common  3-character
     strings for indicating time zones in North America.

Hogyan lehetne ezt előállítani .NET-ben, hiszen nincs közvetlenül olyan dátumformátumunk, ami pont ilyen lenne. Próbáljuk összerakni:

    Console.WriteLine( DateTime.Now.ToString("ddd, dd MMM yyyy HH:mm:ss zzz") );

Ebből ez lesz a konzolon, ami nem éppen az igazi:

Cs, 30 aug. 2007 11:41:39 +02:00

Írhatunk hozzá hosszabb kódot, például így (vagy akár szebben is): 

    public static string ToRfc822String( DateTime date )
    {
        int offset = TimeZone.CurrentTimeZone.GetUtcOffset( DateTime.Now ).Hours;
        char sign = '+';

        if( offset < 0 )
        {
            sign = '-';
            offset = offset * -1;
        }

        string zone = ( sign + offset.ToString().PadLeft( 2, '0' ) ).PadRight( 5, '0' );
        return date.ToString( "ddd, dd MMM yyyy HH:mm:ss " + zone, CultureInfo.InvariantCulture );
    }

Külön figyelmet érdemel az InvariantCulture alkalmazása, enélkül ugyanis szép magyar hónap és nap nevek jönnének, mivel azonban a kultúra információkért felelős .NET fejlesztő csapat szerint, ha valami invariáns, akkor legyen angol, éppen rendben vagyunk:

Thu, 30 Aug 2007 11:05:13 +0200

Bár a fenti kódrészletet valószínűleg meg lehet írni szebben és tömörebben, rutinos .NET fejlesztő nehezen hiszi el, hogy erre nem gondoltak a keretrendszer fejlesztői és saját függvény írására vagyunk kárhoztatva. Alaposabban nézegetve az MSDN Standard DateTime Format Strings fejezetét feltűnhet egy formátum, ami kilóg a sorból:

R or r:  RFC1123 pattern

Represents a custom DateTime format string defined by the current RFC1123Pattern property. The pattern is a defined standard and the property is read-only. Therefore, it is always the same regardless of the culture used or the format provider supplied.

The custom format string is "ddd, dd MMM yyyy HH':'mm':'ss 'GMT'".

Formatting does not modify the value of the DateTime object that is being formatted. Therefore, the application must convert the value to Coordinated Universal Time (UTC) before using this format specifier.

Hm, ez a formátum kísértetiesen hasonlít az RFC 822 formátumára, nézzük csak meg, hogy mit mond az 1989. októberéből származó RFC 1123, ami a "Requirements for Internet Hosts - Application and Support" címre hallgat! Ennek az 5.2.14 Date and Time Specification fejezete közvetlenül hivatkozik az RFC 822 Section 5-re, némi kiegészítéssel:

         The syntax for the date is hereby changed to:

            date = 1*2DIGIT month 2*4DIGIT

         All mail software SHOULD use 4-digit years in dates, to ease
         the transition to the next century.

         There is a strong trend towards the use of numeric timezone
         indicators, and implementations SHOULD use numeric timezones
         instead of timezone names.  However, all implementations MUST
         accept either notation.  If timezone names are used, they MUST
         be exactly as defined in RFC-822.

         The military time zones are specified incorrectly in RFC-822:
         they count the wrong way from UT (the signs are reversed).  As
         a result, military time zones in RFC-822 headers carry no
         information.

         Finally, note that there is a typo in the definition of "zone"
         in the syntax summary of appendix D; the correct definition
         occurs in Section 3 of RFC-822.

Tehát a különbségek:

  • 4 digites évszámokat kell használni
  • Számokkal kell leírni az időzónákat.

Ez kibírható, próbáljuk ki!

    Console.WriteLine( DateTime.Now.ToUniversalTime().ToString( "R" ) );

A kimenet pedig ez lesz:

Thu, 30 Aug 2007 09:23:15 GMT

A kérdés tehát: kell-e saját dátumformázó függvényt írnunk, vagy jó lesz a ToString("R") is?

A fentiek alapján elmondhatjuk, hogy a beépített dátumformátum megfelel az RSS előírásainak, tehát használható, sőt valószínűleg ez a legegyszerűbb megoldás. Ugyanakkor meg kell jegyeznünk, hogy a keretrendszer nem követi teljesen az RFC 1123-at, mert nem numerikus időzóna meghatározásokat használ.



Balássy György (MS RD, ASP.NET MVP, MCTS)

Balássy György (MS RD, ASP.NET MVP, MCTS) Villamosmérnök, a BME Automatizálási és Alkalmazott Informatikai Tanszékén webportálok fejlesztését oktatja. 2000 óta foglalkozik a Microsoft .NET platformjával, melynek meghonosításában jelentős szerepet vállalt előadóként, konzulensként és A .NET Framework és programozása című könyv társszerzőjeként. Az MSDN Kompetencia Központon belül a Portál Technológiák Csoport vezetője, szakterülete web alapú rendszerek fejlesztése és üzemeltetése. 2004-ben Magyarországon elsőként kapta meg a Most Valuable Professional címet, majd 2005 óta a Microsoft magyarországi regionális igazgatója. Publikációi a Technet Magazinban, az MSDN Kompetencia Központ honlapján és szakmai blogjában olvashatóak.

2007.08.30. 12:19:10 | Permalink | Hozzászólások: 0 | Tárgyszavak:


  • LESS

    Balássy György (MS RD, ASP.NET MVP, MCTS) Weboldalak dizájn részének szerkesztése közben gyakran előjön az az érzés, hogy a CSS bizony egy buta jószág. Sok mindent meg lehet vele csinálni szépen, de kinek nem volt még olyan gondolata, hogy de jó lenne, ha legalább konstansokat tudnánk definiálni vagy egyik osztály örökölhetne beállításokat másik osztálytól? Tovább »
  • Az ASP.NET Cache beállításai

    Dávid Zoltán Míg a renderelt HTML válasz gyorsítótárazására az OutputCache használható, addig az adatokéra a HttpContext.Cache. Ez viszont a fizikai memória telítettségének és néhány előre drótózott bűvszámnak a függvényében kihajigálja magából az elemeket. Ez egy biztonsági mechanizmus, hogy ne legyen swap, ne legyen OutOfMemoryException vagy ne makkantsuk meg a GarbageCollectort túl sok “szeméttel”. Az, hogy pontosan mik ezek a bűvszámok és, hogy miért alakultak így elolvasható itt. Ami viszont sokkal fontosabb az, hogy ezek a határok hogyan állíthatók át. Íme. Tovább »


Írja meg Ön is véleményét!


Hozzászólásokat csak regisztrált, bejelentkezett felhasználóktól tudunk elfogadni!

Hozzászólások