Extended Time Format Functions (with Milliseconds) | CodeGuru

Extended Time Format Functions (with Milliseconds)

Environment: Developed with VC6 SP2; Tested under Windows 2000 Extended format a time string with milliseconds. The output string for a time could be 23:59:59.999. Prototypes size_t strfstime(char *strDest, size_t maxsize, const char *format, const SYSTEMTIME *stimeptr); size_t wcsfstime(wchar_t *strDest, size_t maxsize, const wchar_t *format, const SYSTEMTIME *timeptr); For additional compatibility information, see VC++ documentation […]

Written By
CodeGuru Staff
CodeGuru Staff
Oct 1, 2002
1 minute read
CodeGuru content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More

Environment: Developed with VC6 SP2; Tested under Windows 2000

Extended format a time string with milliseconds. The output string for a time could be 23:59:59.999.

Prototypes

size_t strfstime(char *strDest,
                 size_t maxsize,
                 const char *format,
                 const SYSTEMTIME *stimeptr);
size_t wcsfstime(wchar_t *strDest,
                 size_t maxsize,
                 const wchar_t *format,
                 const SYSTEMTIME *timeptr);
For additional compatibility information, see VC++ documentation for strftime and wcsftime..
Return Value
strfstime returns the number of characters placed in strDest if the total number of resulting
characters, including the terminating null, is not more than maxsize. wcsfstime returns the
corresponding number of wide characters. Otherwise, the functions return 0, and the contents
of strDest is indeterminate.
Parameters


strDest
Output string


maxsize
Maximum length of string


format
Format-control string


stimeptr
SYSTEMTIME data structure


Remarks
The strfstime and wcsfstime functions format the SYSTEMTIME time value in stimeptr according
to the supplied format argument and store the result in the buffer strDest. At most, maxsize
characters are placed in the string. For a description of the fields in the timeptr structure,
see strftime and wcsftime. wcsfstime is the wide-character equivalent of strfstime; its
string-pointer argument points to a wide-character string. These functions behave
identically otherwise.
Generic-Text Routine Mappings
TCHAR.H Routine 
_UNICODE & _MBCS Not Defined
 _MBCS Defined
 _UNICODE Defined
_tcsfstime strfstime strfstime wcsfstime


The format argument are the same as documented for VC++ functions strftime and wcsftime.
Also one user defined additional format argument is now allowed. This argument is (default):
%s        Milliseconds as decimal number (000 - 999)


extern “C” {
 const char* strfscode( const char* code );
 size_t strfstime(char *strDest,
                  size_t maxsize,
                  const char *format,
                  const SYSTEMTIME *stimeptr );
 const char* wcsfscode( const wchar_t* code );
 size_t wcsfstime(wchar_t *strDest,
                  size_t maxsize,
                  const wchar_t *format,
                  const SYSTEMTIME *stimeptr );
};
// ——————————————
#ifdef _UNICODE
 #define _tcsfstime wcsftime
#else // _MBCS
 #define _tcsfstime strfstime
#endif
static char szFCode[3] = _T(“%s”);
const char* strfscode( const char* code )
{
 if( code ){
  strncpy( szFCode, code, sizeof(szFCode)-1);
  szFCode[2] = char(0);
 }
 return szFCode;
}
size_t strfstime(char *strDest, size_t maxsize,
                 const char *format, const SYSTEMTIME *stimeptr )
{
 struct tm tmTime;
 memset(&tmTime, 0, sizeof(tmTime));
 tmTime.tm_sec = stimeptr->wSecond; // seconds after the minute – [0,59]
 tmTime.tm_min = stimeptr->wMinute; // minutes after the hour – [0,59]
 tmTime.tm_hour = stimeptr->wHour;  // hours since midnight – [0,23]
 ASSERT(stimeptr->wDay >= 1 && stimeptr->wDay <= 31);

 tmTime.tm_mday = stimeptr->wDay;  day of the month – [1,31]
 ASSERT(stimeptr->wMonth >= 1 && stimeptr->wMonth <= 12);

 tmTime.tm_mon = stimeptr->wMonth-1; // months since January – [0,11]
 ASSERT(stimeptr->wYear >= 1900);
 tmTime.tm_year = stimeptr->wYear-1900; // years since 1900 
 tmTime.tm_wday = stimeptr->wDayOfWeek; // days since Sunday – [0,6] 
 // tmTime.tm_yday = NOT USED HERE; // days since January 1 – [0,365] 
 // tmTime.tm_isdst = NOT USED HERE; // daylight savings time flag 
 const char* pStrFound = strstr(format, szFCode );
 if( pStrFound ){
  if( maxsize < (strlen(format)+1+3) )
   return 0;

  char* pNewFormat = new char[maxsize+1];

  long lOffset = pStrFound-format;
  strncpy(pNewFormat, format, lOffset);
  pNewFormat[lOffset] = char(0);

  char szMilliSec[4];
  itoa(stimeptr->wMilliseconds, szMilliSec, 10);
  for(int i=strlen(szMilliSec); i<3; i++ )
   strcat(pNewFormat+lOffset, "0");

  strcat(pNewFormat+lOffset, szMilliSec);
  strcat(pNewFormat+lOffset, format+lOffset+strlen(szFCode));

  size_t size = strftime( strDest, maxsize, pNewFormat, &tmTime );

  delete pNewFormat;

  return size;
 }

 return strftime( strDest, maxsize, format, &tmTime );
}

