Calculate the daily midnight time from current timestamp - c++

Like suppose Current time is 2021-05-16 22:42 then midnight time be 2021-05-17 00:00:00 at 12 when time change.
I want to calculate the time left in midnight to come from the current time.

You could do:
#include <iostream>
#include <ctime>
#include <sstream>
int main() {
struct tm tm;
std::string s("2013-12-04 15:03");
strptime(s.c_str(), "%Y-%m-%d %H:%M", &tm);
struct tm tm1 = tm;
tm1.tm_mday = tm1.tm_mday +1;
tm1.tm_hour = 0;
tm1.tm_min = 0;
double secs = std::difftime(mktime(&tm1), mktime(&tm));
std::cout<<secs<<" seconds\n";
return 0;
}

Related

MKTIME always return -1 (Window10_64bit / MSVS2019 / C++)

I have problem..
I can not understand why Function MKTIME always return -1
#include <Windows.h>
#include <stdio.h>
#include <time.h>
using namespace std;
int main() {
time_t now = time(NULL);
struct tm today;
localtime_s(&today, &now);
today.tm_year += 1900;
today.tm_mon += 1;
time_t t_today = mktime(&today);
printf("%ld", (long)t_today);
return 0;
}
t_today is -1
mktime can deal with only upto the year 3000. Adding 1900 to today.tm_year will exceed this limit. (1970 + 1900 = 3870) Try smaller offset.
References:
localtime_s, _localtime32_s, _localtime64_s | Microsoft Docs
mktime, _mktime32, _mktime64 | Microsoft Docs

How can a Windows DATE be converted into a Unix time in c++

Windows uses the DATE type to represent dates. This is a double value representing the number of days since 30 December 1899, midnight.
How can a DATE be converted into a Unix timestamp (the number of seconds since 01 January 1970) value?
Specifically, how can this be achieved using only the c++ standard library, and windows libraries for which MinGW distributes header files?
For example, I can get a date property from an IShellFolder2:
void MyFunc(IShellFolder2 *folder, PCUITEMID_CHILD pidl, const SHCOLUMNID *columnid) {
VARIANT* v = (VARIANT*) malloc(sizeof(VARIANT));
DATE d;
HRESULT hr = folder->GetDetailsEx(pidl, colid, v);
if (SUCCEEDED(hr)) {
hr = VariantChangeType(v, v, 0, VT_DATE);
if (SUCCEEDED(hr)) {
d = v->date;
}
VariantClear(v);
}
free(v);
// process date here
}
How do I then transform this value for use with software that uses the Unix timestamp format?
Currently used header files (not all relevant to this specific issue):
#include <iostream>
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include <shlobj.h>
#include <shlwapi.h>
#include <propkey.h>
#include <wchar.h>
#include <shlguid.h>
#include <string>
#include <vector>
Use VariantTimeToSystemTime to convert DATE to SYSTEMTIME.
Conversion of SYSTEMTIME to unix time is then a simple task.
In Visual Studio you could use COleDateTime but that's not available in MinGW
#include <Windows.h>
#include <stdio.h>
#include <time.h>
#include <OleAuto.h>
unsigned int unix_stamp_of_DATE(DATE date)
{
//convert DATE to SYSTEMTIME
SYSTEMTIME st;
VariantTimeToSystemTime(date, &st);
//convert SYSTEMTIME to FILETIME
FILETIME ft;
SystemTimeToFileTime(&st, &ft);
//convert FILETIME to ULARGE_INTEGER
//then QuadPart is 64bit timestamp
ULARGE_INTEGER ul{ ft.dwLowDateTime, ft.dwHighDateTime };
return (unsigned int)((ul.QuadPart - 116444736000000000ULL)/10000000);
}
Usage:
int main()
{
DATE dt = 25569.000000f; //1970, 1, 1
time_t rawtime = unix_stamp_of_DATE(dt);
tm *timeinfo = gmtime(&rawtime); //DATE was UTC!
char buf[50];
strftime(buf, sizeof(buf), "%c", timeinfo);
printf("%s\n", buf);
return 0;
}
Explanation: unix_epoch is 116444736000000000U, calculated as
ULARGE_INTEGER unix_epoch{ 0 };
FILETIME ft;
SYSTEMTIME st = { 0 };
st.wDay = 1;
st.wMonth = 1;
st.wYear = 1970;
SystemTimeToFileTime(&st, &ft);
unix_epoch = ULARGE_INTEGER{ ft.dwLowDateTime, ft.dwHighDateTime };
//=116444736000000000U
Alternate method
int main()
{
DATE dt = 25569.000000; //1970,1,1
SYSTEMTIME st;
VariantTimeToSystemTime(dt, &st);
time_t rawtime;
struct tm * timeinfo;
time(&rawtime);
//system time or localtime?
timeinfo = gmtime(&rawtime);
//timeinfo = localtime(&rawtime);
timeinfo->tm_year = st.wYear - 1900;
timeinfo->tm_mon = st.wMonth - 1;
timeinfo->tm_mday = st.wDay;
timeinfo->tm_hour = st.wHour;
timeinfo->tm_min = st.wMinute;
timeinfo->tm_sec = st.wSecond;
mktime(timeinfo);
printf("%d\n", st.wYear);
return 0;
}

