Visualizzazione dei risultati da 1 a 7 su 7

Discussione: [C++] timediff

  1. #1

    [C++] timediff

    Salve,

    volevo sapere come fare operazioni sul timestamp per vedere quando tempo dista tra due momenti, ad esempio da quando è stato lanciato un thread ad ora. Mi piacerebbe che ritornasse una stringa tipo: hh:mm:ss che identificasse l'uptime.

    Mettiamo che ho una struttura del genere:
    codice:
    enum { MAXCHAR = 128; };
    
    struct user
    {
    	char szUserAgent[MAXCHAR];
    	char timestamp // inventato
    }
    che uso in una mappa del genere:
    codice:
    // Global
    std::map<int, user> row;
    CRITICAL_SECTION row_mutex;     // avrò poi un'altro thread
    				// che legge la mappa ogni sec.
    Lancio un nuovo thread:
    codice:
    {
    	int threadid = (int)GetCurrentThreadId();
    
    	user u = { _T("marameo/1.0"), now() }; // now() inventato
    
    	EnterCriticalSection(&row_mutex);
    	row.insert( std::make_pair(threadid, u) );
    	LeaveCriticalSection(&row_mutex);
    }
    Ora mi piacerebbe che nel thread dedicato alla lettura mi visualizzasse non solo i due campio ma anche un terzo campo creato sul momento che altro non è che la differenza tra now() e user.timestamp:

    codice:
    {
    	while(1)
    	{
    		if(stopThreadFlag)
    			break;
    
    		std::map<int, user>::iterator itt;
    
    		EnterCriticalSection(&row_mutex);
    		for(itt=row.begin(); itt!=row.end(); ++itt)
    		{
    			std::cout << " User: " << itt.second.szUserAgent;
    			std::cout << " Timestamp: " << itt.second.timestamp;
    			std::cout << " Up Time: " << ( now() - itt.second.timestamp );
    		}
    		LeaveCriticalSection(&row_mutex);
    
    		Sleep(1000);
    
    	}
    }
    Ora certe cose le ho messe solo per rendere l'idea..ma si può fare cmq?

    grazie
    Alla batteria dai retta ballA

  2. #2
    Ok, ho studiato un pò la <ctime> ed ho scritto questo piccolo codice che nin funziona come mi aspettavo:

    codice:
    #include <windows.h>
    #include <ctime>
    #include <cstdlib>
    #include <iostream>
    
    int main()
    {
    	time_t start = time(NULL);
    	{
    		struct tm timeinfo;
    		memset(&timeinfo, 0, sizeof(timeinfo));
    
    		localtime_s(&timeinfo, &start);
    
    		char szTime[30] = {0};
    		strftime(szTime, 30, "%X", &timeinfo);
    		std::cout << "Start: " << szTime << std::endl;
    	}
    
    	Sleep(2000);
    
    	time_t end = time(NULL);
    	{
    		struct tm timeinfo;
    		memset(&timeinfo, 0, sizeof(timeinfo));
    
    		time_t dif = (time_t)difftime(end, start);
    
    		localtime_s(&timeinfo, &dif);
    
    		char szTime[30] = {0};
    		strftime(szTime, 30, "%X", &timeinfo);
    		std::cout << "End, time elapsed is: " << szTime << std::endl;
    	}
    
    	system("pause");
    	return EXIT_SUCCESS;
    }
    In pratica passano 2 secondi tra il primo blocco ed il secondo, ma il time elapsed indica 01:00:02 ovvero un'ora e due secondi...dov'è che sbaglio? inoltre sono stato costretto a fare il cast in: time_t dif = (time_t)difftime(end, start); perchè la funziona ritorna solo double...ho fatto bene?

    grazie
    Alla batteria dai retta ballA

  3. #3
    La funzione difftime non restituisce un double a caso: il valore restituito infatti è il numero di secondi di differenza. Ora, se tu li converti in un time_t, questi vengono interpretati come numero di secondi passati dalla mezzanotte dell'1/1/1970, per cui se il tempo trascorso è inferiore al mese ( ) dovresti poterlo convertire in un tm o in una stringa con le apposite funzioni di data/ora senza problemi (per quanto sia un po' un abuso di queste funzioni). Il punto però è che devi usare la gamma le funzioni UTC, non quelle locali, altrimenti vengono applicate le correzioni per l'ora legale e i fusi orari. In sostanza, invece di usare localtime usa gmtime.
    Amaro C++, il gusto pieno dell'undefined behavior.

  4. #4
    gmtime_s va un'ora indietro. mentre localtime_s mi ritorna l'ora esatta sul mio computer.

    BTW, quali sarebbero le apposite funzioni di data/ora?

    grazie
    Alla batteria dai retta ballA

  5. #5
    Originariamente inviato da gianvituzzi
    gmtime_s va un'ora indietro. mentre localtime_s mi ritorna l'ora esatta sul mio computer.
    gmtime ti restituisce l'ora UTC, infatti. Ma se stai usando un time_t "finto" (di fatto una differenza di tempo, e non davvero il numero di secondi trascorso da eccetera eccetera) per ottenere valori sensati devi usare gmtime.
    BTW, quali sarebbero le apposite funzioni di data/ora?
    Non mi pare che vengano fornite funzioni per gestire le differenze di data/ora. In effetti la libreria C per quanto riguarda le funzioni per data e ora è abbastanza pessima (sotto numerosi aspetti).
    Amaro C++, il gusto pieno dell'undefined behavior.

  6. #6
    ok, ho trovato un modo da un vecchio script perl:

    codice:
    #include <windows.h>
    #include <ctime>
    #include <cstdlib>
    #include <iostream>
    
    int main()
    {
    	time_t start = 1266413283;
    	{
    		struct tm timeinfo;
    		memset(&timeinfo, 0, sizeof(timeinfo));
    
    		gmtime_s(&timeinfo, &start);
    
    		char szTime[30] = {0};
    		strftime(szTime, 30, "%X", &timeinfo);
    		std::cout << "Start: " << szTime << " time: " << start << std::endl;
    	}
    
    	time_t end = time(NULL);
    	{
    		struct tm timeinfo;
    		memset(&timeinfo, 0, sizeof(timeinfo));
    
    		double dif = difftime(end, start);
    
    		int seconds = (int)dif % 60;
    		int minutes = ( ((int)dif - seconds) % (60*60) ) / 60;
    		int hours   = (seconds - minutes * 60 - (int)dif) / (60*60);
    
    		char szElapsedTime[30] = {0};
    		sprintf_s(szElapsedTime, 30, "%02d:%02d:%02d", hours, minutes, seconds);
    
    		std::cout << szElapsedTime << std::endl;
    	}
    
    	system("pause");
    	return EXIT_SUCCESS;
    }
    per adattarlo devo cmq fare cast (int) su: double dif = difftime(end, start);

    funziona bene...
    Alla batteria dai retta ballA

  7. #7
    funziona meglio questa sicuramente:

    Codice PHP:
    void strDiffTime(char szElapsedTime, const time_t start)
    {
        
    // Ritorna quanto tempo è passato da start a now()
        // Necessita <ctime> e <cmath>
        //
        
    time_t end time(NULL);
        
    struct tm timeinfo;
        
    memset(&timeinfo0sizeof(timeinfo));

        
    double dif difftime(endstart);

        
    int seconds int(floor(difftime(endstart)));
        
    int hours seconds 3600;
        
    seconds -= hours 3600;
        
    int minutes seconds 60;
        
    seconds -= minutes 60;

        if(
    hours>0)
        {
            
    sprintf_s(szElapsedTime30"%d Hour, %d Min, %d Sec"hoursminutesseconds);
        } else if(
    minutes>0) {
            
    sprintf_s(szElapsedTime30"%d Min, %d Sec"minutesseconds);
        } else {
            
    sprintf_s(szElapsedTime30"%d Sec"seconds);
        }

    Alla batteria dai retta ballA

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.