I'm looking to print hh:mm:ss.uuuuuu timestamps in C++. It seems like I need to use the chrono library and std::chrono::use high_resolution_clock::now()?
I'm unsure how to proceed from here however.
This is easily accomplished with this C++20 chrono preview library which works with C++11/14/17:
#include "date/date.h"
#include <chrono>
#include <iostream>
int
main()
{
using namespace date;
using namespace std;
using namespace std::chrono;
cout << format("%T", floor<microseconds>(system_clock::now())) << '\n';
}
Just output for me:
19:31:54.033196
This will port to C++20 by:
Drop #include "date/date.h"
Drop using namespace date;
Change "%T" to "{:%T}"
This is a header-only, open-source library.
The output is UTC. If you need local time, that is available too, but the library is not header-only. It is at the same link and would be used like this:
#include "date/tz.h"
#include <chrono>
#include <iostream>
int
main()
{
using namespace date;
using namespace std;
using namespace std::chrono;
zoned_time zt{current_zone(), floor<microseconds>(system_clock::now()))};
cout << format("%T", zt) << '\n';
}
The above syntax uses C++17. If you're using C++11 or 14 change zoned_time to zoned_time<microseconds>.
Some installation is required for the tz.h library.
Related
I have code like this that converts an Epoch timestamp into GMT timestamp:
#include <array>
#include <ctime>
#include <string>
std::string getDateTimeZ(size_t epoch)
{
const time_t time = epoch;
const auto timeInfo = *localtime(&time);
std::array<char, 80> buffer;
std::strftime(buffer.data(), buffer.size(), "%Y-%m-%dT%H:%M:%S%z", &timeInfo);
return buffer.data();
}
This works fine, except that my timestamp is e.g.:
2020-09-10T20:53:10+0300
I'd like it to be:
2020-09-10T20:53:10+03:00
How can I do this out-of-the-box without an ugly and error-prone hack on the resulting string? I don't see any other options to get the offset besides %z.
Some other library like Boost would also be acceptable.
You could use this preview of the C++20 <chrono> facilities, which works with C+11:
#include "date/tz.h"
#include <chrono>
#include <cstddef>
#include <string>
#include <sstream>
std::string
getDateTimeZ(std::size_t epoch)
{
using namespace date;
using namespace std::chrono;
zoned_seconds zt{current_zone(), sys_seconds{seconds{epoch}}};
std::ostringstream os;
os << format("%FT%T%Ez", zt);
return os.str();
}
The trick with this library is to use %Ez in place of %z.
This library does require some installation.
everyone.
I have learnt that it is often desirable to write in my codes using std::cout instead of using namespace std in order to avoid namespace conflicts. In the following script I only use cout and if I write std:: cout instead of using namespace std; it does not work.
Can anyone please help me understand why? In general, when does std::cout not work and I am forced to use using namespace std?
#include <iostream>
#include <string>
using std::cout; //if writing here "using namespace std;" instead, the code does not work
class MyClass{
public:
string name;
MyClass (string n)
{
name=n;
cout<<"Hello "<<name;
}
};
int main()
{
MyClass MyObj("Mike");
return 0;
}
You need to add using std::string; along with using std::cout; to make it work as you're not only using cout from namespace std, string is also a member of namespace std which you are using in your code.
Your code works okay with:
using std::cout;
statement for cout, but the compiler must know the location of string (actually it's std::string) too which you're currently using. You must define:
using std::string;
When you enter:
using namespace std;
It calls the entire namespace called std which contains a variety of features added as C++ standard library and then you don't need to use prefix std:: for those functions/classes/variables of that namespace.
I am using an API to retrieve a UNIX time but it's coming in as a string i.e. "1539944398000"
I would like to convert this to a UNIX time so that I can manipulate it (and eventually extract just the hours/minutes to put in a print).
Here's the code that I tried:
String nextBusScheduled = client2.readStringUntil('<');
char bufScheduled[40];
strptime(bufScheduled, "%Y-%m-%d", nextBusScheduled);
And this is the error I got:
cannot convert 'String' to 'tm*' for argument '3' to 'char* strptime(const char*, const char*, tm*)'
I recommend Howard Hinnant's date/time library. For this exercise, all you need is the date.h header (and no source):
#include "date/date.h"
#include <chrono>
#include <cstdint>
#include <iostream>
#include <sstream>
int
main()
{
using namespace date;
using namespace std;
using namespace std::chrono;
int64_t i;
istringstream in{"1539944398000"};
in >> i;
sys_time<milliseconds> tp{milliseconds{i}};
cout << tp << '\n';
cout << format("%H:%M", tp) << '\n';
}
Just parse into a 64 bit integral type, and construct a std::chrono::milliseconds from that parse (so far this is just straight C++11). Then you can construct a sys_time<milliseconds> from that. sys_time<milliseconds> is just a type alias for std::chrono::time_point<std::chrono::system_clock, std::chrono::milliseconds>, or to put it more simply: a Unix Time with millisecond precision.
I show two ways of printing it out, which is where date.h really helps. This example outputs:
2018-10-19 10:19:58.000
10:19
This code will port to C++20 by just removing #include "date/date.h" and using namespace date;.
#include <string>
#include "boost\date_time\gregorian\gregorian.hpp"
#include <boost\algorithm\string.hpp>
using namespace std;
using namespace boost::gregorian;
using namespace boost;
void printString()
{
vector<string> strs;
boost::split(strs, "string to split", boost::is_any_of(' '));
cout << strs[0];
}
This flags up about 6 errors in Boost and 1 in std. My thinking is the namespaces are messing up. This is an edited version of the actual code base but basically I'm using boost::gregorian for a seperate date_time thing and boost for the algoritm code base. I saw an example and using more than one namespace was fine. For me it's just not letting me use split.
You're passing a single character to boost::is_any_of, but it expects a sequence.
Change the code from:
from: boost::is_any_of(' ')
to: boost::is_any_of(" ") and you should be golden.
(oh yeah, and add #include <vector> and #include <iostream> to your example.
I'm using boost::date_time and I got a time_t, that have been generated by a library using the time() function from the C standard library.
I'm looking for a way get a local time from that time_t. I'm reading the documentation and can't find any way to do this without providing a time zone, that I don't know about because it's dependant on the machine's locale, and I can't find any way to get one from it.
What am I missing?
boost::posix_time::from_time_t()
#include <ctime>
#include <ostream>
#include <iostream>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/date_time/local_time_adjustor.hpp>
#include <boost/date_time/c_local_time_adjustor.hpp>
boost::posix_time::ptime local_ptime_from_utc_time_t(std::time_t const t)
{
using boost::date_time::c_local_adjustor;
using boost::posix_time::from_time_t;
using boost::posix_time::ptime;
return c_local_adjustor<ptime>::utc_to_local(from_time_t(t));
}
int main()
{
using boost::posix_time::to_simple_string;
using boost::posix_time::from_time_t;
std::time_t t;
std::time(&t); // initalize t as appropriate
std::cout
<< "utc: "
<< to_simple_string(from_time_t(t))
<< "\nlocal: "
<< to_simple_string(local_ptime_from_utc_time_t(t))
<< std::endl;
}
For this task, I'd ignore boost::date_time and just use localtime (or localtime_r, if available) from the standard library.