8

I am making a program, in C++ using Visual Studio 2005, that needs to create a watermark with the time on a set of images.

These images are taken from a video that were processed at certain time intervals. What I am trying to do is to modify the time on each image through SYSTEMTIME. I looked at the MSDN and it says not to modify the values within SYSTEMTIME itself, but to convert it into a FILETIME and then an ULARGE_INTEGER. My question is how is the ULARGE_INTEGER split up? Is the HighPart the date and the Low Part the time and if that's the case how to I take into account rollover? Like if a image shows up at 11:58pm on 2/25/2011 and goes through until 12:11 2/26/2011? Would just adding the specified value automatically be taken into account and shown when I convert it back into a SYSTEMTIME variable?

Thanks in advance for your help.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
Seb
  • 3,414
  • 10
  • 73
  • 106

1 Answers1

8

They suggest converting SYSTEMTIME to FILETIME, which is a number of ticks since an epoch. You can then add the required number of 'ticks' (i.e. 100ns intervals) to indicate your time, and convert back to SYSTEMTIME.

The ULARGE_INTEGER struct is a union with a QuadPart member, which is a 64bit number, that can be directly added to (on recent hardware).

SYSTEMTIME add( SYSTEMTIME s, double seconds ) {

    FILETIME f;
    SystemTimeToFileTime( &s, &f );

    ULARGE_INTEGER u  ; 
    memcpy( &u  , &f , sizeof( u ) );

    const double c_dSecondsPer100nsInterval = 100.*1.e-9;
    const double c_dNumberOf100nsIntervals = 
                    seconds / c_dSecondsPer100nsInterval;

    // note: you may want to round the number of intervals.
    u.QuadPart += c_dNumberOf100nsIntervals;

    memcpy( &f, &u, sizeof( f ) );

    FileTimeToSystemTime( &f, &s );
    return s;
 }
xtofl
  • 40,723
  • 12
  • 105
  • 192
  • So if I wanted to do Minutes instead of seconds I would have to change the formula from 100*1.e-9 to 100*60.e-9? – Seb Feb 25 '11 at 15:03
  • You could do that. You could also call the function like `SYSTEMTIME s2 = add( s1, 60*minutes )`, which keeps the function more reusable. – xtofl Feb 25 '11 at 15:06
  • @xtofl I get a compiler warning on u.QuadPart += seconds / c_dSecondsPer100nsInterval, possible loss of data – Peter Jan 24 '12 at 12:56
  • @Peter: that's probably due to the truncation; same warning would occur with `__int64 i = (double) 1.;`. The compiler rightfully warns you that you will lose precision; actually I should have either rounded or truncated the number of 100 ns intervals _explicitly_. – xtofl Jan 25 '12 at 10:26
  • Instead of using memcpy is it possible to do this `u.LowPart=f.dwLowDateTime; u.HighPart=f.dwHighDateTime;`? – Roland Feb 16 '13 at 06:38
  • @Mr.Roland: actually, it seems better to me. The `memcpy` way assumes that both structures have the same size, your proposal doesn't, which is better. I don't remember why I used `memcpy`. – xtofl Feb 17 '13 at 08:00