Get a time_t from universal time string?

If I have this string:
2011-10-08T07:07:09Z
is it possible to get a time_t from it? If so, how can this be done?
Yes, it is. First, convert it to a broken down time with strptime(3). This gives you a struct tm, which is the structure type for a broken down time.
From there, you can convert to a time_t with mktime(3).
Here's an example:
#define _XOPEN_SOURCE
#include <time.h>
#include <stdio.h>
#include <string.h>
int main(void) {
const char *date_example = "2011-10-08T07:07:09Z";
struct tm broken_down;
memset(&broken_down, 0, sizeof(broken_down));
strptime(date_example, "%Y-%m-%dT%H:%M:%SZ", &broken_down);
broken_down.tm_isdst = 0; // Indicates that DST is not in effect
time_t epoch_time = mktime(&broken_down);
// Note: this is platform dependent
printf("Epoch time: %lld\n", (long long) epoch_time);
return 0;
}
Use sscanf() to tear apart the time. The trick is somehow determine the difference between local and universal time so code may call mktime() - which uses assumes struct tm is local time..
#include <time.h>
#include <stdio.h>
int Get_TZ_delta(const struct tm *tmptr) {
// Make local copy
struct tm tm = *tmptr;
time_t t = mktime(&tm);
struct tm utc_tm = *gmtime(&t);
time_t t2 = mktime(&utc_tm);
return (int) difftime(t, t2);
}
time_t UniversalTimeStamp_to_time_t(const char *ts) {
struct tm tm = { 0 };
// Use a sentinel to catch extra garbage
char sentinel;
if (sscanf(ts, "%d-%2d-%2dT%2d:%2d:%2dZ%c", &tm.tm_year, &tm.tm_mon,
&tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec, &sentinel) != 6) {
return -1;
}
// struct tm uses offset from 1900 and January is month 0
tm.tm_year -= 1900;
tm.tm_mon--;
// Convert tm from UCT to local standard time
tm.tm_isdst = 0;
tm.tm_sec += Get_TZ_delta(&tm);
time_t t = mktime(&tm); // mktime() assumes tm is local
// test code
{
printf("UTC `%s`\n", ts);
char buf[100];
strftime(buf, sizeof buf, "%Y-%m-%dT%H:%M:%S %Z", &tm);
printf("Local %s\n", buf);
printf("Unix %lld\n\n", (long long) mktime(&tm));
}
return t;
}
int main(void) {
UniversalTimeStamp_to_time_t("2015-06-18T22:07:52Z");
UniversalTimeStamp_to_time_t("2011-10-08T07:07:09Z");
UniversalTimeStamp_to_time_t("1970-01-01T00:00:00Z");
return 0;
}
Output
UTC `2015-06-18T22:07:52Z`
Local 2015-06-18T17:07:52 CDT
Unix 1434665272
UTC `2011-10-08T07:07:09Z`
Local 2011-10-08T02:07:09 CDT
Unix 1318057629
UTC `1970-01-01T00:00:00Z`
Local 1969-12-31T18:00:00 CST
Unix 0
Another approach works should code know that time_t is the number of seconds since Jan 1, 1970 0:00:00. Uses sscanf() to parse the string, calculate the number of days, and then return the number of seconds.
#include <time.h>
#include <stdio.h>
#define MARCH 3
#define DaysPer400Years (400*365LL + 97)
#define DaysPer100Years (100*365LL + 24)
#define DaysPer4Years (4*365LL + 1)
#define DaysPer1Year 365LL
#define DayNumber1970Jan1 719469LL
long long DayNumber(int year, int Month, int Day, long epoch) {
long long dn = Day;
long long y = year;
y += Month / 12;
Month %= 12;
while (Month < MARCH) {
Month += 12;
y--;
}
// And then a miracle occurs.
dn += ((Month - MARCH) * (7832 / 4) + (140 / 4)) >> (8 - 2);
dn += (y / 400) * DaysPer400Years;
y %= 400;
dn += (y / 100) * DaysPer100Years;
y %= 100;
dn += (y / 4) * DaysPer4Years;
y %= 4;
dn += y * DaysPer1Year;
return dn - epoch;
}
time_t UniversalTimeStamp_to_time_t(const char *ts) {
int y,m,d,H,M,S;
// Use a sentinel to catch extra garbage
char sentinel;
if (sscanf(ts, "%d-%2d-%2dT%2d:%2d:%2dZ%c", &y, &m,
&d, &H, &M, &S, &sentinel) != 6) {
return -1;
}
long long t = DayNumber(y, m, d, DayNumber1970Jan1);
t = t*24L*60*60 + 3600L*H + 60*M + S;
// test code
{
printf("UTC `%s`\n", ts);
time_t tt = t;
struct tm tm = *gmtime(&tt);
char buf[100];
strftime(buf, sizeof buf, "%Y-%m-%dT%H:%M:%S %Z", &tm);
printf("Local %s\n", buf);
printf("Unix %lld\n\n", t);
}
return t;
}
int main(void) {
UniversalTimeStamp_to_time_t("2015-06-18T22:07:52Z");
UniversalTimeStamp_to_time_t("2011-10-08T07:07:09Z");
UniversalTimeStamp_to_time_t("1970-01-01T00:00:00Z");
return 0;
}
Output
UTC `2015-06-18T22:07:52Z`
Local 2015-06-18T22:07:52
Unix 1434665272
UTC `2011-10-08T07:07:09Z`
Local 2011-10-08T07:07:09
Unix 1318057629
UTC `1970-01-01T00:00:00Z`
Local 1970-01-01T00:00:00
Unix 0

