¿Cómo se imprime un punto de tiempo C++11?
He creado un punto de tiempo, pero he estado luchando para imprimirlo en el terminal.
#include <iostream>
#include <chrono>
int main(){
//set time_point to current time
std::chrono::time_point<std::chrono::system_clock,std::chrono::nanoseconds> time_point;
time_point = std::chrono::system_clock::now();
//print the time
//...
return 0;
}
La única documentación que puedo encontrar que imprime un time_point se encuentra aquí: http://en.cppreference.com/w/cpp/chrono/time_point
Sin embargo, ni siquiera puedo crear un time_t basado en mi time_point(como en el ejemplo).
std::time_t now_c = std::chrono::system_clock::to_time_t(time_point); //does not compile
Error:
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/chrono: In instantiation of ‘constexpr std::chrono::time_point<_Clock, _Dur>::time_point(const std::chrono::time_point<_Clock, _Dur2>&) [with _Dur2 = std::chrono::duration<long int, std::ratio<1l, 1000000000l> >; _Clock = std::chrono::system_clock; _Dur = std::chrono::duration<long int, std::ratio<1l, 1000000l> >]’:
time.cpp:13:69: required from here
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/chrono:540:32: error: no matching function for call to ‘std::chrono::duration<long int, std::ratio<1l, 1000000l> >::duration(std::chrono::time_point<std::chrono::system_clock, std::chrono::duration<long int, std::ratio<1l, 1000000000l> > >::duration)’
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/chrono:540:32: note: candidates are:
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/chrono:247:14: note: template<class _Rep2, class _Period2, class> constexpr std::chrono::duration::duration(const std::chrono::duration<_Rep2, _Period2>&)
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/chrono:247:14: note: template argument deduction/substitution failed:
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/chrono:243:46: error: no type named ‘type’ in ‘struct std::enable_if<false, void>’
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/chrono:240:23: note: template<class _Rep2, class> constexpr std::chrono::duration::duration(const _Rep2&)
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/chrono:240:23: note: template argument deduction/substitution failed:
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/chrono:236:27: error: no type named ‘type’ in ‘struct std::enable_if<false, void>’
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/chrono:234:12: note: constexpr std::chrono::duration<_Rep, _Period>::duration(const std::chrono::duration<_Rep, _Period>&) [with _Rep = long int; _Period = std::ratio<1l, 1000000l>]
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/chrono:234:12: note: no known conversion for argument 1 from ‘std::chrono::time_point<std::chrono::system_clock, std::chrono::duration<long int, std::ratio<1l, 1000000000l> > >::duration {aka std::chrono::duration<long int, std::ratio<1l, 1000000000l> >}’ to ‘const std::chrono::duration<long int, std::ratio<1l, 1000000l> >&’
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/chrono:232:12: note: constexpr std::chrono::duration<_Rep, _Period>::duration() [with _Rep = long int; _Period = std::ratio<1l, 1000000l>]
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/chrono:232:12: note: candidate expects 0 arguments, 1 provided
6 answers
(En este post omitiré std::chrono::
las calificaciones para la claridad. Confío en que sepa adónde van.)
La razón por la que su ejemplo de código no se compila es que hay un desajuste entre el tipo devuelto de system_clock::now()
y el tipo de variable al que está tratando de asignar esto (time_point<system_clock, nanoseconds>
).
El valor de retorno documentado de system_clock::now()
es system_clock::time_point
, que es un typedef para time_point<system_clock, system_clock::duration>
. system_clock::duration
está definido por la implementación, con microseconds
y nanoseconds
siendo de uso común. Parece que su implementación utiliza microseconds
, por lo que el tipo de retorno de system_clock::now()
es time_point<system_clock, microseconds>
.
time_point
s con diferentes duraciones no son implícitamente convertibles entre sí, por lo que se obtiene un error del compilador.
Puede explícitamente convertir puntos de tiempo con diferentes duraciones usando time_point_cast
, por lo que lo siguiente se compilaría en su sistema:
time_point<system_clock, nanoseconds> time_point;
time_point = time_point_cast<nanoseconds>(system_clock::now());
Observe que el parámetro de plantilla explícito para time_point_cast
es el tipo target duration, no el tipo target time_point. Los tipos de reloj deben coincidir en un time_point_cast
, por lo que especificar todo el tipo time_point (que se templa tanto en el tipo de reloj como en el tipo de duración) sería redundante.
Por supuesto en su caso, ya que solo está buscando imprimir el punto de tiempo, no hay necesidad de que esté en una resolución específica, por lo que puede declarar que time_point
es del mismo tipo que lo que system_clock::now()
devuelve para empezar. Una forma sencilla de hacerlo es usar el system_clock::time_point
typedef:
system_clock::time_point time_point;
time_point = system_clock::now(); // no time_point_cast needed
Dado que esto es C++11, también puede usar auto
:
auto time_point = system_clock::now();
Habiendo resuelto este error del compilador, la conversión a time_t
funciona bien:
std::time_t now_c = std::chrono::system_clock::to_time_t(time_point);
Y ahora puede usar métodos estándar para mostrar valores time_t
, como std::ctime
o std::strftime
. (Como Cassio Neri señala en un comentario a su pregunta, la función more C++-y std::put_time
aún no es compatible con GCC).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-04-03 02:52:38
Este fragmento podría ayudarte:
#include <iostream>
#include <chrono>
#include <ctime>
template<typename Clock, typename Duration>
std::ostream &operator<<(std::ostream &stream,
const std::chrono::time_point<Clock, Duration> &time_point) {
const time_t time = Clock::to_time_t(time_point);
#if __GNUC__ > 4 || \
((__GNUC__ == 4) && __GNUC_MINOR__ > 8 && __GNUC_REVISION__ > 1)
// Maybe the put_time will be implemented later?
struct tm tm;
localtime_r(&time, &tm);
return stream << std::put_time(&tm, "%c"); // Print standard date&time
#else
char buffer[26];
ctime_r(&time, buffer);
buffer[24] = '\0'; // Removes the newline that is added
return stream << buffer;
#endif
}
int main() {
std::cout << std::chrono::system_clock::now() << std::endl;
// Wed May 22 14:17:03 2013
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-19 00:45:11
El nanoseconds
parece ser parte del problema, mirando un poco la documentación pude hacer que esto funcionara:
#include <iostream>
#include <chrono>
#include <ctime>
int main(){
//set time_point to current time
std::chrono::time_point<std::chrono::system_clock> time_point;
time_point = std::chrono::system_clock::now();
std::time_t ttp = std::chrono::system_clock::to_time_t(time_point);
std::cout << "time: " << std::ctime(&ttp);
return 0;
}
Aunque parece que std::chrono::microseconds
funciona bien:
std::chrono::time_point<std::chrono::system_clock,std::chrono::microseconds> time_point;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-04-03 07:20:27
Respuesta actualizada para una vieja pregunta:
Para un std::chrono::time_point<std::chrono::system_clock, some-duration>
ahora hay una 3rd bibliotecas de partido que le dan mucho mejor control. Para time_points basados en otros relojes, todavía no hay mejor solución que simplemente obtener la representación interna e imprimirla.
Pero para system_clock
, usando esta biblioteca , esto es tan fácil como:
#include "date.h"
#include <iostream>
int
main()
{
using namespace date;
using namespace std::chrono;
std::cout << system_clock::now() << " UTC\n";
}
Que acaba de salir para mí:
2016-07-19 03:21:01.910626 UTC
Que es la fecha y hora UTC actual con precisión de microsegundos. Si en su plataforma system_clock::time_point
tiene una precisión de nanosegundos, imprimirá una precisión de nanosegundos para usted.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-19 03:25:51
Para cualquiera que trabaje con time_point<steady_clock>
(no time_point<system_clock>
):
#include <chrono>
#include <iostream>
template<std::intmax_t resolution>
std::ostream &operator<<(
std::ostream &stream,
const std::chrono::duration<
std::intmax_t,
std::ratio<std::intmax_t(1), resolution>
> &duration)
{
const std::intmax_t ticks = duration.count();
stream << (ticks / resolution) << '.';
std::intmax_t div = resolution;
std::intmax_t frac = ticks;
for (;;) {
frac %= div;
if (frac == 0) break;
div /= 10;
stream << frac / div;
}
return stream;
}
template<typename Clock, typename Duration>
std::ostream &operator<<(
std::ostream &stream,
const std::chrono::time_point<Clock, Duration> &timepoint)
{
typename Duration::duration ago = timepoint.time_since_epoch();
return stream << ago;
}
int main(){
// print time_point
std::chrono::time_point<std::chrono::steady_clock> now =
std::chrono::steady_clock::now();
std::cout << now << "\n";
// print duration (such as the difference between 2 time_points)
std::chrono::steady_clock::duration age = now - now;
std::cout << age << "\n";
}
El formateador de números decimales no es el más eficiente, pero no necesita un conocimiento previo del número de decimales, que no se conoce si desea que resolution
sea templada, a menos que pueda idear una expresión constante para ceil(log10(resolution))
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-03 16:47:41
La función ctime() no funciona para Visual C++. Uso MS Visual Studio 2013. Cambié el código anterior para usar ctime_s (...), como lo solicita el compilador MSVC. Funcionó.
//set time_point to current time
std::chrono::time_point<std::chrono::system_clock> time_point;
time_point = std::chrono::system_clock::now();
std::time_t ttp = std::chrono::system_clock::to_time_t(time_point);
char chr[50];
errno_t e = ctime_s(chr, 50, &ttp);
if (e) std::cout << "Error." << std::endl;
else std::cout << chr << std::endl;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-09 23:40:35