How can I convert FILETIME to seconds? I need to compare two FILETIME objects..
I found this,
but seems like it doesn't do the trick...
ULARGE_INTEGER ull;
ull.LowPart = lastWriteTimeLow1;
ull.HighPart = lastWriteTimeHigh1;
time_t lastModified = ull.QuadPart / 10000000ULL - 11644473600ULL;
ULARGE_INTEGER xxx;
xxx.LowPart = currentTimeLow1;
xxx.HighPart = currentTimeHigh1;
time_t current = xxx.QuadPart / 10000000ULL - 11644473600ULL;
unsigned long SecondsInterval = current - lastModified;
if (SecondsInterval > RequiredSecondsFromNow)
return true;
return false;
I compared to 2 FILETIME and expected diff of 10 seconds and it gave me ~7000...
Is that a good way to extract number of seconds?
The code you give seems correct, it converts a FILETIME to a UNIX timestamp (obviously losing precision, as FILETIME has a theoretical resolution of 100 nanoseconds). Are you sure that the FILETIMEs you compare indeed have only 10 seconds of difference?
I actually use a very similar code in some software:
double time_d()
{
FILETIME ft;
GetSystemTimeAsFileTime(&ft);
__int64* val = (__int64*) &ft;
return static_cast<double>(*val) / 10000000.0 - 11644473600.0; // epoch is Jan. 1, 1601: 134774 days to Jan. 1, 1970
}
This returns a UNIX-like timestamp (in seconds since 1970) with sub-second resolution.
For the sake of comparisom
double toSeconds(const FILETIME& t)
{
return LARGE_INTEGER{t.dwLowDateTime, (long)t.dwHighDateTime}.QuadPart * 1e-7;
}
is the simplest.
You can use this macro to get time in UNIX epochs:
#define windows_time_to_unix_epoch(x) ((x) - 116444736000000000LL) / 10000000LL
Related
I have got a value of timestamp represented by number of ticks. Obtaining from it date/time under c# is easy by creating a new System.DateTime object and passing the timestamp value into the constructor, or so I am told (it was created in c#). The thing is I can only use C/C++.
Even converting ticks into seconds is somewhat confusing. According to cplusplus.com simple multiplication by the macro CLOCKS_PER_SEC - Clock ticks per second, should suffice. This results in multiplication by 1000. According to Microsoft website, however, the conversion factor to seconds should be 1e7. Sample value to be converted is 634400640022968750, suggesting the second version is closer to reality.
I will not spend time describing my failed attempts, because they got me nowhere.
Any help will be deeply appreciated.
Assuming you are on windows, the problem is that c# DateTime starts at 1 january of 0001 and c++ FILETIME starts at 1 january of 1601 so to get a SYSTEMTIME with the C# value, you need something like this...
ULARGE_INTEGER uliTime;
uliTime.QuadPart = 634400640022968750; // Your sample value
SYSTEMTIME stSytemTime;
memset(&stSytemTime,0,sizeof(SYSTEMTIME));
FILETIME stFileTime;
memset(&stFileTime,0,sizeof(FILETIME));
// Fill FILETIME with your value
stFileTime.dwLowDateTime = uliTime.LowPart;
stFileTime.dwHighDateTime = uliTime.HighPart;
// Convert FILETIME so SYSTEMTIME
FileTimeToSystemTime(&stFileTime, &stSytemTime);
stSytemTime.wYear -= 1600; // Remove the "start" diference
Convert SYSTEMTIME to time_t
void ConvertSystemTimeToTimeT(const SYSTEMTIME &stSystemTime, time_t &stTimeT)
{
// time_t min value is 1 January 1970
LARGE_INTEGER liJanuary1970 = {0};
liJanuary1970.QuadPart = 116444736000000000;
FILETIME stFileTime = {0};
SystemTimeToFileTime(&stSystemTime, &stFileTime);
ULARGE_INTEGER ullConverter;
ullConverter.LowPart = stFileTime.dwLowDateTime;
ullConverter.HighPart = stFileTime.dwHighDateTime;
// time_t resolution is 1 second, FILETIME is 100 nanoseconds, so convert to seconds and remove the 1970 value
stTimeT = (time_t)(ullConverter.QuadPart - liJanuary1970.QuadPart) / 10000000;
}
if you want to time your code, I would advise to use the QueryPerformance library (QueryPerformanceFrequency and QueryPerformanceCounterfunctions especially) , if it is supported by your hardware.
If you just want an timestamp in seconds from an epoch, use the "time.h" library : How to get current time and date in C++?
In windows and in C++. I have following code.
typedef struct _FILETIME {
DWORD dwLowDateTime;
DWORD dwHighDateTime;
} FILETIME, *PFILETIME, *LPFILETIME;
struct DateTime
{
unsigned int dwLowDateTime;
unsigned int dwHighDateTime;
};
FILETIME ftTime;
GetSystemTimeAsFileTime(&ftTime);
DateTime myTime;
myTime.dwHighDateTime = (unsigned int)ftTime.dwHighDateTime;
myTime.dwLowDateTime = (unsigned int)ftTime.dwLowDateTime;
Now I have requirement to assign values like
2012-06-25 12:00:10.123
to "myTime" or ftTime.
How can I achive this?
Another question is how can I get number of seconds elapsed like 64-bit integer for date "2012-06-25 12:00:10.123" ? How do I convert this to __int64 so that I assign to FILETIME?
I have seen in another question post
__int64 t;
FILETIME ft;
ft.dwLowDateTime = (DWORD)t;
ft.dwHighDateTime = (DWORD)(t >> 32);
I am not supposed to use Boost in my project.
Thanks!
Assign the value "2012-06-25 12:00:10.123" to the SystemTime structure and convert it into FileTime using the function SystemTimeToFileTime.
SYSTEMTIME st,st1;
st.wDay = 25;
st.wMonth = 06;
st.wYear = 2012;
st.wHour = 12;
st.wMinute = 10;
st.wSecond = 10;
st.wMilliseconds = 10;
FILETIME ft;
SystemTimeToFileTime(&st,&ft);
FileTimeToSystemTime(&ft,&st1);
There are multiple ways and functions that can get you there.
You can use DosDateTimeToFileTime() to convert year/month/day h:m:s into FILETIME. You'll need to take additional care of the odd seconds and second fractions.
You also have C(++)'s mktime() to first get time in seconds since 1970. Then you'd need to convert it to seconds since January 1st 1601 by adding 11644473600 to it, scale it to 100-nanoseconds and add the seconds fraction.
But SystemTimeToFileTime() is a better choice because it handles milliseconds as well.
It's not clear what you mean by how can I get number of seconds elapsed like 64-bit integer for date "2012-06-25 12:00:10.123"?
Seconds elapsed since then until now? If so, you get the current time in seconds and convert the given date/time to seconds (described above) and subtract one from the other.
Seconds elapsed since an earlier time until then? Do the same, get seconds for both date/time pairs and subtract.
Use SystemTimeToFileTime.
Assign the datetime data to the SYSTEMTIME structure.
typedef struct _SYSTEMTIME {
WORD wYear;
WORD wMonth;
WORD wDayOfWeek;
WORD wDay;
WORD wHour;
WORD wMinute;
WORD wSecond;
WORD wMilliseconds;
} SYSTEMTIME, *PSYSTEMTIME;
And use
BOOL WINAPI SystemTimeToFileTime(
__in const SYSTEMTIME *lpSystemTime,
__out LPFILETIME lpFileTime
);
for the conversion.
Update:
For converting from the string to date,time components, you can use DateTime::Parse Method(String) method.
Then assign the values to the SYSTEMTIME structure and then convert that to FileTime.
I've seen some other answers on SO that suggest we can get the time from epoch in milliseconds by subtracting the epoch time from the "other" time, but it doesn't work when I try it:
ptime epoch = time_from_string("1970-01-01 00:00:00.000");
ptime other = time_from_string("2011-08-09 17:27:00.000");
long diff = (other-epoch).total_milliseconds();
At this stage diff is -1349172576 and it should be a positive number since the "other" time is 2011. Does anybody know what might be causing this? What's the proper way to get the milliseconds since epoch?
Additionally, I've tried to construct a ptime object from milliseconds:
ptime result = from_time_t(diff);
Result then becomes: "1927-Apr-01 13:50:24" and it should be "2011-Aug-09 17:27:00.000". What's the catch here?
Update:
OK, so my mistake stems from the fact that I have 2 programs, one is C# (8 byte/64-bit long) and a C++ (4 byte/32-bit long); in any case, that interaction is not depicted here.
However, when I use long long, the value is positive but the resulting date (constructed from_time_t) is still incorrect: "2012-Oct-02 10:09:36".
Presumably you're on a platform on which long is smaller than 64 bits.
Let's assume it's 32 bits – in that case, the maximum value of a long is 2147483648. However, it's been ~1312000000000 milliseconds since epoch, so long is clearly insufficient to hold this value and consequently you're seeing overflow.
I'd do something like this instead:
ptime epoch = time_from_string("1970-01-01 00:00:00.000");
ptime other = time_from_string("2011-08-09 17:27:00.000");
time_duration const diff = other - epoch;
long long ms = diff.total_seconds();
ms *= 1000LL;
ms += diff.fractional_seconds() / 1000000L; // 1000L if you didn't build datetime
// with nanosecond resolution
Creating a ptime from the specified number of milliseconds has the same problem – ptime works in terms of long and you have a long long – so you'll essentially need to do the reverse:
// given long long ms
time_duration t = seconds(static_cast<long>(ms / 1000LL));
if (ms % 1000LL)
t += milliseconds(static_cast<long>(ms % 1000LL));
A shortened variation on ildjarn's great solution:
ptime epoch = time_from_string("1970-01-01 00:00:00.000");
ptime other = time_from_string("2011-08-09 17:27:00.001");
time_duration const diff = other - epoch;
long long ms = diff.total_milliseconds();
This would be independent of whether it was built with nanosecond resolution.
you could try:
ptime other = time_from_string("2011-08-09 17:27:00.000");
time_t posix_time = (other - ptime(min_date_time)).total_seconds();
I have a trace file that each transaction time represented in Windows filetime format. These time numbers are something like this:
128166372003061629
128166372016382155
128166372026382245
Would you please let me know if there are any C/C++ library in Unix/Linux to extract actual time (specially second) from these numbers ? May I write my own extraction function ?
it's quite simple: the windows epoch starts 1601-01-01T00:00:00Z. It's 11644473600 seconds before the UNIX/Linux epoch (1970-01-01T00:00:00Z). The Windows ticks are in 100 nanoseconds. Thus, a function to get seconds from the UNIX epoch will be as follows:
#define WINDOWS_TICK 10000000
#define SEC_TO_UNIX_EPOCH 11644473600LL
unsigned WindowsTickToUnixSeconds(long long windowsTicks)
{
return (unsigned)(windowsTicks / WINDOWS_TICK - SEC_TO_UNIX_EPOCH);
}
FILETIME type is is the number 100 ns increments since January 1 1601.
To convert this into a unix time_t you can use the following.
#define TICKS_PER_SECOND 10000000
#define EPOCH_DIFFERENCE 11644473600LL
time_t convertWindowsTimeToUnixTime(long long int input){
long long int temp;
temp = input / TICKS_PER_SECOND; //convert from 100ns intervals to seconds;
temp = temp - EPOCH_DIFFERENCE; //subtract number of seconds between epochs
return (time_t) temp;
}
you may then use the ctime functions to manipulate it.
(I discovered I can't enter readable code in a comment, so...)
Note that Windows can represent times outside the range of POSIX epoch times, and thus a conversion routine should return an "out-of-range" indication as appropriate. The simplest method is:
... (as above)
long long secs;
time_t t;
secs = (windowsTicks / WINDOWS_TICK - SEC_TO_UNIX_EPOCH);
t = (time_t) secs;
if (secs != (long long) t) // checks for truncation/overflow/underflow
return (time_t) -1; // value not representable as a POSIX time
return t;
New answer for old question.
Using C++11's <chrono> plus this free, open-source library:
https://github.com/HowardHinnant/date
One can very easily convert these timestamps to std::chrono::system_clock::time_point, and also convert these timestamps to human-readable format in the Gregorian calendar:
#include "date.h"
#include <iostream>
std::chrono::system_clock::time_point
from_windows_filetime(long long t)
{
using namespace std::chrono;
using namespace date;
using wfs = duration<long long, std::ratio<1, 10'000'000>>;
return system_clock::time_point{floor<system_clock::duration>(wfs{t} -
(sys_days{1970_y/jan/1} - sys_days{1601_y/jan/1}))};
}
int
main()
{
using namespace date;
std::cout << from_windows_filetime(128166372003061629) << '\n';
std::cout << from_windows_filetime(128166372016382155) << '\n';
std::cout << from_windows_filetime(128166372026382245) << '\n';
}
For me this outputs:
2007-02-22 17:00:00.306162
2007-02-22 17:00:01.638215
2007-02-22 17:00:02.638224
On Windows, you can actually skip the floor, and get that last decimal digit of precision:
return system_clock::time_point{wfs{t} -
(sys_days{1970_y/jan/1} - sys_days{1601_y/jan/1})};
2007-02-22 17:00:00.3061629
2007-02-22 17:00:01.6382155
2007-02-22 17:00:02.6382245
With optimizations on, the sub-expression (sys_days{1970_y/jan/1} - sys_days{1601_y/jan/1}) will translate at compile time to days{134774} which will further compile-time-convert to whatever units the full-expression requires (seconds, 100-nanoseconds, whatever). Bottom line: This is both very readable and very efficient.
The solution that divides and adds will not work correctly with daylight savings.
Here is a snippet that works, but it is for windows.
time_t FileTime_to_POSIX(FILETIME ft)
{
FILETIME localFileTime;
FileTimeToLocalFileTime(&ft,&localFileTime);
SYSTEMTIME sysTime;
FileTimeToSystemTime(&localFileTime,&sysTime);
struct tm tmtime = {0};
tmtime.tm_year = sysTime.wYear - 1900;
tmtime.tm_mon = sysTime.wMonth - 1;
tmtime.tm_mday = sysTime.wDay;
tmtime.tm_hour = sysTime.wHour;
tmtime.tm_min = sysTime.wMinute;
tmtime.tm_sec = sysTime.wSecond;
tmtime.tm_wday = 0;
tmtime.tm_yday = 0;
tmtime.tm_isdst = -1;
time_t ret = mktime(&tmtime);
return ret;
}
Assuming you are asking about the FILETIME Structure, then FileTimeToSystemTime does what you want, you can get the seconds from the SYSTEMTIME structure it produces.
Here's essentially the same solution except this one encodes negative numbers from Ldap properly and lops off the last 7 digits before conversion.
public static int LdapValueAsUnixTimestamp(SearchResult searchResult, string fieldName)
{
var strValue = LdapValue(searchResult, fieldName);
if (strValue == "0") return 0;
if (strValue == "9223372036854775807") return -1;
return (int)(long.Parse(strValue.Substring(0, strValue.Length - 7)) - 11644473600);
}
If somebody need convert it in MySQL
SELECT timestamp,
FROM_UNIXTIME(ROUND((((timestamp) / CAST(10000000 AS UNSIGNED INTEGER)))
- CAST(11644473600 AS UNSIGNED INTEGER),0))
AS Converted FROM events LIMIT 100
Also here's a pure C#ian way to do it.
(Int32)(DateTime.FromFileTimeUtc(129477880901875000).Subtract(new DateTime(1970, 1, 1))).TotalSeconds;
Here's the result of both methods in my immediate window:
(Int32)(DateTime.FromFileTimeUtc(long.Parse(strValue)).Subtract(new DateTime(1970, 1, 1))).TotalSeconds;
1303314490
(int)(long.Parse(strValue.Substring(0, strValue.Length - 7)) - 11644473600)
1303314490
DateTime.FromFileTimeUtc(long.Parse(strValue))
{2011-04-20 3:48:10 PM}
Date: {2011-04-20 12:00:00 AM}
Day: 20
DayOfWeek: Wednesday
DayOfYear: 110
Hour: 15
InternalKind: 4611686018427387904
InternalTicks: 634389112901875000
Kind: Utc
Millisecond: 187
Minute: 48
Month: 4
Second: 10
Ticks: 634389112901875000
TimeOfDay: {System.TimeSpan}
Year: 2011
dateData: 5246075131329262904
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
measuring time with resolution of microseconds in c++?
Hi,
Is there a simple way i can get the system time on a Windows machine, down to microsecond accuracy?
Look at GetSystemTimeAsFileTime
It gives you accuracy in 0.1 microseconds or 100 nanoseconds.
Note that it's Epoch different from POSIX Epoch.
So to get POSIX time in microseconds you need:
FILETIME ft;
GetSystemTimeAsFileTime(&ft);
unsigned long long tt = ft.dwHighDateTime;
tt <<=32;
tt |= ft.dwLowDateTime;
tt /=10;
tt -= 11644473600000000ULL;
So in such case time(0) == tt / 1000000
Like this
unsigned __int64 freq;
QueryPerformanceFrequency((LARGE_INTEGER*)&freq);
double timerFrequency = (1.0/freq);
unsigned __int64 startTime;
QueryPerformanceCounter((LARGE_INTEGER *)&startTime);
//do something...
unsigned __int64 endTime;
QueryPerformanceCounter((LARGE_INTEGER *)&endTime);
double timeDifferenceInMilliseconds = ((endTime-startTime) * timerFrequency);
What we really need is a high-resolution GetTickCount(). As far as I know, this doesn't really exist.
If you're willing to use a hackish way to solve this (that would probably only work on some versions of Windows like XP), look here at ReactOS. Then try this code:
long long GetTickCount64()
{
return (long long)
((((unsigned long long)*(unsigned long int*)0x7FFE0000
* (unsigned long long)*(unsigned long int*)0x7FFE0004)
* (unsigned long long)10000) >> 0x18);
}
Tweaking it might give you what you need in some versions of Windows.