Sua Área, seu Local
31 jan
Recentemente venho tomando um cuidado maior na forma como apresento as informações de um sistema para o usuário.
Certos tipos de dados quando apresentados para o usuário não trazem consigo muita informação, um caso clássico são as datas e horas. Datas e Horas ganham muito mais significado quando comparadas a outras datas, por isso, seria muito mais interessante que nas consultas, relatórios e outros locais do sistema, aonde mantenham-se datas e horas, o sistema fizesse estas comparações para o usuário, pois se o sistema não o fizer, o usuário vai ter que fazer isto “de cabeça”.
Na prática o que quero demonstrar é que é muito mais fácil e natural, ler algo como “O boleto vence daqui 3 dias”, do que, “O boleto vence dia 10/02/2008″. Percebam como no primeiro exemplo houve uma comparação da data de vencimento do boleto com a data atual, o que significa que o vencimento é daqui 3 dias, enquanto no segundo exemplo apenas foi informado a data de vencimento, nua e crua.
…usabilidade normalmente se refere à simplicidade e facilidade com que uma interface, um programa de computador ou um website pode ser utilizado. Fonte: http://pt.wikipedia.org/wiki/Usabilidade
A informação de que o boleto vence no dia 10 é importante, mas ela seria muito mais informativa se viesse acompanha da dica de que esta data de vencimento acontece somente daqui 3 dias.
Percebam que sempre haverá a comparação com outra data, para poder fornecer este tipo de informação ao usuário, pode ser uma relação da data de nascimento com a data atual, da data de vencimento com a data de pagamento etc.
Sempre que houver uma interface, ou seja, um ponto de contato entre um ser humano e um objeto físico (ex: cafeteira) ou abstrato (ex: software), podemos observar a usabilidade que esse objeto oferece. Fonte: http://usabilidoido.com.br
O Gmail se utiliza desta técnica também, e é muito útil. Quando uma mensagem é aberta, é exibido no canto direito a quantos minutos, horas ou dias a mensagem foi enviada, ao lado da data ou hora de envio.
Usabilidade é sinônimo de facilidade de uso. Se um produto é fácil de usar, o usuário tem maior produtividade: aprende mais rápido a usar, memoriza as operações e comete menos erros. Fonte: http://usabilidoido.com.br
Desenvolvi uma função em Delphi que permite passar como parâmetro duas datas e retornar a diferença em anos, meses e dias das duas datas. A função tem ainda um terceiro parâmetro opcional que permite definir o nível de comparação, permitindo retornar assim somente os anos/mêses, mêses/dias ou os anos/mêses/dias entre as duas datas.
Adaptando o código, ela poderia ser facilmente convertida para o PHP. Se alguém o fizer, por favor responda, colocando o código-fonte junto.
Segue abaixo o código-fonte da função:
function FuzzyDateBetween(DateOf,DateThen: TDateTime; Nivel: Word=2): string;
var anos, meses, dias, i: integer;
str, junta: string;
begin
str := '';
junta := '';
EnsureRange(Nivel,1,3);
for i := 1 to Nivel do
begin
anos := YearsBetween(DateOf,DateThen);
if anos = 0 then
begin
meses := MonthsBetween(DateOf,DateThen);
if meses = 0 then
begin
dias := DaysBetween(DateOf,DateThen);
if dias = 1 then
str := str + junta + IntToStr(dias) + ' dia'
else
str := str + junta + IntToStr(dias) + ' dias';
break;
end
else
begin
if meses = 1 then
str := str + junta + IntToStr(meses) + ' mês'
else
str := str + junta + IntToStr(meses) + ' meses';
junta := ' e ';
DateOf := incMonth(DateOf, meses);
end;
end
else
begin
if anos = 1 then
str := str + junta + IntToStr(anos) + ' ano'
else
str := str + junta + IntToStr(anos) + ' anos';
junta := ifThen(Nivel=3,', ',' e ');
DateOf := IncYear(DateOf,anos);
end;
end;
Result := Trim(str);
end;
Alguns exemplos de chamadas a função:
FuzzyDateBetween(’11/09/2001′,’31/01/2008′,1) resulta em “6 anos”
FuzzyDateBetween(’11/09/2001′,’31/01/2008′,2) resulta em “6 anos e 4 meses”
FuzzyDateBetween(’11/09/2001′,’31/01/2008′,3) resulta em “6 anos, 4 meses e 20 dias”
FuzzyDateBetween(’11/09/2007′,’31/01/2008′,1) resulta em “4 meses”
FuzzyDateBetween(’11/09/2007′,’31/01/2008′,2) resulta em “4 meses e 20 dias”
FuzzyDateBetween(’11/09/2007′,’31/01/2008′,3) resulta em “4 meses e 20 dias”
P.S.: Ignorei a conversão da data para não ficar extenso demais, no Delphi o correto seria passar como parâmetro StrToDate(’11/09/2001′), etc.
Na próxima versão da função vou implementar o cálculo de diferença de horas, minutos e segundos.
6 Comentários for "Usabilidade na exibição de datas e horas"
Pois é, este é um exemplo clássico da qual um detalhe pode fazer toda a diferença no produto final. E na internet, a usabilidade é um fator crucial, ainda mais sabendo que o concorrente está a um clique de distância. Por isso a importância de expor o conteúdo de uma maneira clara e fácil, afinal de contas como disse Felipe Memória no seu livro Design para Internet “Design não são usuários e usuário não são designer.”
Aurélio, muito boa sua colocação.
Para complementar, a utilização de mascaras na entrada dos dados também é importante.
Abaixo deixo o link com um script para esta finalidade.
http://digitalbush.com/projects/masked-input-plugin
Caramba….
Isso sim é produção de conhecimento. Parabéns Aurélio pelo excelente post e Gilmara pelo comentário.
Quanto a sugestão em fazer a função em PHP.
Desafio o primeiro a postar.
Aurélio, foi-me muito útil a sua lógica, no entanto não poderia deixar de observar suas falhas em algumas situações conforme exemplo.
Veja o que acontece quando as Datas forem;
Entre as dadas 01/01/1985 e incDay(’31/07/1987′)
Aurélio, segue minha lógica para correção, fiz na pressa mas funcionou.
var
i,y,anos,meses,dias: integer;
str, junta: string;
DiaDecode : TAnoMesDia;
MatrizOper : array[1..3] of array[1..3] of Integer;
begin
//CREATED BY AGNALDO 23/07/2008
str := ”;
junta := ”;
EnsureRange(Nivel,1,3);
for i:=1 to Nivel do
for y:=1 to Nivel do
MatrizOper[i,y]:=0;
for i := 1 to Nivel do
begin
anos := YearsBetween(DateOf,DateThen);
MatrizOper[1,i]:=YearsBetween(DateOf,DateThen);
if anos = 0 then
begin
meses := MonthsBetween(DateOf,DateThen);
MatrizOper[2,i]:=MonthsBetween(DateOf,DateThen);
if meses = 0 then
begin
dias := DaysBetween(DateOf,DateThen);
MatrizOper[3,i]:=DaysBetween(DateOf,DateThen);
break;
end
else
begin
junta := ‘ e ‘;
DateOf := incMonth(DateOf, meses);
end;
end
else
begin
junta := ifThen(Nivel=3,’, ‘,’ e ‘);
DateOf := IncYear(DateOf,anos);
end;
end;
DiaDecode.Ano:=0;
DiaDecode.Mes:=0;
DiaDecode.Dia:=0;
for i:=1 to Nivel do
begin
DiaDecode.Ano:= MatrizOper[1,i]+DiaDecode.Ano;
DiaDecode.Mes:= MatrizOper[2,i]+DiaDecode.Mes;
DiaDecode.Dia:= MatrizOper[3,i]+DiaDecode.Dia;
end;
//ESCREVENDO EXTENSO
if DiaDecode.Ano = 1 then
str := str + junta + IntToStr(DiaDecode.Ano) + ‘ ano’
else
str := str + junta + IntToStr(DiaDecode.Ano) + ‘ anos’;
if DiaDecode.Mes = 1 then
str := str + junta + IntToStr(DiaDecode.Mes) + ‘ mês’
else
str := str + junta + IntToStr(DiaDecode.Mes) + ‘ meses’;
if DiaDecode.Dia = 1 then
str := str + junta + IntToStr(DiaDecode.Dia) + ‘ dia’
else
str := str + junta + IntToStr(DiaDecode.Dia) + ‘ dias’;
s := Trim(str);
Result := DiaDecode;
Agnaldo, realmente não havia percebido este problema, fiz o teste chamando a função assim FuzzyDateBetween(’01/01/1985′,’01/08/2008′,3) e isso resulta em “2 anos, 6 meses e 1 mês”.
Estou um pouco complicado de tempo agora, mas quando resolver este bug, coloco o novo código aqui.
Não testei a sua solução, mas obrigado por compartilhar seu código. Um abraço, Aurélio
Deixar resposta