Cue the smarter version of GetDateFormat... ok, it's a wrap!

by Michael S. Kaplan, published on 2006/09/01 16:41 -04:00, original URI: http://blogs.msdn.com/b/michkap/archive/2006/09/01/735817.aspx


I've mentioned Tarek Mahmoud Sayed from the GIFT development team in the past. The other day, in helping out some folks who were dealing with the issues I pointed out in How To [NOT] detect that a locale is bidi and They make 'em smarter than GetDateFormat, and at the end of the conversation had produced a nice wrapper around GetDateFormat that takes away the bulk of the need for developers calling GetDateFormat to figure out what flags to pass if they are not sure.

UPDATE 06 Oct 2006: Small addition to the code to handle an interesting case that the NLS function supports. It is marked in RED in the code. -- michkap 

I thought maybe I would post the code here so others could benefit! :-)

Anyway, here is the wrapper:

int GetDateFormatWrapper(
    LCID Locale,
    DWORD dwFlags,
    CONST SYSTEMTIME* lpDate,
    LPCTSTR lpFormat,
    LPTSTR lpDateStr,
    int cchDate
)
{
    DWORD dwBidiFlags = 0;

    if ((dwFlags & (DATE_LTRREADING | DATE_RTLREADING)) == 0)
    {
        WCHAR FontSignature[16];
        CALID CalId;

        Locale = ConvertDefaultLocale(Locale);
        dwBidiFlags = DATE_LTRREADING;

        if (GetLocaleInfo(
                Locale,
                LOCALE_FONTSIGNATURE,
                (LPWSTR) FontSignature,
                sizeof(FontSignature)/sizeof(FontSignature[0]))
             &&
                FontSignature[7] & 0x0800
             &&
                GetLocaleInfo(Locale,
                    LOCALE_ICALENDARTYPE | LOCALE_RETURN_NUMBER,
                    (LPWSTR) &CalId,
                    sizeof(CalId)/sizeof(WCHAR))) {

            // A small addition (in red) to help with the
            // myriad of ways GetDateFormat can be called
            if (((dwFlags & (DATE_YEARMONTH | DATE_SHORTDATE | DATE_LONGDATE) == 0))
              &&
                (lpFormat == NULL)) {
                dwFlags |= DATE_SHORTDATE;
            }

            // Bidi Locale
            if (PRIMARYLANGID(LANGIDFROMLCID(Locale)) == LANG_HEBREW) {
                if ((dwFlags & DATE_SHORTDATE) == 0 || CalId == CAL_HEBREW) {
                    dwBidiFlags = DATE_RTLREADING;
                }
            } else if ( CalId == CAL_GREGORIAN ||
                        CalId == CAL_HIJRI ||
                        CalId == 23 || // CAL_UMALQURA
                        CalId == CAL_GREGORIAN_ARABIC ||
                        CalId == CAL_GREGORIAN_XLIT_ENGLISH ||
                        CalId == CAL_GREGORIAN_XLIT_FRENCH) {
                dwBidiFlags = DATE_RTLREADING;
            }
        }
    }

    return GetDateFormat(Locale, dwFlags | dwBidiFlags, lpDate, lpFormat, lpDateStr, cchDate);
}

This function has some very compelling features to it, such as the fact that it integrates the IsBidi sort of code I talked about previously and that the signature of the wrapper is identical, but what I like best about it is that if this functionality were added to GetDateFormat in a future version of Windows that then none of the code calling the wrapper would be broken. :-)

Enjoy!

 

This post brought to you by U+200f, RIGHT-TO-LEFT MARKER


no comments

referenced by

2012/01/16 I'm reasonably certain that those who disagree with me here are wrong!

2008/09/24 It used to be right, dammit!

2008/02/20 Officially unofficial? Or Unofficially official?

2007/11/02 Predictably (in retrospect), aka Where Wild^H^H^Hindows-Only Things Are, aka SHORT [on ]TIME for a LONG TIME

2006/12/11 IsComplexEnoughForYou?

2006/12/09 On being consistently consistent, while still managing to be dead wrong

2006/10/15 Not everything you might want out of a GetDateFormatEx, but think of it as a fixer-upper

2006/10/06 What do those marks do again?

go to newer or older post, or back to index or month or day