rusia quien pierde mundial marruecos juega goles españa contra con c++ c date dst

c++ - quien - Cómo agregar un día a un tiempo obtenido a partir del tiempo()



si pierde españa contra rusia (5)

Siempre obtuve el mejor resultado al mantener las marcas de hora UTC y convertirlas a la zona horaria especificada (incluido el horario de verano) cuando desea visualizar los valores.

Esto ahorra muchas molestias como esta (y hace que su programa sea independiente de las zonas horarias.

Tengo un tiempo representado como el número de segundos transcurridos desde la medianoche del 1 de enero de 1970, UTC (los resultados de una llamada anterior al tiempo ()). ¿Cómo agrego un día a esta vez?

Agregar 24 * 60 * 60 funciona en la mayoría de los casos, pero falla si el horario de verano se activa o desactiva en el medio. En otras palabras, principalmente quiero agregar 24 horas, pero a veces 23 o 25 horas.

Para ilustrar: el programa:

#include <time.h> #include <iostream> int main() { time_t base = 1142085600; for(int i = 0; i < 4; ++i) { time_t time = base + i * 24 * 60 * 60; std::cout << ctime(&time); } return 0;

}

Produce:

Sat Mar 11 08:00:00 2006 Sun Mar 12 09:00:00 2006 Mon Mar 13 09:00:00 2006 Tue Mar 14 09:00:00 2006

Quiero que los horarios para el 12, 13 y 13 de marzo también sean las 8 a. M.

La respuesta proporcionada por FigBug me indicó la dirección correcta. Pero tuve que usar localtime en lugar de gmtime.

int main() { time_t base = 1142085600; for(int i = 0; i < 4; ++i) { struct tm* tm = localtime(&base); tm->tm_mday += i; std::cout << asctime(tm); } return 0; }

Dame:

Sat Mar 11 08:00:00 2006 Sat Mar 12 08:00:00 2006 Sat Mar 13 08:00:00 2006 Sat Mar 14 08:00:00 2006

Que es lo que quiero Usar gmtime me da los tiempos a las 14:00:00

Sin embargo, tenga en cuenta que todos los días son sábados. Además, va al 32 de marzo, 33, etc. Si lanzo la función mktime estoy de vuelta donde comencé:

#include <time.h> #include <iostream> int main() { time_t base = 1142085600; for(int i = 0; i < 4; ++i) { struct tm* tm = localtime(&base); tm->tm_mday += i; time_t time = mktime(tm); std::cout << asctime(tm); } return 0; }

Me da:

Sat Mar 11 08:00:00 2006 Sun Mar 12 09:00:00 2006 Mon Mar 13 09:00:00 2006 Tue Mar 14 09:00:00 2006

¿¿¿Qué me estoy perdiendo???

OK, he probado la última sugerencia de FigBug que es usar:

std::cout << ctime(&time);

en lugar de a la hora, pero obtengo los mismos resultados. Así que supongo que mi biblioteca y / o compilador están en mal estado. Estoy usando g ++ 3.4.4 en cygwin. Copié los archivos a Solaris 5.8 y usé g ++ 3.3 para compilar. ¡Obtuve los resultados correctos allí! De hecho, obtengo los resultados correctos ya sea que use ctime o asctime para la salida:

Sat Mar 11 08:00:00 2006 Sun Mar 12 08:00:00 2006 Mon Mar 13 08:00:00 2006 Tue Mar 14 08:00:00 2006

También obtengo los resultados correctos (con ambas funciones de salida) en Red Hut Linux con g ++ 3.4.6.

Así que supongo que me he encontrado con un error de Cygwin.

Gracias por toda su ayuda y consejo ....


Solo agregue 24 * 60 * 60. No debería fallar durante el horario de verano, ya que UTC nunca usará el horario de verano.

Si está fallando, entonces no estás usando UTC en algún lugar de tu código. Eliminar la dependencia de la zona horaria.


use gmtime () para convertir time_t a struct tm

agregar uno al día ( tm_mday )

use mktime () para convertir la estructura tm a un time_t

ver time.h para más información

Editar:

Lo intenté, esto funciona:

int main() { time_t base = 1142085600; for(int i = 0; i < 4; ++i) { struct tm* tm = localtime(&base); tm->tm_mday += i; time_t next = mktime(tm); std::cout << ctime(&next); } return 0; }


