Problem Summary
I have two strings in the form YYYY-MM-DD:hh:mm:ss and I would like to calculate the time difference between them. For example, the difference between 2021-10-01:03:44:34 and 2021-10-01:03:44:54, should be 20 seconds. However, the result I get is 0.
Code
I have tried the following:
#include <iomanip>
#include <iostream>
using namespace std;
using timestamp = time_t;
auto StringToTimestamp(const string& timeString) -> timestamp {
tm tm {};
stringstream ssBuffer(timeString);
ssBuffer >> get_time(&tm, "%Y-%b-%d:%H:%M:%S");
cout << tm.tm_year << " " << tm.tm_mon << " " << tm.tm_mday << " "
<< tm.tm_hour << " "<< tm.tm_min << " " << tm.tm_sec << " " << endl;
return mktime(&tm);
}
int main() {
string beg = {"2021-10-01:03:44:34"s};
string end = {"2021-10-01:03:44:54"s};
timestamp begTm = StringToTimestamp(beg);
timestamp endTm = StringToTimestamp(end);
double diff = difftime(endTm, begTm);
cout << "Time difference is " << diff << endl;
return 0;
}
Output
121 0 0 0 0 0
121 0 0 0 0 0
Time difference is 0
Expected Output
2021 10 01 03 44 34
2021 10 01 03 04 54
Time difference is 20
Why is the output as such? How can I fix this?
EDIT
I changed this line "%Y-%b-%d:%H:%M:%S" to "%Y-%m-%d:%H:%M:%S" and now the output is
121 9 1 3 44 34
121 9 1 3 44 54
Time difference is 20
Why are the year and month "incorrect"?
You use the conversion specifier%b to get the month but it should be %m:
ssBuffer >> get_time(&tm, "%Y-%m-%d:%H:%M:%S");
%b - parses the month name, either full or abbreviated, e.g. Oct (non-numeric)
%m - parses the month as a decimal number (range [01,12]), leading zeroes permitted but not required
The year and month are correct. 121 is the number of years since 1900 and 9 is the month, zero-based [0,11], which is what's specified for std::tm.
Related
I am new in C++.I am using STL Containers.I am mapping the AnimalWeightCAT to unique values of distance travel in km.Using this code
#include <iostream>
#include <map>
#include <sstream>
int main() {
std::istringstream file(
"3 138 3 239 3 440 3 241 3 462 3 432 3 404 2 435 2 514 2 565 3 328 3 "
"138 5 401 5 142 5 404 5 460 5 472 2 418 5 510 2");
// some typedefs to make it simpler:
typedef int AnimalWeightCAT_t;
typedef int distance_t;
typedef int count_t;
typedef std::map<distance_t, count_t> distcount_t;
typedef std::map<AnimalWeightCAT_t, distcount_t> AWeightDistance;
AWeightDistance AWeightDistanceCount; // map AnimalWeightCAT -> distances with counts
AnimalWeightCAT_t AnimalWeightCAT; // temporary variable to read a AnimalWeightCAT
distance_t dist; // temporary variable to read a distance
// read AnimalWeightCAT and distance until the file is depleated and use AnimalWeightCAT and dist as
// keys in the outer and inner map and increase the count:
while (file >> AnimalWeightCAT >> dist) ++AWeightDistanceCount[AnimalWeightCAT][dist];
for(AWeightDistance::iterator adit= AWeightDistanceCount.begin(); adit!= AWeightDistanceCount.end(); ++adit) {
std::cout << "AnimalWeightCAT: " << adit->first << '\n';
for(distcount_t::iterator dcit = adit->second.begin();dcit != adit->second.end();++dcit){
std::cout << '\t' << dcit->first << ' ' << dcit->second << '\n';
}
}
}
How i can find the count of number of distict in indices of AnimalWeightCAT of iterator aditby using map in C++?
Above code display the following output
Output:
AnimalWeightCAT: 2
418 1
435 1
514 1
565 1
AnimalWeightCAT: 3
138 2
239 1
241 1
328 1
404 1
432 1
440 1
462 1
AnimalWeightCAT: 5
142 1
401 1
404 1
460 1
472 1
510 1
I want this kind of output.How?
AnimalWeightCAT: 2 count = 4
AnimalWeightCAT: 3 count = 8
AnimalWeightCAT: 5 count = 6
For count of the second map adit->second.size() will be sufficient so your last loop, in order to look like you desire must be:
for(AWeightDistance::iterator adit = AWeightDistanceCount.begin();
adit != AWeightDistanceCount.end(); ++adit)
{
std::cout << "AnimalWeightCAT: " << adit->first
<< " count: " << adit->second.size() << '\n';
}
or simpler, using a range based for-loop:
for(auto&&[awc, dist_count] : AWeightDistanceCount) {
std::cout << "AnimalWeightCAT: " << awc
<< " count: "<< dist_count.size() << '\n';
}
I'm trying to calculate exact age of person using difference between now and the date of birth. I'm getting difference in seconds, which, I suppose is correct value. Then i'd like to convert seconds into struct tm, using gmtime(). But it is giving me a tm_year on 70 bigger than it must be, and tm_mday on 1 bigger than must be. It seems to be clear about tm_mday- the range of it is from 1 to 31, I can just subtract 1 from, whereas tm_year is the years from 1900. OK, so why does gmtime() give me +70 years?
#include <iostream>
#include <ctime>
using namespace std;
int main() {
int min,h,d,m,y;
struct tm bd = {0};
cout << "Enter birth date in the format: hh:min/dd.mm.yyyy"<<endl;
scanf("%d:%d/%d.%d.%d",&h,&min,&d,&m,&y);
bd.tm_year = y-1900;
bd.tm_mon = m-1;
bd.tm_mday = d;
bd.tm_hour = h;
bd.tm_min = min;
time_t now = time(NULL);
cout << "NOW: "<<now<<" BD: "<<mktime(&bd)<<endl;
time_t seconds = difftime(now,mktime(&bd));//(end,beginning)
cout <<"seconds elapsed: "<< seconds<<endl;
struct tm * age;
age = gmtime (&seconds);
cout << "year" << age->tm_year << endl;
cout << "mon" << age->tm_mon << endl;
cout << "mday" << age->tm_mday << endl;
cout << "hour" << age->tm_hour << endl;
cout << "min" << age->tm_min << endl;
cout << "sec" << age->tm_sec << endl;
}
output:
Enter birth date in the format: hh:min/dd.mm.yyyy
13:28/04.03.2021
NOW: 1614853702 BD: 1614853680
seconds elapsed: 22
year 70
mon 0
mday 1
hour 0
min 0
sec 22
It is translating "unix epoch time", which is seconds since 1970, to a date.
It is not converting seconds to an amount of days/months/years. There is fundamentally no such conversion. 30 days can be less than or more than a month. 365 days can be a year, or 1 day less than a year. 24 times 60 times 60 seconds can be less than a day when a leap second happens.
Seconds after a point in time is a date. But seconds does not uniquely map to a number of days/months/years.
Find the two points in time - dates - and compare/subtract components to do that.
I have a windows filetime (for example, 132522078890080000)
In Python I easily can convert it like that. Result is 1607716289 (Sat Dec 12 2020 00:51:29 GMT+0500 (Yekaterinburg Standard Time)). That's right!
But in C++ I tried to convert it like that
#include <iostream>
#include <ctime>
#define WINDOWS_TICK 10000000
#define SEC_TO_UNIX_EPOCH 11644473600LL
uint64_t WindowsTickToUnixSeconds(uint64_t windowsTicks)
{
return (uint64_t)(windowsTicks / WINDOWS_TICK - SEC_TO_UNIX_EPOCH);
}
int main() {
const uint64_t in_raw = 132522078890080000;
auto unix_timestamp = WindowsTickToUnixSeconds(in_raw);
time_t out = unix_timestamp;
std::cout << "Timestamp: " << unix_timestamp << std::endl;
std::cout << "Local: " << asctime(localtime(&out)) << std::endl;
std::cout << "GMT: " << asctime(gmtime(&out)) << std::endl;
return 0;
}
And result of that is
Timestamp: 1607734289
Local: Sat Dec 12 05:51:29 2020
GMT: Sat Dec 12 00:51:29 2020
As you can see the timestamps are different (1607734289, 1607716289, difference is 5 hours (because timezone is Asia/Yekaterinburg)).
I can easily subtract 5 hours but in that case it won't work in another timezone.
So how can I get correct timestamp?
If i ask the user to input a date
and he entered "16 then 5 then 2010"
how can I display it this way
16/5/10
I only did it this way
cout<<day<<"/"<<month<<"/"<<year<<endl;
but the output appears this way
16/5/2010
You could just print the year modulo 100. For example,
int yr1 = 1973;
int yr2 = 2010;
std::cout << (yr1%100) << std::endl; // prints 73
std::cout << (yr2%100) << std::endl; // prints 10
I am learning C++ and right we are covering preprocessors but I am trying to solve a question from a quiz which I has confused me a bit or a lot.. I tried to worked out by my own before running the program.. and my output was..
System started...
Data at 2 is: 27 28 29 30
Data at 1 is: 23 24 25 26
The data is: 19
I checked the program in Xcode to see if my output is right but the right output is the next one:
System started...
Data at 1 is: 0 0 0 19
Data at 0 is: 7 0 0 0
The data is: 19 0 0 0
This is the code...
#include <iostream>
namespace test{
#define COMPILE_FAST
#define PRINT_SPLIT(v) std::cout << (int)*((char*)(v)) << ' ' << \
(int)*((char*)(v) + 1) << ' ' << (int)*((char*)(v) +2) << ' ' << \
(int)*((char*)(v) + 3) << std::endl
typedef unsigned long long uint;
namespace er{
typedef unsigned int uint;
}
void debug(void* data, int size = 0){
if(size==0){
std::cout << "The data is: ";
PRINT_SPLIT(data);
} else {
while(size--){
std::cout << "Data at " << size << " is: ";
char* a = (char*)data;
PRINT_SPLIT((a + (4+size)));
}
}
}
}// End of Test namespace...
int main(){
test::uint a = 19;
test::er::uint b[] = {256,7};
std::cout << "System started..." << std::endl;
test::debug(b,2);
test::debug(&a);
std::cout << "Test complete";
return 0;
}
My big doubt or what I actually don't understand is whats going on here in this preprocessor because clearly for what I did its totally wrong...
#define PRINT_SPLIT(v) std::cout << (int)*((char*)(v)) << ' ' << \
(int)*((char*)(v) + 1) << ' ' << (int)*((char*)(v) +2) << ' ' << \
(int)*((char*)(v) + 3) << std::endl
if someone can be so nice and give me a brief explanation I will extremely appreciate it.
The macro prints the values (as ints) of 4 consecutive bytes. It allows you to see how a 4 byte int is layed out in memory.
Memory contents, by byte, look like this (base10):
0x22abf0: 0 1 0 0 7 0 0 0
0x22abf8: 19 0 0 0 0 0 0 0
0 1 0 0 is 256, i.e. b[0]
7 0 0 0 is 7, i.e b[1]
19 0 0 0 0 0 0 0 is 19, i.e. a
The sizeof(a) is different than the sizeof(b[0]) because there are 2 different typedefs for uint. Namely, test:uint and test::er::uint.
The address of a is greater than the address of b[] even though b is declared after a because the stack is growing downwards in memory.
Finally, I would say the output represents a defective program because the output would more reasonably be:
System started...
Data at 1 is: 7 0 0 0
Data at 0 is: 0 1 0 0
The data is: 19 0 0 0
To get that output the program needs to be changed as follows:
while(size--){
std::cout << "Data at " << size << " is: ";
int* a = (int*)data;
PRINT_SPLIT((a + (size)));