-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTimeConverter.h
109 lines (85 loc) · 2.7 KB
/
TimeConverter.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
//*********************************************************
//
// Copyright (c) Microsoft. All rights reserved.
// This code is licensed under the MIT License (MIT).
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************
#pragma once
#include <cassert>
#include <chrono>
#include <cstdint>
#include <wrl.h>
typedef std::chrono::duration<int64_t, std::ratio<1, 10'000'000>> HundredsOfNanoseconds;
HundredsOfNanoseconds UniversalToUnixTime(const FILETIME fileTime);
long long checkAndConvertUnsigned(UINT64 val);
class TimeConverter
{
public:
TimeConverter()
{
QueryPerformanceFrequency(&m_qpf);
m_qpc2ft = CalculateRelativeToAbsoluteTicksOffset();
}
~TimeConverter()
{
}
HundredsOfNanoseconds TimeConverter::RelativeTicksToAbsoluteTicks(const HundredsOfNanoseconds ticks) const
{
return m_qpc2ft + ticks;
}
HundredsOfNanoseconds TimeConverter::UniversalToUnixTime(const HundredsOfNanoseconds fileTime)
{
const std::chrono::seconds c_unix_epoch(11'644'473'600);
return fileTime - c_unix_epoch;
}
private:
HundredsOfNanoseconds TimeConverter::UnsignedQpcToRelativeTicks(const uint64_t qpc) const
{
static const std::uint64_t c_ticksPerSecond = 10'000'000;
const std::uint64_t q = qpc / m_qpf.QuadPart;
const std::uint64_t r = qpc % m_qpf.QuadPart;
return HundredsOfNanoseconds(
q * c_ticksPerSecond + (r * c_ticksPerSecond) / m_qpf.QuadPart);
}
HundredsOfNanoseconds TimeConverter::QpcToRelativeTicks(const int64_t qpc) const
{
if (qpc < 0)
{
return -UnsignedQpcToRelativeTicks(
static_cast<uint64_t>(-qpc));
}
else
{
return UnsignedQpcToRelativeTicks(
static_cast<uint64_t>(qpc));
}
}
HundredsOfNanoseconds QpcToRelativeTicks(const LARGE_INTEGER qpc) const
{
return QpcToRelativeTicks(qpc.QuadPart);
}
HundredsOfNanoseconds TimeConverter::FileTimeToAbsoluteTicks(const FILETIME ft) const
{
ULARGE_INTEGER ft_uli;
ft_uli.HighPart = ft.dwHighDateTime;
ft_uli.LowPart = ft.dwLowDateTime;
return HundredsOfNanoseconds(ft_uli.QuadPart);
}
HundredsOfNanoseconds CalculateRelativeToAbsoluteTicksOffset() const
{
LARGE_INTEGER qpc_now{};
FILETIME ft_now;
assert(QueryPerformanceCounter(&qpc_now));
GetSystemTimePreciseAsFileTime(&ft_now);
const HundredsOfNanoseconds qpc_now_in_ticks = QpcToRelativeTicks(qpc_now);
const HundredsOfNanoseconds ft_now_in_ticks = FileTimeToAbsoluteTicks(ft_now);
assert(ft_now_in_ticks > qpc_now_in_ticks);
return ft_now_in_ticks - qpc_now_in_ticks;
}
LARGE_INTEGER m_qpf;
HundredsOfNanoseconds m_qpc2ft;
};