This a problem from introduction to C++ course. We need to read a Data from the file jan91.dat. Data looks like that.
1 59 26 43 .. .. .. .. ..
2 40 12 24 .. .. .. .. ..
3 21 14 18 .. .. .. .. ..
4 .. .. .. .. .. .. .. ..
First number is a date, we want to read only second and third number from each line.
Second number is Max Temperature, and third number is Min Temperature. Later we may need to read other numbers in a line like humidity etc that (but it is not required yet).
// This program determines the number of days in each of six
// temperature categories for the days of January 1991.
#include <iostream> // required for cin and cout
#include <iomanip> // required for set precision, setw
#include <fstream> // required for ifstream and ofstream
#include <string> // required for string
using namespace std; // standard library
int main()
{
// Name of Variables
int i, below0 = 0, from0to32 = 0, from33to75 = 0, above75 = 0;
double min_temp, max_temp, date = 0;
const string FILENAME = "jan91.dat";
// Open input file
ifstream jan91;
jan91.open(FILENAME.c_str());
if (jan91.fail()) {
cerr << "Error opening file" << endl;
exit(1);
}
// Read and check temperature per day
while (!jan91.eof()) {
(jan91 >> date >> max_temp >> min_temp);
if (min_temp < 0);
below0++;
if (max_temp > 75) {
from0to32++;
from33to75++;
above75++;
}
else if (max_temp > 33 && max_temp < 75) {
from0to32++;
from33to75++;
}
else if (max_temp > 0 && max_temp < 33) {
from0to32++;
}
}
// Print results
cout << "January of 1991" << endl;
cout << "Temperature Ranges \t Number of Days " << endl;
cout << "Below 0 \t \t\t" << below0 << endl;
cout << "0 to 32 \t \t\t" << from0to32 << endl;
cout << "33 to 75\t \t\t" << from33to75 << endl;
cout << "Above 75 \t \t\t" << above75 << endl;
// Close file
jan91.close();
// Exit program.
return 0;
}
some people suggested to use "getline" but for some reason I could not use it in my Visual Studio 17.3.3
Please advise
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.
I'm using ta-lib c++ library to calculate MACD, but the result is totally different from what the website shows,
the real MACD is [444.39, 505.05, 248.02, -232.33, 100.39, -13.18],
but my result is [282.10, -74.12, -211.27, -460.82, -850.86]
I have set all the MAType to TA_MAType_EMA, but it makes no sense
#include <iostream>
#include <cassert>
#include <ta-lib/ta_libc.h>
using namespace std;
int main()
{
// init ta-lib context
TA_RetCode retcode;
retcode = TA_Initialize();
assert(retcode == TA_SUCCESS);
// comput moving average price
TA_Real close_price_array[100] = { 37924.41, 40849.89, 37952.37, 36564.58, 36844.22, 34719.71, 33156.65, 32858.22,
34212.01, 37118.35, 31924.17, 30327.18, 31757.38, 34459.95, 31952.8 , 31876.57,
32457.32, 31392.34, 34183.43, 37328.12, 36408.31, 35732.04, 37460.76, 35627.27,
39551.87, 34677.01, 33834.78, 31580.01, 39674.77, 40513.11, 40829.87, 38950.0 ,
34555.33, 32091.45, 31737.83, 33506.67, 31695.17, 29190.91, 28779.14, 28153.95,
26617.04, 26911.93, 27360.51, 25625.24, 24019.43, 23230.15, 23450.3 , 23341.65,
23099.56, 23873.04, 23551.1 , 22553.6 , 23329.31, 20659.69, 19406.28, 19198.7 ,
19215.36, 18401.98, 18106.72, 18134.91, 18347.36, 18806.82, 19213.0 , 19126.33,
19107.67, 18945.51, 19533.84, 18891.06, 19265.5 , 19306.92, 18116.34, 17505.0 ,
16502.76, 16905.43, 19129.39, 19358.42, 18269.55, 18294.73, 18784.06, 18655.81,
18046.78, 17871.06, 17318.57, 16450.98, 16026.15, 15950.15, 16098.79, 16122.33,
15666.22, 15168.03, 15004.24, 15354.6 , 15342.63, 15411.23, 15077.18, 13911.95,
13708.92, 13492.15, 13797.96, 13854.39 };
TA_Real *p = close_price_array;
cout.precision(8);
TA_Integer out_begin = 0;
TA_Integer out_nb_element = 0;
TA_Real outMACD[100] = { 0 };
TA_Real outMACDSignal[100] = { 0 };
TA_Real outMACDHist[100] = { 0 };
retcode = TA_MACDEXT(0, 99,
&close_price_array[0],
12, TA_MAType_EMA ,
26, TA_MAType_EMA ,
9, TA_MAType_EMA ,
&out_begin, &out_nb_element,
outMACD, outMACDSignal, outMACDHist);
assert(retcode == TA_SUCCESS);
cout << "out_begin_index: " << out_begin << endl;
cout << "out_nb_element: " << out_nb_element << endl;
cout << "outMACD array: " << endl;
for (auto &i : outMACD)
cout << i << " ";
cout << endl;
cout << "outMACDSignal array: " << endl;
for (auto &i : outMACDSignal)
cout << i << " ";
cout << endl;
cout << "outMACDSignal array: " << endl;
for (auto &i : outMACDHist)
cout << i << " ";
cout << endl;
retcode = TA_Shutdown();
assert(retcode == TA_SUCCESS);
return 0;
}
enter image description here
[After comparing TA-lib results with Excel calculations]: In your excel the 12-day EMA is calculated from the 1st day and its first value is the average on 12th day (8/13/2020) and the 26-day EMA is calculated from 1st day and first value is average on 26th day (26/13/2020). TA-Lib postpones the 12 day EMA calculation start to get its first value on the same day as first value of 26-day EMA. That means 12-day EMA is calculated from 8/16/2020 and it's first value is the average on (26/13/2020) as it's in 26-day EMA. So to adjust your excel to TA-Lib results you need to copy formula =AVERAGE(B19:B30) into the cell C30.
Another note is that TA-Lib's MACD outputs 3 arrays at once: macd, signal, histogram. And thus TA-Lib starts the output at the point it got meaningful values for all 3 result arrays. Thus you're getting result starting not from the point where 26-day EMA can be calculated, but from the point where Signal can be calculated (8 days later). So you shall compare talib_macd[1] with excel starting from cell E38 instead of E30.
I want to generate the current UTC date time in milliseconds precision but I am only be able to get it in seconds or microsec precision.
Is it possible to get it in milliseconds precision?
std::cout << to_iso_extended_string(microsec_clock::universal_time()) + "Z" << std::endl;
"2020-02-27T13:05:46.543801Z"
std::cout << to_iso_extended_string(second_clock::universal_time()) + "Z" << std::endl;
"2020-02-27T13:11:00Z"
Expected format:
"2020-02-27T13:05:46.543Z"
I think you can take a substring from the microsecond version.
Something like:
std::string microsec_time = to_iso_extended_string(microsec_clock::universal_time());
std::string millisec_time = microsec_time.substr(0, microsec_time.size()-3);
std::cout << millisec_time << 'Z' << std::endl;
It should give you the output you expect.
i tried doing this:
struct Den_t
{
int day, month, year;
};
int main()
{
struct Den_t* Datum = new struct Den_t;
struct Den_t* Dnes = new struct Den_t;
time_t theTime = time(NULL);
struct tm aTime;
localtime_s(&aTime, &theTime);
Dnes->day = aTime.tm_mday;
Dnes->month = aTime.tm_mon + 1;
Dnes->year = aTime.tm_yday + 1900;
cin >> Datum->day >> Datum->month >> Datum->year;
if (Dnes->year - Datum->year >= 18 )
cout << "full aged " << endl;
else
cout << "not full aged " << endl;
system("PAUSE");
return 0;
}
but i somehow cant understand what should i even compare and decrement,could someone explain me
what else i need to do to tell people's date for example in float by
comparing year,month and day of actual time and date user inputs in
the program?
You have an issue with your code logic here.
For example:
Datum is 31/12/1982
Dnes is 01/01/2000
The year difference is 18 but the age is 17 and 2 days.
Consider using standard library functions instead of reinventing the wheel.
difftime could be useful, for example
This is a very dirty example, but it would do the work:
time_t dnes;
time(&dnes);
// Set datum here ...
cin >> Datum->day >> Datum->month >> Datum->year;
datum.tm_mday = Datum->day;
datum.tm_mon = Datum->month - 1;
datum.tm_yday = Datum->year - 1900;
datum->tm_yday+=18;
if (difftime(dnes, mktime(&datum)) <0 )
cout << "not full aged " << endl;
else
cout << "full aged " << endl;
Using these libraries:
http://howardhinnant.github.io/date/date.html
http://howardhinnant.github.io/date/tz.html
This is how I would tackle the problem. First the code, then the explanation:
#include "tz.h"
#include "date.h"
#include <iostream>
int
main()
{
using namespace date;
using namespace std::chrono;
std::cout << "Enter birthday [day month year]:";
int di, mi, yi;
std::cin >> di >> mi >> yi;
if (std::cin.fail())
{
std::cout << "Invalid date\n";
return 1;
}
auto y = year{yi};
if (!y.ok())
{
std::cout << "Invalid year\n";
return 1;
}
auto m = month(mi);
if (!m.ok())
{
std::cout << "Invalid month\n";
return 1;
}
auto d = day(di);
if (!d.ok())
{
std::cout << "Invalid day\n";
return 1;
}
auto birthday = y/m/d;
if (!birthday.ok())
{
std::cout << "Invalid birthday\n";
return 1;
}
auto local_time = current_zone()->to_local(system_clock::now());
auto today = year_month_day{floor<days>(local_time)};
auto age = today.year() - birthday.year();
if (birthday + age > today)
--age;
if (age >= years{18})
std::cout << "full aged at " << age.count() << "\n";
else
std::cout << "not full aged at " << age.count() << "\n";
}
I would first go to some trouble to check the validity of the user input. What I have below seems like a minimum:
It must be integral input.
Each integral input must have a reasonable value (e.g. month must be in the range [1, 12].
The combination y/m/d must be a valid date.
A more robust program might give the user some feedback on what he input, and give him another chance to correct his mistake.
Once assured we have a valid birthday, we need to get the current date in the local timezone. This:
auto local_time = current_zone()->to_local(system_clock::now());
gets the local time.
This local time can be converted to a local year, month and day with:
auto today = year_month_day{floor<days>(local_time)};
This computation follows the custom that your birthday begins at the local midnight, regardless of what time of day (and where on the planet) you were actually born. In other words, once the local year/month/day is established, this problem is independent of the local time zone, and even the local time of day.
Next, the current age is computed:
auto age = today.year() - birthday.year();
if (birthday + age > today)
--age;
The difference between the years of today and the birthday is a first approximation to the age. This approximation is refined by computing the date on which your birthday falls this year. If this year's birthday is still in the future, then by custom we count that as one year younger. If we were doing something that leaned less towards a legal system, and more towards scientific work, we might well compute in other ways, such as rounding to the nearest year (also easy to do with this library).
If the birthday is on Feb 29, the above code still works: birthday + age will result (75% chance) in an invalid date, e.g.: feb/29/2015. However this invalid date will correctly compare greater than feb/28/2015 and less than mar/1/2015, exactly as we need it to! Invalid dates are your friend, not your enemy -- you just have to know they exist and what to do about them.
Now it is a simple matter to report your findings:
if (age >= years{18})
std::cout << "full aged at " << age.count() << "\n";
else
std::cout << "not full aged at " << age.count() << "\n";