Seconds since Epoch to formatted time [duplicate] - c++

How can I convert number of seconds since 1970 to DateTime in c++?
I am getting the time in the below format:
1296575549:573352
The left part of the colon is in seconds and the right part in micro seconds.
Please help.
Thanks,
Syd

Try and use gmtime() (see http://www.cplusplus.com/reference/clibrary/ctime/gmtime/) or localtime() to convert a time_t to a struct tm

Use boost::Date_Time to do this. Code below assumes _interval is number of seconds since 1970. Note this code example doesn't handle the micro-second portion, but I am sure it could be modified to do so.
#include <boost/date_time/gregorian/gregorian_types.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
double interval(1296575549.0f);
boost::posix_time::ptime m_DateTime = ptime(date(1970, 1, 1),
time_duration(0, 0, 0,
time_duration::ticks_per_second() *
(time_duration::fractional_seconds_type)_interval));

Three important things about converting time using C/C++ library.
gmtime() or localtime() from standard library convert from time_t to struct tm, but the resolution for time_t is seconds from epoch. So fractional seconds will not count.
mktime() converts backwards from struct tm to time_t, but it will return -1 if the input date is out of range. (Reference: year 2038 problem)
If you are not using 64bit timestamp, even you run programs on 64bit machines, you still have year 2038 problem. There are 64bit version functions like gmtime64(), localtime64(), mktime64() that may resolve the year out of range issue. (Reference)

New answer for a very old question. Rationale: Better tools.
Starting in C++11, one can easily store this quantity in a std::chrono::system_clock::time_point:
#include <chrono>
#include <iostream>
#include <sstream>
int
main()
{
using namespace std;
using namespace std::chrono;
istringstream in{"1296575549:573352"};
long si, usi;
char sep;
in >> si >> sep >> usi;
system_clock::time_point tp{seconds{si} + microseconds{usi}};
}
Though the epoch of system_clock is unspecified in C++11, every implementation is tracking Unix Time (time since 1970-01-01 00:00:00 UTC, excluding leap seconds). Different implementations will have different precisions for system_clock::time_point, but you don't really have to care about that when converting into system_clock::time_point as shown above. The <chrono> library will just do the right thing.
Starting in C++20 the Unix Time measure of system_clock::time_point will be specified, and you will be able to stream it out in a human readable form:
cout << tp << '\n';
For this example that will output:
2011-02-01 15:52:29.573352
On some platforms there may be a few trailing zeroes on this output, depending on the precision of system_clock::time_point on that platform. This is a UTC date/time. There will also be ways to convert this to a particular time zone if desired (in C++20).
You can experiment with this part of C++20 today by using Howard Hinnant's date/time library. This will require an additional #include "date/date.h" ("date/tz.h" for time zone functionality), and a using namespace date; to enable the system_clock::time_point streaming operator.
If it is known that your count of seconds includes leap seconds (Unix Time stamps don't), C++20 also provides a way to deal with that:
Just change system_clock to utc_clock in the above example and the new output will be:
2011-02-01 15:52:05.573352
which accounts for the 24 leap seconds inserted prior to this date.

As an example of duration available in seconds, let's assume you want to have an idea of the running time of your program:
#include <ctime>
time_t startRawTime;
time( &startRawTime );
//...your program performs computations...
time_t endRawTime;
time( &endRawTime );
time_t elapsedSec = difftime( endRawTime, startRawTime );
// but elapsedSec can be any duration, e.g. 3734, as long as it is in seconds
tm * ptm = gmtime( &elapsedSec );
printf( "elapsed time: %02dh %02dm %02ds\n",
ptm->tm_hour,
ptm->tm_min,
ptm->tm_sec );
You would get something like this for instance:
elapsed time: 01h 02m 14s

Well, the most complex case:
86'400 s/day
31'557'600 s/year (365.25 d)
1296575549/31557600 = 41 years
1296575549-41*31557600 = 2'713'949 s
2713949/86400 ==> 31 d
2713949-31*86400 =35'549
35549/(60*60) = 9h
35549-9*60*60 = 3'149
3'149/(60*60) = 0h
3'149- 0* (60*60) = 3'149
3149/60 = 52 m
3149-52*60 = 29s
--> year = 1970 + 41
--> month = 1 + 0
--> day = 31 (+1?)
--> Time 00:52:29
==> 2011, Jan 31, 00:52:29 GMT
To calculate the month from the day, you need to copy paste an isLeapYear function, because of February.
Hmm, looks like one also needs to account for the leap years until last leap year, which were subtracted in surplus. Hmm, effects of daylight saving time...
Go sleep !

Related

Convert UTC time_t to UTC tm

All my internal times are UTC stored in time_t. I need to convert them to struct tm. If I use localtime the time is correct, except that tm_isdst may be set resulting in the time being off an hour. If I use gmtime it gets the wrong time, off by the time zone difference.
Edit I am looking for a cross platform solution that works in Windows and Linux
Here is a cross platform solution that requires C++11 or better, and a free, open-source, header-only date library. And when your vendor brings you C++20, you can loose the date library as it is incorporated into C++20 <chrono>.
It is actually easier to convert from time_t to a UTC tm by going through <chrono> than it is to use the C API. There do exist various extensions to do this on each platform, but the extensions have different syntaxes. This solution has a uniform syntax across all platforms.
In C++11, though not specified, it is a de-facto standard that both time_t and std::chrono::system_clock track Unix Time, though at different precisions. In C++20 this becomes specified for std::chrono::system_clock. For time_t the de-facto precision is seconds. One can take advantage of this knowledge to create extremely efficient conversions between the C API and the C++ <chrono> API.
Step 1: Convert time_t to a chrono::time_point
This is very easy and efficient:
date::sys_seconds
to_chrono(std::time_t t)
{
using namespace date;
using namespace std::chrono;
return sys_seconds{seconds{t}};
}
date::sys_seconds is simply a type alias for:
std::chrono::time_point<std::chrono::system_clock, std::chrono::seconds>
I.e. a time_point based on system_clock but with seconds precision.
All this function does is change type from time_t to seconds and then to time_point. No actual computation is done. Here is an optimized clang compilation of to_chrono:
.globl __Z9to_chronol ## -- Begin function _Z9to_chronol
.p2align 4, 0x90
__Z9to_chronol: ## #_Z9to_chronol
.cfi_startproc
## %bb.0:
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset %rbp, -16
movq %rsp, %rbp
.cfi_def_cfa_register %rbp
movq %rdi, %rax
popq %rbp
retq
.cfi_endproc
All that's there is the boiler plate for a function call. And if you inline this, even that disappears.
Furthermore this function will port to C++20 by simply removing using namespace date and changing date::sys_seconds to std::chrono::sys_seconds.
Step 2: Convert sys_seconds to a tm
This is where the computation happens:
std::tm
to_tm(date::sys_seconds tp)
{
using namespace date;
using namespace std::chrono;
auto td = floor<days>(tp);
year_month_day ymd = td;
hh_mm_ss<seconds> tod{tp - td}; // <seconds> can be omitted in C++17
tm t{};
t.tm_sec = tod.seconds().count();
t.tm_min = tod.minutes().count();
t.tm_hour = tod.hours().count();
t.tm_mday = unsigned{ymd.day()};
t.tm_mon = (ymd.month() - January).count();
t.tm_year = (ymd.year() - 1900_y).count();
t.tm_wday = weekday{td}.c_encoding();
t.tm_yday = (td - sys_days{ymd.year()/January/1}).count();
t.tm_isdst = 0;
return t;
}
All of the computation happens in the first three lines:
auto td = floor<days>(tp);
year_month_day ymd = td;
hh_mm_ss<seconds> tod{tp - td}; // <seconds> can be omitted in C++17
Then the rest of the function just extracts the fields to fill out the tm members.
auto td = floor<days>(tp);
The first line above simply truncates the precision of the time_point from seconds to days, rounding down towards negative infinity (even for time_points prior to the 1970-01-01 epoch). This is little more than a divide by 86400.
year_month_day ymd = td;
The second line above takes the count of days since the epoch and converts it to a {year, month, day} data structure. This is where most of the computation happens.
hh_mm_ss<seconds> tod{tp - td}; // <seconds> can be omitted in C++17
The third line above subtracts the days-precision time_point from the seconds-precision time_point resulting in a std::chrono::seconds time duration since midnight UTC. This duration is then broken out into a {hours, minutes, seconds} data structure (the type hh_mm_ss). In C++17 this line can optionally be simplified to:
hh_mm_ss tod{tp - td}; // <seconds> can be omitted in C++17
Now to_tm simply extracts the fields to fill out the tm according to the C API.
int tm_sec; // seconds after the minute -- [0, 60]
int tm_min; // minutes after the hour -- [0, 59]
int tm_hour; // hours since midnight -- [0, 23]
int tm_mday; // day of the month -- [1, 31]
int tm_mon; // months since January -- [0, 11]
int tm_year; // years since 1900
int tm_wday; // days since Sunday -- [0, 6]
int tm_yday; // days since January 1 -- [0, 365]
int tm_isdst; // Daylight Saving Time flag
It is important to first zero-initialize the tm because different platforms have extra tm data members as extensions that are best given the value 0.
tm t{};
For the hours, minutes and seconds one simply extracts the appropriate chrono::duration from tod and then extracts the integral values with the .count() member function:
t.tm_sec = tod.seconds().count();
t.tm_min = tod.minutes().count();
t.tm_hour = tod.hours().count();
day has an explicit conversion to unsigned and this is one of the few places where the C API doesn't give a tm data member an unexpected bias:
t.tm_mday = unsigned{ymd.day()};
tm_mon is defined as "months since January" so that bias has to be taken into account. One can subtract January from the month, resulting in a months duration. This is a chrono::duration, and the integral value can be extracted with the .count() member function:
t.tm_mon = (ymd.month() - January).count();
Similarly, tm_year is years since 1900:
t.tm_year = (ymd.year() - 1900_y).count();
One can convert a days-precision time_point (td) to a weekday with conversion syntax, and then weekday has a member function .c_encoding() to extract an integral value which matches the C API: days since Sunday -- [0, 6]. Alternatively there is also a .iso_encoding() member function if one desires the ISO encoding [Mon, Sun] -> [1, 7].
t.tm_wday = weekday{td}.c_encoding();
tm_yday is days since January 1 -- [0, 365]. This is easily computed by subtracting the first of the year from the days-precision time_point (td), creating a days chrono::duration:
t.tm_yday = (td - sys_days{ymd.year()/January/1}).count();
Finally tm_isdst should be set to 0 to indicate Daylight Saving Time is not in effect. Technically this step was already done when zero-initializing tm, but is repeated here for readability purposes:
t.tm_isdst = 0;
to_tm can be ported to C++20 by:
remove using namespace date;
change date::sys_seconds to std::chrono::sys_seconds
change 1900_y to 1900y
Example Use:
Given a time_t, here is how you can use these functions to convert it to a UTC tm:
std::time_t t = std::time(nullptr);
std::tm tm = to_tm(to_chrono(t));
Here are the necessary headers:
#include "date/date.h"
#include <chrono>
#include <ctime>
Or in C++20, just:
#include <chrono>
#include <ctime>

C++: get time zone deviation

So I want to creata a time stamp (as a string) with the format HH:MM:SS in C++. I use std::chrono to get a unix time stamp and then calculate the hours, minutes and seconds.
// Get unix time stamp in seconds.
const auto unix_time_stamp = std::chrono::system_clock::now();
long long seconds_since_epoch = std::chrono::duration_cast<std::chrono::seconds>(unix_time_stamp.time_since_epoch()).count();
// Calculate current time (hours, minutes, seconds).
uint8_t hours = (seconds_since_epoch % 86400) / 3600;
uint8_t minutes = (seconds_since_epoch % 3600) / 60;
uint8_t seconds = (seconds_since_epoch % 60);
// Create strings for hours, minutes, seconds.
std::string hours_string = std::to_string(hours);
std::string minutes_string = std::to_string(minutes);
std::string seconds_string = std::to_string(seconds);
// Check if the number is only one digit. If it is, add a 0 in the beginning (5:3:9 --> 05:03:09).
if(hours_string.size() == 1)
{
hours_string = "0" + hours_string;
}
if(minutes_string.size() == 1)
{
minutes_string = "0" + minutes_string;
}
if(seconds_string.size() == 1)
{
seconds_string = "0" + seconds_string;
}
// Append to a final string.
std::string time_stamp = hours_string + ":" + minutes_string + ":" + seconds_string;
This is all working fine and great but there is one big problem: time zones.
With this way, I'm only calculating the time stamp for GMT. Is there any easy, fast and, most importantly, portable way to get the "offset" in seconds or minutes or hours for your system's time zone? By "portable" I mean platform-independent.
Please note: I know you can do all of this more easily with std::strftime and so on, but I really want to implement this by myself.
Some implementations of std::tm will contain a member that has the local offset as a member. ... But it isn't portable.
One trick is to take your seconds_since_epoch, and either assign it to a std::time_t, or just make its type std::time_t in the first place instead of long long.
... Oh, wait that isn't quite portable. Some platforms still use a 32 bit time_t. But assuming a 64 bit time_t ...
Then use localtime to get a std::tm:
std::tm tm = *localtime(&seconds_since_epoch);
This isn't officially portable because system_clock and time_t aren't guaranteed to have the same epoch. But in practice they do.
Now take the {year, month, day, hour, minute, second} fields out of the tm and compute a "local epoch". The hard part of this computation is converting the {year, month, day} part into a count of days. You can use days_from_civil from here to do that computation efficiently. Be sure to take the weird offsets into account for tm_year and tm_mon when doing this.
After you get this then subtract seconds_since_epoch from it:
auto offset = local_epoch - seconds_since_epoch;
This is your signed UTC offset in seconds. Positive is east of the prime meridian.
In C++20 this simplifies down to:
auto offset = std::chrono::current_zone()->get_info(system_clock::now()).offset;
and offset will have type std::chrono::seconds.
You can get a free, open-source preview of this here. It does require some installation.

How to calculate time differences in C++ with time_t before the epoch?

What I would like to do with my simple program is to calculate a difference in seconds between two dates.
time_t referenceDate;
time_t dateNow = time(0);
struct tm referenceDateComponent = {0};
referenceDateComponent.tm_hour = 0;
referenceDateComponent.tm_min = 0;
referenceDateComponent.tm_sec = 0;
referenceDateComponent.tm_year = 89;
referenceDateComponent.tm_mon = 11;
referenceDateComponent.tm_mday = 31;
referenceDate = mktime(&referenceDateComponent);
long seconds = difftime(dateNow, referenceDate);
Whit the code above the application works fine, but if try to set tm.year negative (to build a date before 1900) the mktime() function return -1
I know that time_t type manage only dates starting from Jan 1, 1970 UTC according with the documentation:
For historical reasons, it is generally implemented as an integral value representing the number of seconds elapsed since 00:00 hours, Jan 1, 1970 UTC (i.e., a unix timestamp). Although libraries may implement this type using alternative time representations.
I know there are also the Boost libraries but is not a usable solution for me.
So my question would be, there is any way to get difference in seconds from dates starting before 1970?
I recommend using the C++11 std::chrono namespace and <chrono> standard headers and the standard functions and classes inside them.
You might also consider difftime from the C standard and localtime & mktime
And there are a lot of good other reasons to upgrade to C++11 at least (or C++14 if you can). Several good recent free software compilers GCC and Clang/LLVM support that standard (compile with -std=c++11 or -std=gnu++14 if you want GNU extensions & C++14)
BTW, your question is much more complex than you believe. Calendars has changed. Julian/Gregorian calendar transition happened in the XXth century in Russia. My late mother was born in 1919, during emigration and the civil war, in a Russian village whose legal system was disputed at that time (Russian revolution did not occur instantly). She had some papers mentioning 13th december 1919, and other papers mentioning 26th december 1919, referring to the same date in two different calendars. How would your software deal with that? I'm not even sure that timezone is enough!
BTW, I'm not sure that Boost or C++11 <chrono> can reliably deal with such calendar issues.
nwp mentioned in a comment a very good computerphile video: Problem with Time & Timezones.
You've already answered this question. time_t represents a number of seconds since the UNIX epoch, not number of seconds since some arbitrary time before that. What you are trying to do fundamentally makes no sense.
If you're stuck on C++03, regardless of your ambiguous claims about what you can and cannot use, you will have to use Boost.DateTime.
Otherwise, the standard library has some nice modern timekeeping features in <chrono>.
When you're trying to do calendar arithmetic using time_t, you naturally have to worry about the type and representation of time_t, which is of course implementation-defined. It's almost always a signed, integral type. On Unix and modern MacOS systems it's seconds since 1970, and for compatibility I think it might be used that way on Windows, too. It tends to be 32 bits. Putting that all together, it can typically represent dates between December 13, 1901 and January 18, 2038.
And indeed when I changed the tm_year line in your code to
referenceDateComponent.tm_year = 60;
the code worked and printed 1721200226, which is about 19921 days or 54.5 years, which is exactly the difference between December 31, 1960 and today.
But if you set tm_year to be negative, you'd be asking for a date before 1900, and that's not going to work using the typical definition of time_t we've been discussing.
(It's true there are other possibilities for time_t. It could be floating point. It could be unsigned instead of signed. It could be a 64-bit type, meaning it'd have a range of almost 600,000,000,000 years, which is incidentally more than a 32-bit tm_year can hold.)
So although there are several naysayers here telling you not to, and although there are certainly plenty of obscure difficulties having to do with time zones and leap seconds and calendars other than Gregorian, you can usually get away with using time_t to do basic calendar math for dates in the 20th century and in this century up until 2038, when the infamous "Y2.038K problem" is going to hit. (It will, I fear, be somewhat worse than the not-so-infamous Y2K problem, but that's another story.)
As I said, your code worked for me for dates before 1970. Here's what I'd recommend using for simple time_t-based date calculations (and with caveats as already mentioned):
time_t makedate(int year, int month, int day)
{
struct tm tm = {0};
tm.tm_hour = 12;
tm.tm_min = tm.tm_sec = 0;
tm.tm_year = year - 1900;
tm.tm_mon = month - 1;
tm.tm_mday = day;
tm.tm_isdst = -1;
return mktime(&tm);
}
int main()
{
long int d = difftime(makedate(2015, 7, 17), makedate(2015, 6, 1));
printf("%ld sec = %ld days = %.2f years\n", d, d/86400, d/86400./365.25);
d = difftime(makedate(2015, 7, 17), makedate(2014, 7, 17));
printf("%ld sec = %ld days = %.2f years\n", d, d/86400, d/86400./365.25);
d = difftime(makedate(1975, 7, 17), makedate(1965, 7, 17));
printf("%ld sec = %ld days = %.2f years\n", d, d/86400, d/86400./365.25);
d = difftime(makedate(1950, 1, 11), makedate(1925, 1, 1));
printf("%ld sec = %ld days = %.2f years\n", d, d/86400, d/86400./365.25);
d = difftime(makedate(2030, 12, 31), makedate(2025, 12, 31));
printf("%ld sec = %ld days = %.2f years\n", d, d/86400, d/86400./365.25);
}
Just like your code, this leverages the surprisingly powerful mktime function, and can do everything it can do. It handles leap years, no problem. It does not handle leap seconds or calendar changes.
And if, as you say, you're interested in dates before 1900, I'm afraid you're out of luck. time_t simply cannot represent those dates on most systems, so you're going to have to pursue some other solution.
You can use the Gregorian calendar's 400-year periodicity to work with dates before the Epoch. (Of course, you need to be careful about the start of the Gregorian calendar in your country of interest).
Add 400 years to both dates you're comparing so that they are beyond 1970 (the Epoch), normalize with mktime(), and compute the difference with difftime():
#include <time.h>
#include <stdio.h>
double compare_dates (const struct tm *date_1, const struct tm *date_2)
{
struct tm normalized_1 = *date_1, normalized_2 = *date_2;
normalized_1.tm_year += 400, normalized_2.tm_year += 400;
time_t t1 = mktime(&normalized_1);
time_t t2 = mktime(&normalized_2);
return difftime(t1, t2);
}
int main (void)
{
// how many seconds between June 1st 1880 and 15th September 1892 ?
struct tm june_1st_1880 = { .tm_mon = 6 - 1, .tm_mday = 1, .tm_year = 1880 - 1900 };
struct tm september_15th_1892 = { .tm_mon = 9 - 1, .tm_mday = 15, .tm_year = 1892 - 1900 };
printf("%f seconds", compare_dates(&june_1st_1880, &september_15th_1892));
}

How can I convert number of seconds since 1970 to DateTime in c++?

How can I convert number of seconds since 1970 to DateTime in c++?
I am getting the time in the below format:
1296575549:573352
The left part of the colon is in seconds and the right part in micro seconds.
Please help.
Thanks,
Syd
Try and use gmtime() (see http://www.cplusplus.com/reference/clibrary/ctime/gmtime/) or localtime() to convert a time_t to a struct tm
Use boost::Date_Time to do this. Code below assumes _interval is number of seconds since 1970. Note this code example doesn't handle the micro-second portion, but I am sure it could be modified to do so.
#include <boost/date_time/gregorian/gregorian_types.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
double interval(1296575549.0f);
boost::posix_time::ptime m_DateTime = ptime(date(1970, 1, 1),
time_duration(0, 0, 0,
time_duration::ticks_per_second() *
(time_duration::fractional_seconds_type)_interval));
Three important things about converting time using C/C++ library.
gmtime() or localtime() from standard library convert from time_t to struct tm, but the resolution for time_t is seconds from epoch. So fractional seconds will not count.
mktime() converts backwards from struct tm to time_t, but it will return -1 if the input date is out of range. (Reference: year 2038 problem)
If you are not using 64bit timestamp, even you run programs on 64bit machines, you still have year 2038 problem. There are 64bit version functions like gmtime64(), localtime64(), mktime64() that may resolve the year out of range issue. (Reference)
New answer for a very old question. Rationale: Better tools.
Starting in C++11, one can easily store this quantity in a std::chrono::system_clock::time_point:
#include <chrono>
#include <iostream>
#include <sstream>
int
main()
{
using namespace std;
using namespace std::chrono;
istringstream in{"1296575549:573352"};
long si, usi;
char sep;
in >> si >> sep >> usi;
system_clock::time_point tp{seconds{si} + microseconds{usi}};
}
Though the epoch of system_clock is unspecified in C++11, every implementation is tracking Unix Time (time since 1970-01-01 00:00:00 UTC, excluding leap seconds). Different implementations will have different precisions for system_clock::time_point, but you don't really have to care about that when converting into system_clock::time_point as shown above. The <chrono> library will just do the right thing.
Starting in C++20 the Unix Time measure of system_clock::time_point will be specified, and you will be able to stream it out in a human readable form:
cout << tp << '\n';
For this example that will output:
2011-02-01 15:52:29.573352
On some platforms there may be a few trailing zeroes on this output, depending on the precision of system_clock::time_point on that platform. This is a UTC date/time. There will also be ways to convert this to a particular time zone if desired (in C++20).
You can experiment with this part of C++20 today by using Howard Hinnant's date/time library. This will require an additional #include "date/date.h" ("date/tz.h" for time zone functionality), and a using namespace date; to enable the system_clock::time_point streaming operator.
If it is known that your count of seconds includes leap seconds (Unix Time stamps don't), C++20 also provides a way to deal with that:
Just change system_clock to utc_clock in the above example and the new output will be:
2011-02-01 15:52:05.573352
which accounts for the 24 leap seconds inserted prior to this date.
As an example of duration available in seconds, let's assume you want to have an idea of the running time of your program:
#include <ctime>
time_t startRawTime;
time( &startRawTime );
//...your program performs computations...
time_t endRawTime;
time( &endRawTime );
time_t elapsedSec = difftime( endRawTime, startRawTime );
// but elapsedSec can be any duration, e.g. 3734, as long as it is in seconds
tm * ptm = gmtime( &elapsedSec );
printf( "elapsed time: %02dh %02dm %02ds\n",
ptm->tm_hour,
ptm->tm_min,
ptm->tm_sec );
You would get something like this for instance:
elapsed time: 01h 02m 14s
Well, the most complex case:
86'400 s/day
31'557'600 s/year (365.25 d)
1296575549/31557600 = 41 years
1296575549-41*31557600 = 2'713'949 s
2713949/86400 ==> 31 d
2713949-31*86400 =35'549
35549/(60*60) = 9h
35549-9*60*60 = 3'149
3'149/(60*60) = 0h
3'149- 0* (60*60) = 3'149
3149/60 = 52 m
3149-52*60 = 29s
--> year = 1970 + 41
--> month = 1 + 0
--> day = 31 (+1?)
--> Time 00:52:29
==> 2011, Jan 31, 00:52:29 GMT
To calculate the month from the day, you need to copy paste an isLeapYear function, because of February.
Hmm, looks like one also needs to account for the leap years until last leap year, which were subtracted in surplus. Hmm, effects of daylight saving time...
Go sleep !

Converting number of 100 ns since 1601 to boost posix time in C++

I am receiving from a data provider timestamps that follow this specification:
number of 100 nanoseconds since 1601
I am using boost::posix_time::ptime and I would like to convert the timestamps to posix time. Is there a simple way to do that ?
When did the switch from the Julian to Gregorian calendar occur for this system? Some countries switched before 1st January 1601; others didn't switch until much later. This will critically affect your calculation - by 11 days or so.
Since there are 107 units of 100 ns each in one second, you divide the starting number by 107 to produce the number of seconds since the reference time (the remainder is the fraction of a second). You then divide that by 86400 to give the number of days (the remainder is the time of day). Then you can compute the date from the number of days.
Since POSIX time uses 1970-01-01 00:00:00 as the reference, you may simply need to compute the correct number of seconds between 1601-01-01 00:00:00 and the POSIX epoch (as it is known), and subtract that number from the number of seconds you calculated.
number of 100 nanoseconds since 1601
It is Windows FILETIME value.
Boost.DateTime actually use Windows FILETIME for Windows platform.
Below is the relevant Boost source code that convert FILETIME to boost::posix_time::ptime:
(from boost/date_time/microsec_time_clock.hpp)
static time_type create_time(time_converter converter)
{
winapi::file_time ft;
winapi::get_system_time_as_file_time(ft);
uint64_t micros = winapi::file_time_to_microseconds(ft); // it will not wrap, since ft is the current time
// and cannot be before 1970-Jan-01
std::time_t t = static_cast<std::time_t>(micros / 1000000UL); // seconds since epoch
// microseconds -- static casts supress warnings
boost::uint32_t sub_sec = static_cast<boost::uint32_t>(micros % 1000000UL);
std::tm curr;
std::tm* curr_ptr = converter(&t, &curr);
date_type d(curr_ptr->tm_year + 1900,
curr_ptr->tm_mon + 1,
curr_ptr->tm_mday);
//The following line will adjust the fractional second tick in terms
//of the current time system. For example, if the time system
//doesn't support fractional seconds then res_adjust returns 0
//and all the fractional seconds return 0.
int adjust = static_cast< int >(resolution_traits_type::res_adjust() / 1000000);
time_duration_type td(curr_ptr->tm_hour,
curr_ptr->tm_min,
curr_ptr->tm_sec,
sub_sec * adjust);
return time_type(d,td);
}
You can browse your Boost installation for the detailed implementation.