65.9K
CodeProject is changing. Read more.
Home

Creating a Time Picker with no Seconds Field

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.83/5 (11 votes)

Nov 30, 1999

1 min read

viewsIcon

76244

Recently I found myself needing a time picker that would show just the hours and minutes fields, without the seconds. Since the common control has no built-in style to do this, I did the logical thing and wrote a snippet of code to set a picker control to have such a format.

I also needed the code to work on any language and time format, so I delved into the SDK docs and read up on GetLocaleInfo(), which is the key to making the code work with all time formats.

The steps involved in this procedure are:

  1. Get the time separator (usually ':') and the current time format picture.
  2. Search for "ss" following the separator. This handles formats like "hh:mm:ss". If that substring is found, delete it from the format picture and jump to step 4.
  3. Search for "s" following the separator. This handles formats like "hh:mm:s". If that substring is found, delete it from the format picture.
  4. Set the time picker's format to the modified format we just created.

Note that this method doesn't care about the AM/PM indicator, if there is one. It will remain where it is in the format picture.

This code was written in MSVC 6 on Win 98. I use CString::Delete() (an MFC 6 function) to remove characters, so it will require a bit of tweaking to run on VC 5. It should work fine in Unicode, since I do everything with CStrings, although I haven't tested it.

TCHAR          szBuf[64];               // workspace
CString        sTimeFormat;             // the time format being worked on
CString        sSearch;                 // the string to search for
int            nIndex;                  // index of the string, if found
CDateTimeCtrl* pTimeCtl;                // pointer to a time picker

    // First get the time format picture.

    VERIFY ( ::GetLocaleInfo ( LOCALE_USER_DEFAULT, LOCALE_STIMEFORMAT,
                               szBuf, 64 ));

    sTimeFormat = szBuf;

    // Next get the separator character.

    VERIFY ( ::GetLocaleInfo ( LOCALE_USER_DEFAULT, LOCALE_STIME, 
                               szBuf, 64 ));

    // Search for ":ss".

    sSearch = szBuf;
    sSearch += _T("ss");

    nIndex = sTimeFormat.Find ( sSearch );

    if ( -1 != nIndex )
        {
        // Found it!  Remove it from the format picture.
        sTimeFormat.Delete ( nIndex, sSearch.GetLength() );
        }
    else
        {
        // No ":ss", so try ":s".

        sSearch = szBuf;
        sSearch += 's';

        nIndex = sTimeFormat.Find ( sSearch );
    
        if ( -1 != nIndex )
            {
            // Found it!  Remove it from the format picture.
            sTimeFormat.Delete ( nIndex, sSearch.GetLength() );
            }
        }

    // Now set the picker control's format.
    // NOTE: You'll need to set pTimeCtl somehow, such as with GetDlgItem().

    ASSERT_VALID(pTimeCtl);
    VERIFY ( pTimeCtl->SetFormat ( sTimeFormat ));