La solución de FigBug funcionará casi todo el tiempo, pero necesita corrección DST: tm-> tm_isdst = -1

Un valor positivo o 0 para tm_isdst hace que mktime () suponga inicialmente que el horario de verano, respectivamente, está o no en efecto durante el tiempo especificado. Un valor negativo para tm_isdst hace que mktime () intente determinar si el horario de verano está vigente durante el tiempo especificado.

(citado de la especificación mktime )

int main() { time_t base = 1142085600; for(int i = 0; i < 4; ++i) { struct tm* tm = localtime(&base); tm->tm_mday += i; tm->tm_isdst = -1; // don''t know if DST is in effect, please determine // this for me time_t next = mktime(tm); std::cout << ctime(&next); } return 0; }

De lo contrario, habrá un error (ejemplo del horario de verano de Moscú, que comienza el 29 de marzo de 2009, 01:59:59):

int main() { // 28 March 2009 05:00:00 GMT ( local - 08:00 (MSK) ) time_t base = 1238216400; std::time_t start_date_t = base; std::time_t end_date_t = base; std::tm start_date = *std::localtime(&start_date_t); std::tm end_date = *std::localtime(&end_date_t); end_date.tm_mday += 1; // end_date.tm_isdst = -1; std::time_t b = mktime(&start_date); std::time_t e = mktime(&end_date); std::string start_date_str(ctime(&b)); std::string stop_date_str(ctime(&e)); cout << " begin (MSK) (DST is not active): " << start_date_str; cout << " end (MSD) (DST is active): " << stop_date_str; }

Salida:

begin (MSK) (DST is not active): Sat Mar 28 08:00:00 2009 end (MSD) (DST is active): Sun Mar 29 09:00:00 2009


Nueva respuesta para una pregunta muy antigua.

Justificación de la nueva respuesta: ahora existen mejores herramientas para resolver este problema, lo que hace que el resultado sea menos propenso a errores, más fácil de leer y, en realidad, más eficiente al minimizar las conversiones de campo en serie <->.

La nueva respuesta requiere C ++ 11/14, <chrono> y esta biblioteca de zona horaria gratuita y de código abierto .

Aquí está el código:

#include "tz.h" #include <iostream> int main() { using namespace std::chrono; using namespace date; auto base = make_zoned("Pacific/Easter", sys_seconds{1142085600s}); for (int i = 0; i < 4; ++i) { std::cout << format("%a %b %d %T %Y %Z", base) << ''/n''; base = base.get_local_time() + days{1}; } }

Para comenzar, crea un zoned_time emparejando la zona horaria deseada con la marca de tiempo de Unix Time.

Eso está formateado en cualquiera que sea el formato deseado.

Y la adición de 1 día se realiza en el sistema horario local de la zona horaria, que tendrá en cuenta los ahorros de luz diurna. El resultado es:

Sat Mar 11 09:00:00 2006 -05 Sun Mar 12 09:00:00 2006 -06 Mon Mar 13 09:00:00 2006 -06 Tue Mar 14 09:00:00 2006 -06

Como resultado, esta salida no es exactamente lo que el PO declaró que deseaba (la salida solicitada es a las 08:00:00 todos los días). Sin embargo, utilicé esta biblioteca para investigar completamente las transiciones de tiempo de todo el planeta en esta fecha. Y solo hay una zona horaria que tuvo una transición en esta fecha: Pacífico / Semana Santa. Y esa transición fue retroceder una hora, no avanzar . Esta es la zona horaria utilizada para Chile, en el hemisferio sur, donde uno retrocede en el marco de tiempo de marzo.

Esto puede demostrarse haciendo la aritmética en UTC en lugar de la hora local. Este es un pequeño ajuste al programa anterior en una línea:

base = base.get_sys_time() + days{1};

El uso de base.get_sys_time() , a diferencia de base.get_local_time() , hace que la aritmética se realice en "hora del sistema", que es UTC descuidando los segundos intercalares. Y ahora el resultado cambia a:

Sat Mar 11 09:00:00 2006 -05 Sun Mar 12 08:00:00 2006 -06 Mon Mar 13 08:00:00 2006 -06 Tue Mar 14 08:00:00 2006 -06