Printing the total amount of time elapsed while processing the program

I am trying a write a stopwatch which is used to keep track of the program's running time. The code showing the private members is as follows:-
#include <sys/time.h>
class stopwatch
{
private:
struct timeval *startTime;
int elaspedTime;
timezone *Tzp;
public:
//some code here
};
The problem is that while compiling the program, I am getting an error that ISO C++ forbids declaration of 'timezone' with no type. I am thinking this might be due to library that I am using but I am not able to correct my mistake. I have searched on the internet but the only post about <sys/time.h> is that it is very obsolete now. They did not suggest any alternatives. Can you please me.
You can just use chrono:
#include <chrono>
#include <iostream>
int main(int argc, char* argv[])
{
auto beg = std::chrono::high_resolution_clock::now();
// Do stuff here
auto end = std::chrono::high_resolution_clock::now();
std::cout << std::chrono::duration_cast<std::chrono::milliseconds>(end - beg).count() << std::endl;
std::cin.get();
return 0;
}
As seen here
#include <iostream> /* cout */
#include <time.h> /* time_t, struct tm, difftime, time, mktime */
int main ()
{
time_t timer;
struct tm y2k;
double seconds;
y2k.tm_hour = 0; y2k.tm_min = 0; y2k.tm_sec = 0;
y2k.tm_year = 100; y2k.tm_mon = 0; y2k.tm_mday = 1;
time(&timer); /* get current time; same as: timer = time(NULL) */
seconds = difftime(timer,mktime(&y2k));
std::cout << seconds << "seconds since January 1, 2000 in the current timezone" << endl;
return 0;
}
You can modify names as you want. Also, here's a timer with <sys/time.h>
If you're developing on a windows environment, you can call unsigned int startTime = timeGetTime()(msdn) once when the program starts and unsigned int endTime = timeGetTime() when it ends. Subtract endTime from startTime and you have the number of milliseconds that have passed since the program started. If you're looking for more accuracy, check out the QueryPerformanceCounter functions.

C convert char[] to timestamp;

I have char date[] = "2011-04-01"; How it convert to timestamp in C or C++ ?
Warning: strptime is a POSIX-function (may not be available through time.h on OS "Windows" platform).
#include <time.h>
struct tm time;
strptime("2011-04-01", "%Y-%m-%d", &time);
time_t loctime = mktime(&time); // timestamp in current timezone
time_t gmttime = timegm(&time); // timestamp in GMT
Try this:
char date[] = "2011-04-01";
date[4] = date[7] = '\0';
struct tm tmdate = {0};
tmdate.tm_year = atoi(&date[0]) - 1900;
tmdate.tm_mon = atoi(&date[5]) - 1;
tmdate.tm_mday = atoi(&date[8]);
time_t t = mktime( &tmdate );