Como Fazer Cálculos e Formatação de Data no Linux
Aprenda a como fazer calculos para dias passados e futuros usando o comando date do Linux.
Aprenda também a como fazer para formatar a data para ser exibida em seus scripts baseados em shell.
Formatando a data
Por padrão quando você executa o comando date no linux terá o seguinte resultado.
# date Fri Apr 29 21:17:46 BRT 2011
Porém muitas vezes esse formato não é o mais adequado para um shell script, sendo assim você pode personalizar a forma como a data será exibida, vamos a alguns exemplos:
# date "+Data: %d/%m/%Y%nHora: %H:%M:%S"
Data: 29/04/2011
Hora: 21:18:34
# date "+Data: %d/%m/%Y%tHora: %H:%M:%S"
Data: 29/04/2011 Hora: 21:19:03
# date "+%t##### Data: %d/%m/%Y%t ##### %tHora: %H:%M:%S #####"
##### Data: 29/04/2011 ##### Hora: 21:20:15 #####
Você deve usar o comanda date com o sinal de +.
date [+FORMAT]
Abaixo você verá a lista de todas as opções de formatação, mais informações podem ser obtidas usando o man do programa date.
%% a literal %
%a locale's abbreviated weekday name (e.g., Sun)
%A locale's full weekday name (e.g., Sunday)
%b locale's abbreviated month name (e.g., Jan)
%B locale's full month name (e.g., January)
%c locale's date and time (e.g., Thu Mar 3 23:05:25 2005)
%C century; like %Y, except omit last two digits (e.g., 21)
%d day of month (e.g, 01)
%D date; same as %m/%d/%y
%e day of month, space padded; same as %_d
%F full date; same as %Y-%m-%d
%g last two digits of year of ISO week number (see %G)
%G year of ISO week number (see %V); normally useful only with %V
%h same as %b
%H hour (00..23)
%I hour (01..12)
%j day of year (001..366)
%k hour ( 0..23)
%l hour ( 1..12)
%m month (01..12)
%M minute (00..59)
%n a newline
%N nanoseconds (000000000..999999999)
%p localeâs equivalent of either AM or PM; blank if not known
%P like %p, but lower case
%r localeâs 12-hour clock time (e.g., 11:11:04 PM)
%R 24-hour hour and minute; same as %H:%M
%s seconds since 1970-01-01 00:00:00 UTC
%S second (00..60)
%t a tab
%T time; same as %H:%M:%S
%u day of week (1..7); 1 is Monday
%U week number of year, with Sunday as first day of week (00..53)
%V ISO week number, with Monday as first day of week (01..53)
%w day of week (0..6); 0 is Sunday
%W week number of year, with Monday as first day of week (00..53)
%x localeâs date representation (e.g., 12/31/99)
%X localeâs time representation (e.g., 23:13:48)
%y last two digits of year (00..99)
%Y year
%z +hhmm numeric timezone (e.g., -0400)
%:z +hh:mm numeric timezone (e.g., -04:00)
%::z +hh:mm:ss numeric time zone (e.g., -04:00:00)
%:::z numeric time zone with : to necessary precision (e.g., -04, +05:30)
%Z alphabetic time zone abbreviation (e.g., EDT)
By default, date pads numeric fields with zeroes. The following optional flags may follow '%':
- (hyphen) do not pad the field
_ (underscore) pad with spaces
0 (zero) pad with zeros
^ use upper case if possible
# use opposite case if possible
Cálculos com a data no Linux
Datas do passado
Aqui vamos mostrar como fazer o calculo para achar um data no passado, podemos subtrair o dia, o mês ou o ano.
# date --date='1 day ago' Thu Apr 28 21:23:52 BRT 2011 # date --date='1 month ago' Tue Mar 29 21:24:19 BRT 2011 # date --date='1 year ago' Thu Apr 29 21:24:37 BRT 2010
Data futura
Da mesma forma podemos fazer cálculos para datas futuras.
# date --date='1 day' Sat Apr 30 21:25:47 BRT 2011 # date --date='1 month' Sun May 29 21:26:04 BRT 2011 # date --date='1 year' Sun Apr 29 21:26:16 BRT 2012
Misturando tudo
Que tal exibir a data futura de uma forma personalizada, basta misturar as duas opções conforme exemplo abaixo.
# date "+Data: %d/%m/%Y%tHora: %H:%M:%S" --date='1 month' Data: 29/05/2011 Hora: 21:27:10
Somando o ano, mês e dia ao mesmo tempo.
# date "+Data: %d/%m/%Y%tHora: %H:%M:%S" --date='2 year 3 month 10 day' Data: 08/08/2013 Hora: 21:38:06
Podemos usar as seguintes opções para calcular uma data
X year X month X day X hours X minutes X seconds
Aqui estão todas as opções ativas.
# date "+Data: %d/%m/%Y%tHora: %H:%M:%S" --date='2 year 3 month 10 day 4 hours 45 minutes 30 seconds' Data: 03/09/2013 Hora: 17:10:55
Quando usamos mais de uma opção para fazer o calculo com data no passado devemos usar ago em todos, veja abaixo.
X year ago X month ago X day ago X hours ago X minutes ago X seconds ago
# date "+Data: %d/%m/%Y%tHora: %H:%M:%S" --date='2 year ago 3 month ago 10 day ago 4 hours ago 45 minutes ago 30 seconds ago' Data: 14/02/2009 Hora: 08:41:31
Usando na pratica
Você pode utilizar para verificar a aderência da sua maquina ao horário de verão, veja como.
# for m in `seq 1 12`; do date "+Data: %d/%m/%Y%tHora: %H:%M:%S" --date="$m month"; done Data: 29/05/2011 Hora: 21:32:04 Data: 29/06/2011 Hora: 21:32:04 Data: 29/07/2011 Hora: 21:32:04 Data: 29/08/2011 Hora: 21:32:04 Data: 29/09/2011 Hora: 21:32:04 Data: 29/10/2011 Hora: 22:32:04 Data: 29/11/2011 Hora: 22:32:04 Data: 29/12/2011 Hora: 22:32:04 Data: 29/01/2012 Hora: 22:32:04 Data: 29/02/2012 Hora: 21:32:04 Data: 29/03/2012 Hora: 21:32:04 Data: 29/04/2012 Hora: 21:32:04
Veja que nos meses outubro, novembro, dezembro e janeiro o horário está adiantado, isso é porque nesses meses no timezone que o meu Linux está configurado tem horário de verão, sendo assim ele adianta automaticamente o relógio.
Podemos brincar um pouco e colocar para ele fazer dia a dia e você vai saber exatamente o dia que ele mudar para o horário de verão, veja:
# for m in `seq 1 12`; do for d in `seq 1 31`; do date "+Data: %d/%m/%Y%tHora: %H:%M:%S" --date="$m month $d day"; done; done | less Data: 30/05/2011 Hora: 21:40:35 Data: 31/05/2011 Hora: 21:40:35 Data: 01/06/2011 Hora: 21:40:35 Data: 02/06/2011 Hora: 21:40:35 Data: 03/06/2011 Hora: 21:40:35 Data: 04/06/2011 Hora: 21:40:35 ...... Data: 13/10/2011 Hora: 21:40:35 Data: 14/10/2011 Hora: 21:40:35 Data: 15/10/2011 Hora: 21:40:35 Data: 16/10/2011 Hora: 22:40:35 Data: 17/10/2011 Hora: 22:40:35 Data: 18/10/2011 Hora: 22:40:35 Data: 19/10/2011 Hora: 22:40:35 ........ Data: 23/02/2012 Hora: 22:40:35 Data: 24/02/2012 Hora: 22:40:35 Data: 25/02/2012 Hora: 22:40:35 Data: 26/02/2012 Hora: 21:40:35 Data: 27/02/2012 Hora: 21:40:35 ....... Data: 27/05/2012 Hora: 21:40:36 Data: 28/05/2012 Hora: 21:40:36 Data: 29/05/2012 Hora: 21:40:36 Data: 30/05/2012 Hora: 21:40:36
Utilização prática dos scripts acima?
Não muita, apenas para validar se seu Linux está configurado de forma correta para o horário de verão.
Já o script abaixo pode ser utilizado para ler a data informada pelo usuário, a quantidade de dias a serem adicionados ou reduzidos e exibir o resultado para o usuário.
#!/bin/sh
clear
echo Informe uma data. Ex. 31/01/2013
read _DATA
echo
echo Informe o horario. Ex. 15:25:30
read _HORA
echo
_dia=`echo $_DATA | cut -d'/' -f1`
_mes=`echo $_DATA | cut -d'/' -f2`
_ano=`echo $_DATA | cut -d'/' -f3`
echo "Informe quantos DIAS para adicionar (+20) ou reduzir (-25)"
read _NOVA_DATA
echo
if [ $_NOVA_DATA -lt 0 ]; then
_NOVA_DATA=`echo $_NOVA_DATA | tr "-" " "`
date --date="$_ano-$_mes-$_dia $_HORA $_NOVA_DATA day ago"
else
_NOVA_DATA=`echo $_NOVA_DATA | tr "+" " "`
date --date="$_ano-$_mes-$_dia $_HORA $_NOVA_DATA day"
fi
Abraços

