How can I convert a time_t
structure to years as decimal?
For example, for a date 2015-07-18 00:00:00
I would like to get 2015.625
.
How can I convert a time_t
structure to years as decimal?
For example, for a date 2015-07-18 00:00:00
I would like to get 2015.625
.
Following my comment seeking more information about how you came to .625
, I will assume that you actually meant .55
because July 18th, 2015 is the 199th day of the year.
You need to first use get_time
to get time from a string into a std::tm
structure. Then, with some help from mktime
we should be able to get the day of the year. Following that, we can perform a quick calculation to see if the year is a leap year, and then perform division to get our ratio:
#include <ctime>
#include <iostream>
#include <sstream>
#include <locale>
#include <iomanip>
#include <string.h>
int main()
{
std::tm theTime = {};
// initialize timeToConvert with the Year-Month-Day Hours:Minutes:Seconds string you want
std::string timeToConvert = "2015-07-18 00:00:00";
std::istringstream timeStream(timeToConvert);
// need to use your locale (en-US)
timeStream.imbue(std::locale("en_US.UTF-8"));
timeStream >> std::get_time(&theTime, "%Y-%m-%d %H:%M:%S");
if (timeStream.fail())
{
std::cerr << "Parse failed\n";
exit(0);
}
// call mktime to fill out other files in theTime
std::mktime(&theTime);
// get years since 1900
int year = theTime.tm_year + 1900;
/* determine if year is leap year:
If the year is evenly divisible by 4, go to step 2. ...
If the year is evenly divisible by 100, go to step 3. ...
If the year is evenly divisible by 400, go to step 4. ...
The year is a leap year (it has 366 days).
The year is not a leap year (it has 365 days).
*/
bool isLeapYear = year % 4 == 0 &&
year % 100 == 0 &&
year % 400 == 0;
// get number of days since January 1st
int days = theTime.tm_yday+1; // Let January 1st be the 1st day of year, not 0th
// get number of days in this year (either 365 or 366 if leap year)
int daysInYear = isLeapYear ? 366 : 365;
double yearAsFloat = static_cast<double>(year) + static_cast<double>(days)/static_cast<double>(daysInYear);
std::cout << timeToConvert << " is " << yearAsFloat << std::endl;
}
Output:
2015-07-18 00:00:00 is 2015.55
You could convert it into a broken down time using e.g. std::gmtime
or std::localtime
.
The broken down time structure contains the year, and a tm_yday
member which is the days since January 1. You could use this tm_yday
member to calculate the part after the decimal point.
If you want higher resolution, use the hours, minutes and seconds too.
Use strftime
struct stat info;
char buff[20];
struct tm * timeinfo;
stat(workingFile, &info);
timeinfo = localtime (&(info.st_mtime));
strftime(buff, 20, "%b %d %H:%M", timeinfo);
printf("%s",buff);
Formats:
%b - The abbreviated month name according to the current locale.
%d - The day of the month as a decimal number (range 01 to 31).
%H - The hour as a decimal number using a 24-hour clock (range 00 to 23).
%M - The minute as a decimal number (range 00 to 59).
Use the following steps:
std::gmtime
.X
= number of days in the day and month (keeping in mind that the year could be a leap year); For example, for the 3rd of February X
will always be 31 + 3 = 34;
For 3rd of March, it would be 31 + 28 + 3 = 62
or 31 + 29 + 3 = 63
for leap years;Y
= the number of days for the year(X * 100.) / Y
and display it with three decimals