On This Page
Overview and Description
Like date and calendar formats, time formats are not constant throughout the world. Although each representation of time basically displays the hour, minutes, and seconds, their presentation order and separators vary greatly. In fact, there might be many differences between regions within the same country. The time formatting might differ from one culture to another in one of the following three ways:
Important: Changing the user locale or the locale variable does not adjust the time zone by default.
Figure 1: Time formatting for Greek user locale.
Figure 2: Time Zone page of Date And Time Properties property sheet.
Time Formatting and Time Zones in Win32
To format time in the default settings of a given locale or as specified by the user in the Regional and Language Options Control Panel, you can use GetTimeFormat. This function formats time--either a specified time or the local system time--as a time string for a specified locale.
The following code sample displays the current system time for the current user locale, using the default time format for that locale:
Execution of this code would give the following result on English (United States) and Punjabi user locales, respectively. (See Figure 3 below)
Figure 3: Time formatted for English (United States) and Punjabi user locales
As you saw in the previous example, the time formatting can be completely different from one locale to another. In this case, the use of a leading 0 in the hour representation, as well as the actual translation and positioning of P.M., change based on country and cultural standards. But even within the same locale or culture there is a variety of possible ways to format time: short or long formatting. The EnumTimeFormats function enumerates the time formats that are available for a specified locale. It does so by passing (to a callback function that an application defines) a pointer to a buffer that contains a time format. The EnumTimeFormats continues to do so until no more time formats are found, or until the callback function returns FALSE. Here is how the code works:
Execution of this code would give the following result on English (United States) and French (France) user locales, respectively. (See Figure 4 below.)
Figure 4: Time formats for English (United States) and French (France) user locales
The obtained result (format picture) can then be used as an lpFormat argument in a call to GetTimeFormat. This allows you to use an alternative formatting for the time. The following elements can be used to construct a format-picture string. (See Table 1 below.) If you use spaces to separate the elements in the format string, these spaces will appear in the same location in the output string. The letters must adhere to the casing conventions shown in the table. (For example, the correct formatting for "Seconds with leading zero for single-digit seconds" would be "ss" not "SS".) Characters in the format string that are enclosed in single quotation marks will appear in the same location and will be unchanged in the output string.
Table 1: Elements for constructing a format-picture string.
For example, to get the time string:
The Bias parameter of the TIME_ZONE_INFORMATION structure is the difference, in minutes, between UTC time and local time.
All translations between UTC time and local time are based on the following formula:
Unfortunately, Win32 APIs do not offer a solution to enumerate information relative to any other time zone than the one currently selected by the user. GetLocalTime and GetSystemTime will allow you to retrieve the current local and the UTC times, respectively. To convert the local time to UTC, you can use the LocalFileTimeToFileTime API. These are but two of the many Win32 APIs dealing with time. To learn about other functions, search for "time functions" on http://msdn2.microsoft.com.
Time Formatting and Time Zones in .NET Framework
The easiest and most efficient way of doing time formatting in the .NET world is to take advantage of the DateTime structure that provides methods such as DateTime.ToString and DateTime.Parse. These methods allow you to perform culture-sensitive operations on a DateTime object. Use the DateTimeFormatInfo class to format and display a DateTime based on culture. DateTimeFormatInfo defines how DateTime values are formatted and displayed, depending on the culture. For example, using the LongTimePattern, the time 4 hours P.M., 36 minutes and 15 seconds is formatted as 4:36:15 PM for the "en-US" culture and 16:36:15 for the "fr-FR" culture number-formatting standards. (For more information and code samples, see the Date Formatting article.)
Methods and properties in the DateTime structure always use the local time zone for calculations and comparisons. You should consider this when using the DateTime.Parse method and the DateTime.ParseExact method. These methods provide overloads that allow you to convert the string representation of a date and time to a DateTime type. You can also choose to format a DateTime for a specific culture. If you do not specify a time zone in the string that you pass to these methods, they return the parsed date and time without performing a time-zone adjustment. The date and time are based on the system's time-zone setting. If you specify a time-zone offset, these methods parse the date/time string, convert it to UTC, and then convert it to the time on the local system.
Use the DateTime.ToUniversalTime method to convert a local DateTime to its UTC equivalent. To parse a date/time string and convert it to a UTC DateTime, use the DateTimeStyles enumeration AdjustToUniversal value with either the DateTime.Parse or DateTime.ParseExact method. These DateTime manipulations are illustrated in the following code example. This example creates a DateTime for the local time and then converts it to the UTC equivalent DateTime. Both types are converted to strings and written to the console. Notice that the strings differ by the UTC offset between the local time zone and UTC. (For more information on the UTC offset for various time zones, see the TimeZone.GetUtcOffset method in the Microsoft Developer Network documentation at http://msdn2.microsoft.com.) These strings are converted back to DateTime types using the DateTime.ParseExact method. To capture the time-zone information stored in utcdt, the AdjustToUniversal value must be specified as a parameter to the DateTime.ParseExact method.
This code produces the following output:
Another vital point to consider when creating an application that is locale-aware is how currency is displayed. Since money is a valued commodity, it is essential that such things as the correct currency symbol as well as the appropriate decimal and thousands separator be used, for example, or the consequences could potentially be disastrous!
Time Formatting in Web Pages
In "Retrieving the Browser Language Setting" in the Use Locale Model article, you saw how to retrieve the current browser locale on the client side and how to set the global locale of your context or session to this value. After the appropriate locale has been set, you can easily format the time using FormatDateTime, a locale-aware function. Suppose you have retrieved the Chinese (Taiwan) locale as the primary browser locale ("zh-TW" is the default value for this locale). The following code saves the current context locale (matching the server's user locale), sets the locale to Chinese (Taiwan), formats the date in Chinese (Taiwan) format, and restores the original locale.
And the output would be:
Obviously the scripting technology does not offer the same flexibility to manipulate time formats as NLS APIs do in the case of Win32 programming. However, the FormatDateTime function gives you the ability to display time in the user's cultural preferences in both short- and long-time formats.