Monday, March 17, 2008

Culture dependent date formatting


This week's Windows PowerShell Tip of the Week was on Creating a Graphical Date Picker. It shows an excellent way to overcome the difficulty of controlling the user's date-format when entering a date at the command prompt.

Anyway, It was intriguing and I found myself venturing into dates and cultures. I wanted to see how DateTime values are formatted and displayed, depending on the culture (specifically the ShortTimePattern).

The CultureInfo class provides information about a specific culture. The information includes the names for the culture, the writing system, the calendar used, and formatting for dates and sort strings. 

To get the above information for a specific Culture/Language Name you can pass the culture name to the cultureInfo constructor. The DateTimeFormat member shows all the members involved when a date is formatted.


$ci = new-object system.globalization.cultureInfo "en-US"

AMDesignator                     : AM
Calendar                         : System.Globalization.GregorianCalendar
DateSeparator                    : /
FirstDayOfWeek                   : Sunday
CalendarWeekRule                 : FirstDay
FullDateTimePattern              : dddd, MMMM dd, yyyy h:mm:ss tt
LongDatePattern                  : dddd, MMMM dd, yyyy
LongTimePattern                  : h:mm:ss tt
MonthDayPattern                  : MMMM dd
PMDesignator                     : PM
RFC1123Pattern                   : ddd, dd MMM yyyy HH':'mm':'ss 'GMT'
ShortDatePattern                 : M/d/yyyy
ShortTimePattern                 : h:mm tt
SortableDateTimePattern          : yyyy'-'MM'-'dd'T'HH':'mm':'ss
TimeSeparator                    : :
UniversalSortableDateTimePattern : yyyy'-'MM'-'dd HH':'mm':'ss'Z'
YearMonthPattern                 : MMMM, yyyy
AbbreviatedDayNames              : {Sun, Mon, Tue, Wed...}
ShortestDayNames                 : {Su, Mo, Tu, We...}
DayNames                         : {Sunday, Monday, Tuesday, Wednesday...}
AbbreviatedMonthNames            : {Jan, Feb, Mar, Apr...}
MonthNames                       : {January, February, March, April...}
IsReadOnly                       : False
NativeCalendarName               : Gregorian Calendar
AbbreviatedMonthGenitiveNames    : {Jan, Feb, Mar, Apr...}
MonthGenitiveNames               : {January, February, March, April...}


Based on the above it is very easy to construct a table that gets all cultures and format each culture date according to its ShortTimePattern pattern. Note that some cultures do not have ShortTimePattern hence the where clause:

$date = @{n="Date";e={Get-Date -f $_.DateTimeFormat.ShortDatePattern}}
$sdp = @{n="Pattern";e={$_.DateTimeFormat.ShortDatePattern}}
$cultures = [System.Globalization.CultureInfo]::GetCultures("AllCultures")
$cultures | where {$_.DateTimeFormat.ShortDatePattern} | select LCID,Name,DisplayName,$date,$sdp | ft -a



Note the first culture in the sample output. An Invariant culture is culture-insensitive (independent). Your application specifies the invariant culture by name using an empty string ("") or by its identifier. InvariantCulture defines an instance of the invariant culture. It is associated with the English language but not with any country/region. It is used in almost any method in the Globalization namespace that requires a culture.




There is also the DateTimeFormatInfo Class. This class contains information, such as date patterns, time patterns, and AM/PM designators. It also offers a comprehensive list of custom DateTime format patterns and their behavior which you can use when formatting dates with Get-Date or with the ToString() method.

No comments: