Mudanças entre as edições de "FuncoesDeTempoNoC"
(7 revisões intermediárias pelo mesmo usuário não estão sendo mostradas) | |||
Linha 16: | Linha 16: | ||
Entretanto, a biblioteca [https://www.gnu.org/software/libc/manual/html_node/Date-and-Time.html#Date-and-Time glibc] da GNU já apresenta uma série de definições e funções sobre o tempo. É importante conhecê-las pois facilitarão o desenvolvimento dos programs no sentido que permitirão rapidamente ler a hora e data do sistema, computar intervalos de tempo, entre outras possibilidades. | Entretanto, a biblioteca [https://www.gnu.org/software/libc/manual/html_node/Date-and-Time.html#Date-and-Time glibc] da GNU já apresenta uma série de definições e funções sobre o tempo. É importante conhecê-las pois facilitarão o desenvolvimento dos programs no sentido que permitirão rapidamente ler a hora e data do sistema, computar intervalos de tempo, entre outras possibilidades. | ||
− | =A struct tm e | + | =A struct tm e o tipo (inteiro) time_t que representa o tempo= |
A struct tm, conforme [http://man7.org/linux/man-pages/man3/ctime.3.html manual] do linux possui a seguinte estrutura: | A struct tm, conforme [http://man7.org/linux/man-pages/man3/ctime.3.html manual] do linux possui a seguinte estrutura: | ||
Linha 35: | Linha 35: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
− | Esta estrutura permite representar a data/hora calendário que um ser humano consegue facilmente entender e utilizar. | + | Esta estrutura permite representar a data/hora calendário que um ser humano (programador em C :-) consegue facilmente entender e utilizar. |
Por questões de otimização esta não é a melhor forma de representar o tempo em um sistema computacional. Também não é apropriada para representar intervalos de tempo. Desta forma, a biblioteca apresenta a definição ''time_t'' que possui uma estrutura adequada para o sistema computacional operar. Na prática é um tipo inteiro que representa o número de segundos desde 1 de Janeiro de 1970. | Por questões de otimização esta não é a melhor forma de representar o tempo em um sistema computacional. Também não é apropriada para representar intervalos de tempo. Desta forma, a biblioteca apresenta a definição ''time_t'' que possui uma estrutura adequada para o sistema computacional operar. Na prática é um tipo inteiro que representa o número de segundos desde 1 de Janeiro de 1970. | ||
− | Vamos | + | Vamos um exemplo mostrando como capturar o tempo do sistema: |
<syntaxhighlight lang=c> | <syntaxhighlight lang=c> | ||
Linha 60: | Linha 60: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
+ | Note que tempo lido do sistema através da função ''time()'' está na forma de segundos desde 1970 (um valor inteiro). | ||
+ | Este tempo é então convertido para uma struct tm que pode ser manipulado pelas granularidades ano, mês etc. | ||
− | + | ==Comparando tempo de eventos== | |
+ | |||
+ | Suponha que para registrar eventos em uma agenda, foi decidido usar o ''time_t''. A comparação se torna bastante simples. Vamos a um exemplo: | ||
+ | |||
+ | <syntaxhighlight lang=c> | ||
+ | #include <stdio.h> | ||
+ | #include <time.h> | ||
+ | |||
+ | struct tipo_evento{ | ||
+ | int tipo_evento; /* 0 - reunião, 1-aula, 2-consulta médica */ | ||
+ | struct tm data; | ||
+ | }; | ||
+ | |||
+ | main() | ||
+ | { | ||
+ | struct tipo_evento evento1 = {0, {0,0,15,29,10,2018-1900}}; /* evento em 29/11/2018 15h */ | ||
+ | struct tipo_evento evento2 = {1, {0,0,15,23,10,2018-1900}}; /* evento em 23/11/2018 15h */ | ||
+ | |||
+ | time_t aux1,aux2; | ||
+ | |||
+ | aux1=mktime(&evento1.data); /* converte uma data na forma struct tm para time_t */ | ||
+ | aux2=mktime(&evento2.data); /* converte uma data na forma struct tm para time_t */ | ||
+ | |||
+ | if (aux1>aux2) { | ||
+ | printf("evento 1 mais recente que evento 2\n"); | ||
+ | } else { | ||
+ | printf("evento 1 antecede ou está na mesma data do evento 2\n"); | ||
+ | } | ||
+ | |||
+ | /* vamos mudar o mês do evento 1 para um valor anterior ao evento 2 */ | ||
+ | evento1.data.tm_mon = 9; | ||
+ | aux1=mktime(&evento1.data); /* tem que converter de novo... */ | ||
+ | |||
+ | if (aux1>aux2) { | ||
+ | printf("evento 1 mais recente que evento 2\n"); | ||
+ | } else { | ||
+ | printf("evento 1 antecede ou está na mesma data do evento 2\n"); | ||
+ | } | ||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | =Fazendo entrada de dados de forma temporizada= | ||
+ | |||
+ | <syntaxhighlight lang=c> | ||
+ | #include <stdio.h> | ||
+ | #include <sys/time.h> | ||
+ | |||
+ | /* | ||
+ | código adaptado de: | ||
+ | https://www.unix.com/programming/16678-how-get-timed-input-using-cin.html | ||
+ | */ | ||
+ | |||
+ | int ler_val(int tempo, int *valor) | ||
+ | { | ||
+ | fd_set fdset; | ||
+ | struct timeval timeout; | ||
+ | int rc; | ||
+ | int erro; | ||
+ | |||
+ | timeout.tv_sec = tempo; /* espera "tempo" segundos */ | ||
+ | timeout.tv_usec = 0; | ||
+ | |||
+ | |||
+ | FD_ZERO(&fdset); | ||
+ | |||
+ | FD_SET(0, &fdset); | ||
+ | |||
+ | rc = select(1, &fdset, NULL, NULL, &timeout); | ||
+ | if (rc == -1) /* falha no select */ | ||
+ | { | ||
+ | erro = -1; | ||
+ | } | ||
+ | else if (rc == 0) /* tempo esgotado */ | ||
+ | { | ||
+ | erro=-2; | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | if (FD_ISSET(0, &fdset)) | ||
+ | { | ||
+ | erro=0; | ||
+ | scanf("%d", valor); | ||
+ | } | ||
+ | } | ||
+ | return erro; | ||
+ | } | ||
+ | |||
+ | main() | ||
+ | { | ||
+ | int x,y; | ||
+ | |||
+ | if (ler_val(5,&x)==0) | ||
+ | printf("valor lido para x = %d\n", x); | ||
+ | else | ||
+ | printf("esgotado o tempo para ler x\n"); | ||
+ | if (ler_val(5,&y)==0) | ||
+ | printf("valor lido para y = %d\n", y); | ||
+ | else | ||
+ | printf("esgotado o tempo para ler y\n"); | ||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | =Referências= | ||
+ | |||
+ | http://www.catb.org/esr/time-programming/#_good_programming_practice |
Edição atual tal como às 10h50min de 23 de novembro de 2018
Introdução
Em vários projetos de desenvolvimento surge a necessidade de representar data e hora. Por exemplo, um evento em uma agenda eletrônica deve ter associado a ele uma data e hora do momento em que este evento acontece. É natural que se pense ema representação na forma de uma struct:
struct data_hora {
int ano,
mes,
dia,
hora,
minuto,
segundo
};
Entretanto, a biblioteca glibc da GNU já apresenta uma série de definições e funções sobre o tempo. É importante conhecê-las pois facilitarão o desenvolvimento dos programs no sentido que permitirão rapidamente ler a hora e data do sistema, computar intervalos de tempo, entre outras possibilidades.
A struct tm e o tipo (inteiro) time_t que representa o tempo
A struct tm, conforme manual do linux possui a seguinte estrutura:
/* definida em time.h - NÃO é necessário redefinir no seu código*/
struct tm {
int tm_sec; /* segundos (0-60) */
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 (0-11) */
int tm_year; /* ano - 1900 */
int tm_wday; /* dia da semana (0-6, Domingo = 0) */
int tm_yday; /* dia do ano (0-365, 1 Jan = 0) */
int tm_isdst; /* flag de horário de verão (HV): 1-se é HV, 0-não é HV, -1 se não existe esta informação */
};
Esta estrutura permite representar a data/hora calendário que um ser humano (programador em C :-) consegue facilmente entender e utilizar.
Por questões de otimização esta não é a melhor forma de representar o tempo em um sistema computacional. Também não é apropriada para representar intervalos de tempo. Desta forma, a biblioteca apresenta a definição time_t que possui uma estrutura adequada para o sistema computacional operar. Na prática é um tipo inteiro que representa o número de segundos desde 1 de Janeiro de 1970.
Vamos um exemplo mostrando como capturar o tempo do sistema:
#include <stdio.h>
#include <time.h>
main()
{
struct tm *minha_data;
time_t data_hora;
time(&data_hora); /* ler do sistema a data_hora em segundos desde 1 de janeiro de 1970 */
printf ("data hora em segundos desde 1970: %ld\n", data_hora);
minha_data = localtime(&data_hora); /* convert de data representada em time_t para data em struct tm */
printf("Ano %d Mês %d Dia %d Hora %d Minuto %d\n", minha_data->tm_year, minha_data->tm_mon, minha_data->tm_mday, minha_data->tm_hour, minha_data->tm_min);
}
Note que tempo lido do sistema através da função time() está na forma de segundos desde 1970 (um valor inteiro). Este tempo é então convertido para uma struct tm que pode ser manipulado pelas granularidades ano, mês etc.
Comparando tempo de eventos
Suponha que para registrar eventos em uma agenda, foi decidido usar o time_t. A comparação se torna bastante simples. Vamos a um exemplo:
#include <stdio.h>
#include <time.h>
struct tipo_evento{
int tipo_evento; /* 0 - reunião, 1-aula, 2-consulta médica */
struct tm data;
};
main()
{
struct tipo_evento evento1 = {0, {0,0,15,29,10,2018-1900}}; /* evento em 29/11/2018 15h */
struct tipo_evento evento2 = {1, {0,0,15,23,10,2018-1900}}; /* evento em 23/11/2018 15h */
time_t aux1,aux2;
aux1=mktime(&evento1.data); /* converte uma data na forma struct tm para time_t */
aux2=mktime(&evento2.data); /* converte uma data na forma struct tm para time_t */
if (aux1>aux2) {
printf("evento 1 mais recente que evento 2\n");
} else {
printf("evento 1 antecede ou está na mesma data do evento 2\n");
}
/* vamos mudar o mês do evento 1 para um valor anterior ao evento 2 */
evento1.data.tm_mon = 9;
aux1=mktime(&evento1.data); /* tem que converter de novo... */
if (aux1>aux2) {
printf("evento 1 mais recente que evento 2\n");
} else {
printf("evento 1 antecede ou está na mesma data do evento 2\n");
}
}
Fazendo entrada de dados de forma temporizada
#include <stdio.h>
#include <sys/time.h>
/*
código adaptado de:
https://www.unix.com/programming/16678-how-get-timed-input-using-cin.html
*/
int ler_val(int tempo, int *valor)
{
fd_set fdset;
struct timeval timeout;
int rc;
int erro;
timeout.tv_sec = tempo; /* espera "tempo" segundos */
timeout.tv_usec = 0;
FD_ZERO(&fdset);
FD_SET(0, &fdset);
rc = select(1, &fdset, NULL, NULL, &timeout);
if (rc == -1) /* falha no select */
{
erro = -1;
}
else if (rc == 0) /* tempo esgotado */
{
erro=-2;
}
else
{
if (FD_ISSET(0, &fdset))
{
erro=0;
scanf("%d", valor);
}
}
return erro;
}
main()
{
int x,y;
if (ler_val(5,&x)==0)
printf("valor lido para x = %d\n", x);
else
printf("esgotado o tempo para ler x\n");
if (ler_val(5,&y)==0)
printf("valor lido para y = %d\n", y);
else
printf("esgotado o tempo para ler y\n");
}
Referências
http://www.catb.org/esr/time-programming/#_good_programming_practice