我有一个用SYSTEMTIME表示的时间值,我想从中加/减1小时并得到新获取的SYSTEMTIME。我希望转换应该在加法/减法或月份变化或年份变化时考虑日期改变。
如果有一些Windows API可以对SYSTEMTIME进行算术运算,请问是否有人可以帮助我?
我有一个用SYSTEMTIME表示的时间值,我想从中加/减1小时并得到新获取的SYSTEMTIME。我希望转换应该在加法/减法或月份变化或年份变化时考虑日期改变。
如果有一些Windows API可以对SYSTEMTIME进行算术运算,请问是否有人可以帮助我?
DateTime dt = DateTime.Now.AddHours(1);
您可以使用负数来进行减法:
DateTime dt = DateTime.Now.AddHours(-1);
编辑: 我从这篇文章中提取了一个答案。
他们建议将SYSTEMTIME转换为FILETIME,后者是自纪元以来的一定数量的滴答声。然后,您可以添加所需数量的“ticks”(即100ns间隔)来表示您的时间,并转换回SYSTEMTIME。
ULARGE_INTEGER结构是具有QuadPart成员的联合体,它是一个64位数字,最近的硬件可以直接对其进行加法运算。
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;
}
如果你想增加一个小时,使用 SYSTEMTIME s2 = add(s1, 60*60)
在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);
}
union
的技巧是什么?你没有对 ft
进行任何计算,但结果却返回了它...我不明白。 - SandburgFILETIME
的非对齐访问有关。然而,C++ 联合体对于最严格的对齐要求进行了对齐。因此,这种解决方案可以避免 MSDN 所警告的问题。 - MSalters#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);
}