performing Arithmetic on SYSTEMTIME
Solution 1
If you're using C# (or VB.NET, or ASP.NET) you can use
DateTime dt = DateTime.Now.AddHours(1);
You can use negative numbers to subtract:
DateTime dt = DateTime.Now.AddHours(-1);
EDITED: I extract an asnwer from this post
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;
u.QuadPart += seconds / c_dSecondsPer100nsInterval;
memcpy( &f, &u, sizeof( f ) );
FileTimeToSystemTime( &f, &s );
return s;
}
If you want to add an hour use SYSTEMTIME s2 = add(s1, 60*60)
Solution 2
To add signed seconds (forward or backward in time) in C++:
const double clfSecondsPer100ns = 100. * 1.E-9;
void iAddSecondsToSystemTime(SYSTEMTIME* timeIn, SYSTEMTIME* timeOut, double tfSeconds)
{
union {
ULARGE_INTEGER li;
FILETIME ft;
};
// Convert timeIn to filetime
SystemTimeToFileTime(timeIn, &ft);
// Add in the seconds
li.QuadPart += tfSeconds / clfSecondsPer100ns;
// Convert back to systemtime
FileTimeToSystemTime(&ft, timeOut);
}
Solution 3
#include <stdio.h>
#include <windows.h>
#define NSEC 60*60
main()
{
SYSTEMTIME st;
FILETIME ft;
// Get local time from system
GetLocalTime(&st);
printf("%02d/%02d/%04d %02d:%02d:%02d\n",
st.wDay,st.wMonth,st.wYear,st.wHour,st.wMinute,st.wSecond);
// Convert to filetime
SystemTimeToFileTime(&st,&ft);
// Add NSEC seconds
((ULARGE_INTEGER *)&ft)->QuadPart +=(NSEC*10000000LLU);
// Convert back to systemtime
FileTimeToSystemTime(&ft,&st);
printf("%02d/%02d/%04d %02d:%02d:%02d\n",
st.wDay,st.wMonth,st.wYear,st.wHour,st.wMinute,st.wSecond);
}
Comments
-
Peter about 2 years
I have a time value represented in SYSTEMTIME, i want to add/subtract 1 hour from it and get the newly obtained SYSTEMTIME. I want the conversion should take care of the date change on addition/subtraction or month change or e1 year change .
Can someone help me with this if there is some windows api which does arithmetic on SYSTEMTIME
-
Peter over 12 yearsi am using windows SYSTEMTIME structure
-
Marco over 12 years@Peter: ok, but which programming language are you using?
-
Sandburg about 6 yearsWhat is this trick with the
union
? You make no calculus onft
, but it is you result back... I don't understand. -
Rick C. Hodgin about 6 yearsThe byte/bit patterns of the 64-bit FILETIME is the same as those of the ULARGE_INTEGER. By populating ft, you are also populating the portions of li, which allows you to use li at that point. The location in memory just examines the data there in the two different ways. By using ft you see it as a FILETIME. By using li you see it as a ULARGE_INTEGER.
-
CookiePLMonster about 6 yearsThis (interpreting FILETIME as ULARGE_INTEGER) is exactly what is discouraged by MSDN, though.
-
Rick C. Hodgin about 6 yearsThey discourage it because they don't intend to stay on x86 forever. They want you to use functions that can be ported to other architectures without any changes. That's all find and dandy if you have that need (other architecture portability). But if you're strictly x86 (or more generically, little endian), this method works properly.
-
MSalters almost 6 yearsThe MSDN warning is related to unaligned access of a
FILETIME
. However, C++ unions are aligned to the strictest alignment necessary. Hence, this solution prevents the problem MSDN warns about. -
Nikunj Chaklasiya almost 5 yearsI'm using VS2008 and getting "bad suffix error on the line from where you're adding seconds.
-
Piotr about 3 yearsdocs.microsoft.com/en-us/windows/win32/api/minwinbase/… Do not cast a pointer to a FILETIME structure to either a ULARGE_INTEGER* or __int64* value because it can cause alignment faults on 64-bit Windows.