time.h – Manipulando o tempo
Publicado por B i f e em Abril 16, 2008
Linguagem: C.
Sistema: GNU/Linux.
Não sei se vocês, assim como eu, também gostam de saber como a coisa funciona por baixo dos panos. Por incrível que pareça, é mais simples do que eu pensei. =D
Pretendo explorar outros arquivos de cabeçalho também, porém decidi começar com este por se tratar de um assunto interessante, a manipulação do tempo.
É claro que eu não me aprofundei demais no assunto. Pra falar a verdade é apenas uma pequena tradução das referências, encontradas no final do artigo. Não se esqueça que as man-pages são tuas amigas. Mãos na massa. =P
Tipos importantes
Para armazenar o tempo, são definidos alguns tipos de dados e estruturas no arquivo de cabeçalho time.h. São estes:
time_t : Um inteiro com sinal (32 ou 64 bits) que armazena o número de segundos desde a criação do Unix: meia-noite de 1 de Janeiro de 1970 UTC (com exceção dos segundos bissextos).
struct tm : Contém a data e hora separados em 9 campos do tipo int:
struct tm {
int tm_sec; /* Segundos, 0-59*/
int tm_min; /* Minutos, 0-59*/
int tm_hour; /*Horas 0-23 */
int tm_mday; /*dia do mês, 1-31 */
int tm_mon; /* mês a partir de janeiro, 0-11 */
int tm_year; /* anos a partir de 1900 */
int tm_wday; /* dias a partir de domingo, 0-6 */
int tm_yday; /* dias a partir de 1 de janeiro 1-365 */
int tm_isdst; /* Indicador de horário de verão */
}
clock_t : Este tipo é capaz de armazenar “ciclos de máquina” e suporta cálculos aritméticos. Muito útil em conjunto com a macro CLOCKS_PER_SEC.
CLOCKS_PER_SEC : Na verdade, este não é um tipo de dados, mas sim uma macro que armazena quantos ciclos de máquina são necessários para atingir 1 segundo.
As funções
Finalmente chegamos na parte legal. =D
Para melhor organização, separei esta seção em 2 tipos de funções com objetivos parecidos: manipulação de tempo e conversão de tipos.
Manipulação de tempo
time
time_t time( time_t *timer);
Pega a hora atual do sistema e a armazena numa variável do tipo time_t, passada como parâmetro. Se você passar um ponteiro nulo (NULL), ela retorna o valor. Caso aconteça algum problema, o valor de retorno será -1.
Exemplo:
#include <stdio.h>
#include <time.h>
int main(void)
{
time_t segundos;
segundos= time(NULL);
printf("%ld horas desde 1 de Janeiro de 1970.\n", segundos/3600);
return 0;
}
mktime
time_t mktime( struct tm *timeptr);
Converte uma estrutura tm para time_t. Ao alterar um dos campos da estrutura, todos os outros são devidamente alterados para o seu valor correto, equivalente ao novo campo. O valor retornado é um time_t referente a estrutura. Em caso de problemas, será retornado o valor -1.
Exemplo:
/*
Le uma data e imprime o dia da semana referente a mesma.
Foi usada a funcao localtime(), ela converte um valor time_t em
uma estrutura tm. Falaremos dela mais tarde.
*/
#include <stdio.h>
#include <time.h>
int main(void)
{
time_t currentTime;
struct tm *timeinfo;
int dia, mes, ano;
char *diaSemana[]= { "Domingo", "Segunda", "Terca", "Quarta", "Quinta", "Sexta", "Sabado" };
/* Le uma data para verificar o dia da semana correspondente a ela.*/
printf("Dia: ");
scanf("%d",&dia);
printf("Mes: ");
scanf("%d",&mes);
printf("Ano: ");
scanf("%d",&ano);
/* Pega a hora atual do sistema e a converte em uma estrutura tm. */
time(¤tTime);
timeinfo= localtime(¤tTime);
/* Atualiza os valores dia, mes e ano da estrutura. */
timeinfo->tm_mday= dia;
timeinfo->tm_mon= mes - 1;
timeinfo->tm_year= ano - 1900;
/* Atraves da funcao mktime(), atualiza os outros campos da estrutura de acordo
com os atualizados anteriormente. */
mktime(timeinfo);
/* Imprime o dia da semana. */
printf("%02d/%02d/%d foi %s.\n", dia, mes, ano, diaSemana[timeinfo->tm_wday]);
return 0;
}
clock
clock_t clock(void);
Retorna quantos ciclos de máquina se passaram desde o início do programa. Muito útil em conjunto com a macro CLOCKS_PER_SEC. Retorna -1 em caso de erros.
Exemplo:
#include <stdio.h>
#include <time.h>
void esperar(int segundos);
int main(void)
{
int x;
/* Conta ate 3. */
printf("Eu sei contar!! Veja:\n");
for (x=1;x<=3;x++){
printf("%d\n",x);
esperar(1); /* Espera 1 segundo ate ir para o proximo numero. */
}
return 0;
}
void esperar(int segundos)
{
clock_t cicloFinal;
cicloFinal= clock() + segundos * CLOCKS_PER_SEC; /* Calcula o ciclo final de acordo com os segundos passados. */
while (clock() < cicloFinal); /* Para quando o ciclo final e atingido. */
}
difftime
double difftime(time_t time1, time_t time2);
Calcula a diferença de segundos entre dois tempos.
Exemplo:
#include <stdio.h>
#include <time.h>
#include <string.h>
int main(void)
{
time_t inicio, fim;
char nome[51];
inicio= time(NULL);
printf("Digite seu nome: ");
fgets(nome, 51, stdin);
fim= time(NULL);
nome[strlen(nome)-1]= '';
printf("\n%s, voce demorou %.2f segundos para digitar seu nome.\n", nome, difftime(inicio,fim) * (-1));
return 0;
}
stime
int stime(time_t *timer);
Altera a hora local do sistema para a correspondente ao valor do ponteiro timer. Retorna 0 em caso de sucesso e -1 em caso de algum erro. Só pode ser executada pelo usuário root.
Exemplo:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void)
{
time_t currentTime, newTime;
struct tm *timeinfo;
int hours, minutes;
/* Le nova hora e minutos. */
printf("Horas: ");
scanf("%d",&hours);
printf("Minutos: ");
scanf("%d",&minutes);
/* Obtem a hora atual. */
currentTime= time(NULL);
timeinfo= localtime(¤tTime);
/* Altera a estrutura para a nova hora. */
timeinfo->tm_hour= hours;
timeinfo->tm_min= minutes;
/* Transforma a estrutura em um time_t. */
if ((newTime= mktime(timeinfo)) < 0){
fprintf(stderr,"\n**ERRO ao converter struct tm* para time_t.**\n");
exit(1);
}
else{
if (stime(&newTime) < 0){ /* Seta a nova hora local. */
fprintf(stderr,"\n**ERRO ao setar nova hora local.**\n");
fprintf(stderr,"Provavelmente voce nao possui permissao para alterar a hora.\n");
fprintf(stderr,"Tente como usuario root.\n");
exit(1);
}
}
/* Obtem novamente a hora local para mostra-la na saida padrao. */
currentTime= time(NULL);
timeinfo= localtime(¤tTime);
hours= timeinfo->tm_hour;
minutes= timeinfo->tm_min;
printf("Nova hora local: %02d:%02d\n",hours,minutes);
return 0;
}
Conversão de tipos
localtime
struct tm *localtime( time_t *timer);
Converte um valor do tipo time_t em uma estrutura tm. A estrutura é alocada estáticamente e compartilhada pelas funções localtime() e gmtime().
Exemplo:
#include <stdio.h>
#include <time.h>
int main(void)
{
time_t currentTime;
struct tm *timeinfo;
/* Pega a hora atual do sistema. */
currentTime= time(NULL);
/* Converte-o em uma estrutura tm. */
timeinfo= localtime(¤tTime);
/* Apresenta a hora atual no formato horas:minutos:segundos */
printf("Hora atual: %02d:%02d:%02d\n", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);
return 0;
}
asctime
char *asctime (const struct *tm timeptr);
Converte uma estrutura do tipo tm em uma string com o seguinte formato:
Www Mmm dd hh:mm:ss yyyy
Onde Www é o dia da semana, Mmm é o mês, dd é o dia do mês, hh:mm:ss é a hora local e yyyy é o ano. A string é terminada com um caractere de nova linha (\n) seguido de um caractere nulo.
Exemplo:
#include <stdio.h>
#include <time.h>
int main(void)
{
time_t currentTime;
struct tm *timeInfo;
/* Pega a hora atual do sistema e converte-a em uma estrutura tm. */
currentTime= time(NULL);
timeInfo= localtime(¤tTime);
/* Converte a estrutura em uma string e imprime a mesma. */
printf("%s", asctime(timeInfo));
return 0;
}
gmtime
struct tm *gmtime(const time_t *timer);
Constrói uma estrutura do tipo tm a partir do valor passado como parâmetro. A diferença está no formato, que será expressado em UTC ou GMT. Ótima para construir tabelas de fuso-horários.
Exemplo:
#include <stdio.h>
#include <time.h>
#define BRAZIL (-3)
#define CHINA (+8)
int main(void)
{
time_t currentTime;
struct tm *utcTime;
currentTime= time(NULL);
/* Converte a hora atual para UTC. */
utcTime= gmtime(¤tTime);
/* Imprime os fuso-horarios do Brasil e China. */
printf("Brazil: %02d:%02d:%02d\n", (utcTime->tm_hour+BRAZIL)%24, utcTime->tm_min, utcTime->tm_sec);
printf("China: %02d:%02d:%02d\n", (utcTime->tm_hour+CHINA)%24, utcTime->tm_min, utcTime->tm_sec);
return 0;
}
ctime
char *ctime( const time_t *timer);
Esta função é equivalente à asctime().
strftime
size_t strftime( char *ptr, size_t maxsize, const char *format, const struct tm *timeptr);
Copia na string ptr o conteúdo de format, interpreta algumas tags de formato similares as da função printf() de acordo com a estrutura timeptr, com o limite de maxsize caracteres. Pra falar a verdade esta função é extremamente parecida com a função sprintf(). Você vai escrever em uma string utilizando alguns códigos de formato a mais.
Uma lista com todos os códigos pode ser encontrada aqui.
Exemplo:
#include <stdio.h>
#include <time.h>
int main(void)
{
time_t currentTime;
struct tm *timeinfo;
char stringTime[51];
currentTime= time(NULL);
timeinfo= localtime(¤tTime);
/* Cria a string com os codigos de fomatacao no formato:
dia/mes/ano -- hora:minuto:segundo AM/PM. */
strftime(stringTime, 51, "%d/%m/%Y -- %H:%M:%S %p", timeinfo);
/* Imprime a string formatada. */
printf("%s\n",stringTime);
return 0;
}
Ufa! =P
Finalmente.
Obrigado a todos. Não se esqueçam de comentar, é muito importante para o crescimento do blog.
Abraços.
Referências
http://www.cplusplus.com/
http://www.cppreference.com/index.html
http://linux.about.com/library/cmd/blcmdl2_stime.htm
http://www.vivaolinux.com.br/dicas/verDica.php?codigo=1008
Mauricio disse
Muito bom ! Aprendi bastante .
ravi disse
ei brother.
Vlw cara vc ajudou bastante.
luz
Felipe disse
ótimo, mas como faz deixar o tempo correndo enquanto o programa roda?
Felipe disse
Thank you!
great post!
Alan disse
Otimo post!!!
vai ajudar e mto a minha vida..>!! parabens!!
Helkier disse
Cara, otimo post eim…
Isso vai me quebrar um galhão, pois eu já tava doido…
Agora sim consigo manipular o tempo do jeito que eu quiser, assim termino meu projeto mais rápido!
Meus Parabens!! :D
Jo_Spider disse
Como faço para receber a horas, somalas e depois calcular a diferença entre elas?????????????
Agradeço a ájuda!!!
:D
André disse
cara, sou um zero à esquerda em programção, to tentando aprender sozinho.
mas o que eu queria era o seguinte, perguntar a data de nascimento e armazenar numa variavel.
depois pegar a data atual e subtrair da data que foi armazenada, descobrindo assim quantos dias a pessoa viveu.
se puderem me ajudar agradeço: andreluis.felizardo@hotmail.com
abraços
walter disse
obrigadão irmão!!!!
Marco Antonio Arruda disse
Cara, muito bomo seu blog
tá de parabens
eu só não entendi o while do void esperar()
com ‘;’ no final, nunca tinha visto assim