summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/util/timeconv.cpp
blob: 4511aa20d41224f8155beb6ac543e38bb585c5b6 (plain) (blame)
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
// license:BSD-3-Clause
// copyright-holders:Vas Crabb, Nathan Woods
/*********************************************************************

	timeconv.cpp

	Time conversion utility code

***************************************************************************/

#include "timeconv.h"

#include <ctime>


namespace util {
namespace {
/***************************************************************************
	PROTOTYPES
***************************************************************************/

util::ntfs_duration calculate_ntfs_offset();


/***************************************************************************
	GLOBAL VARIABLES
***************************************************************************/

util::ntfs_duration f_ntfs_offset(calculate_ntfs_offset());


/***************************************************************************
	IMPLEMENTATION
***************************************************************************/

util::ntfs_duration calculate_ntfs_offset()
{
	constexpr auto days_in_year(365);
	constexpr auto days_in_four_years((days_in_year * 4) + 1);
	constexpr auto days_in_century((days_in_four_years * 25) - 1);
	constexpr auto days_in_four_centuries((days_in_century * 4) + 1);

	constexpr ntfs_duration day(std::chrono::hours(24));
	constexpr ntfs_duration year(day * days_in_year);
	constexpr ntfs_duration four_years(day * days_in_four_years);
	constexpr ntfs_duration century(day * days_in_century);
	constexpr ntfs_duration four_centuries(day * days_in_four_centuries);

	std::time_t const zero(0);
	std::tm const epoch(*std::gmtime(&zero));

	ntfs_duration result(day * epoch.tm_yday);
	result += std::chrono::hours(epoch.tm_hour);
	result += std::chrono::minutes(epoch.tm_min);
	result += std::chrono::seconds(epoch.tm_sec);

	int years(1900 - 1601 + epoch.tm_year);
	result += four_centuries * (years / 400);
	years %= 400;
	result += century * (years / 100);
	years %= 100;
	result += four_years * (years / 4);
	years %= 4;
	result += year * years;

	return result;
}

} // anonymous namespace



// -------------------------------------------------
// system_clock_time_point_from_ntfs_duration
// -------------------------------------------------

std::chrono::system_clock::time_point system_clock_time_point_from_ntfs_duration(ntfs_duration d)
{
	return std::chrono::system_clock::from_time_t(0) + std::chrono::duration_cast<std::chrono::system_clock::duration>(d - f_ntfs_offset);
}

} // namespace util