// ——————————————
static wchar_t wszFCode_t[3] = L”%s”;
const char* wcsfscode( const wchar_t* code )
{
 if( code ){
  wcsncpy( wszFCode_t, code, sizeof(szFCode)-1);
  wszFCode_t[2] = wchar_t(0);
 }
 return szFCode;
}
size_t wcsfstime(wchar_t *strDest, size_t maxsize,
                 const wchar_t *format, const SYSTEMTIME *stimeptr )
{
 struct tm tmTime;
 memset(&tmTime, 0, sizeof(tmTime));
 tmTime.tm_sec = stimeptr->wSecond;  seconds after the minute – [0,59] 
 tmTime.tm_min = stimeptr->wMinute; // minutes after the hour – [0,59] 
 tmTime.tm_hour = stimeptr->wHour; // hours since midnight – [0,23] 
 ASSERT(stimeptr->wDay >= 1 && stimeptr->wDay <= 31);

 tmTime.tm_mday = stimeptr->wDay; // day of the month – [1,31] 
 ASSERT(stimeptr->wMonth >= 1 && stimeptr->wMonth <= 12);

 tmTime.tm_mon = stimeptr->wMonth-1; // months since January – [0,11] 
 ASSERT(stimeptr->wYear >= 1900);
 tmTime.tm_year = stimeptr->wYear-1900; // years since 1900 
 tmTime.tm_wday = stimeptr->wDayOfWeek; // days since Sunday – [0,6] 
 // tmTime.tm_yday = NOT USED HERE; // days since January 1 – [0,365] 
 // tmTime.tm_isdst = NOT USED HERE; // daylight savings time flag 
 const wchar_t* pStrFound = wcsstr(format, wszFCode_t );
 if( pStrFound ){
  if( maxsize < (wcslen(format)+1+3) )
   return 0;

  wchar_t* pNewFormat = new wchar_t[maxsize+1];

  long lOffset = pStrFound-format;
  wcsncpy(pNewFormat, format, lOffset);
  pNewFormat[lOffset] = wchar_t(0);

  wchar_t wszMilliSec[4];
  _itow(stimeptr->wMilliseconds, wszMilliSec, 10);
  for(int i=wcslen(wszMilliSec); i<3; i++ )
  wcscat(pNewFormat+lOffset, L"0");

  wcscat(pNewFormat+lOffset, wszMilliSec);
  wcscat(pNewFormat+lOffset, format+lOffset+wcslen(wszFCode_t));

  size_t size = wcsftime( strDest, maxsize, pNewFormat, &tmTime );

  delete pNewFormat;

  return size;
 }

 return wcsftime( strDest, maxsize, format, &tmTime );
}

Example

// Create system time structure
SYSTEMTIME SystemTime;
GetSystemTime(&SystemTime);
// Create time string with milliseconds
TCHAR strDest[32];
size_t iSize = strfstime(strDest,
                         sizeof(strDest),
                         T(“%H:%M:%S.%s”),
                         &SystemTime );
if( iSize > 0 ){
 // …. do something with the time string
}

Downloads
Download source – 2 Kb
CodeGuru Logo

CodeGuru covers topics related to Microsoft-related software development, mobile development, database management, and web application programming. In addition to tutorials and how-tos that teach programmers how to code in Microsoft-related languages and frameworks like C# and .Net, we also publish articles on software development tools, the latest in developer news, and advice for project managers. Cloud services such as Microsoft Azure and database options including SQL Server and MSSQL are also frequently covered.

Property of TechnologyAdvice. © 2026 TechnologyAdvice. All Rights Reserved

Advertiser Disclosure: Some of the products that appear on this site are from companies from which TechnologyAdvice receives compensation. This compensation may impact how and where products appear on this site including, for example, the order in which they appear. TechnologyAdvice does not include all companies or all types of products available in the marketplace.