Uma das funções básicas e mais comuns das aplicações é a introdução de dados pelos utilizadores. Grande parte dos campos são simples como inputs, radio buttons, checkboxes ou textareas.

Existem, no entanto, alguns campos que causaram e continuam a causar alguma controvérsia sobre qual a melhor forma de serem preenchidos. Neste post falamos sobre campos e formatos de datas e algumas formas para facilitar o preenchimento destes campos.

Muito melhorou desde que foi apresentado o primeiro datepicker e, mesmo assim, grande parte das aplicações continua a tornar difícil a tarefa dos utilizadores obrigando-os a preencher as datas num determinado formato (talvez, muito devido aos formatos das bases de dados).

Nos primórdios das aplicações, uma data era apenas mais um campo de texto. O utilizador era responsável por preencher o campo corretamente e raras eram (são?) as aplicações que indicavam o formato correto em que deveria ser preenchida a data. Depois desta fase passou-se para um misto de

  • Um campo de texto livre
  • Uma select para cada componente da data (dia, mês, ano)
  • Utilização de datepickers, que exigem um formato de data mas possibilitam a introdução de texto

Ao fim de tantos anos e continua a discussão sobre qual a melhor prática a usar para preencher campos de datas. Não me querendo juntar a esta discussão, neste post assumimos o preenchimento dos campos de data através de datepickers que também permitam a edição das datas manualmente.

Talvez a maior dificuldade no preenchimento deste tipo de campos prende-se com o formato da data exigido, que nem sempre é o formato usado no país. Por exemplo, é comum ver aplicações para o mercado português cujos campos de datas têm de ser preenchidos no formato aaaa-mm-dd, embora o formato correto seja dd-mm-aaaa. Uma das causas deste funcionamento é o formato dos campos DATE e DATETIME que os sistemas de base de dados usam para armazenar as datas. Uma das particularidades destes campos é o formato em que a data fica armazenada que é, habitualmente, aaaa-mm-dd (curiosamente, o formato mais comum no mundo é dd-mm-aaaa).

Se a aplicação não fizer nenhum tratamento intermédio aos valores que são retirados da base de dados, as datas vão ser apresentadas tal como são retiradas do SQL. Da mesma forma, se o preenchimento não for feito no formato correto, as datas não serão gravadas (porque se espera um formato igual ao da base de dados). Isto ocorre independentemente da linguagem usada (.net, Java, PHP) embora me pareça que é mais comum com PHP.

Para facilitar o preenchimento por parte dos utilizadores, é possível adicionar algum código em Javascript para que sejam aceites vários formatos de data. Desta forma, o input do utilizador é alterado para ficar no formato aceite pelo sistema. Assim, considerando que o sistema (base de dados) apenas aceita o formato aaaa-mm-dd, tornamos possivel a inserção de datas com os formatos:

  • dd-mm-aaaa
  • dd/mm/aaaa
  • d/m/aaaa
  • ddmmaaaa

Para isto, é necessário um método para processar o valor introduzido e alterar esse valor de acordo com um conjunto de regras. Para o efeito, usamos a seguinte função em Javascript:

var parseDate = function(value) {
    var m = value.match(/^(\d{1,2})(\/|-)?(\d{1,2})(\/|-)?(\d{4})$/);
    if (m)
        value = m[5] + '-' + ("00" + m[3]).slice(-2) + '-' + ("00" + m[1]).slice(-2);

    return value;
}

O método acima verifica se o valor recebido corresponde ao regex. O valor corresponde ao regex quando o valor tiver um ou dois dígitos, uma ou nenhuma / ou -, seguido de um ou dois dígitos e uma ou nenhuma / ou - e terminado em quatro dígitos. Se esta condição se verificar estamos perante um campo com um formato válido e o valor será alterado de forma a ficar com o formato aaaa-mm-dd.

Contudo o formato correto não garante que o valor introduzido seja uma data válida. Isso pode ser feito com o Date.parse():

var isValidDate = function(value, format) {
    format = format || false;
    // se a variável format for true, tentamos transformar a data
    if (format) {
        value = parseDate(value);
    }

    var timestamp = Date.parse(value);

    return isNaN(timestamp) == false;
}

Para aplicar os múltiplos formatos de data, basta aplicar o parseDate no evento blur do input em que se insere a data:

$('input[name=datepicker]').on("blur",function () {
    // verifica se o valor introduzido é válido. Os formatos aceites são dd-mm-yyyy ou yyyy-mm-dd.
    // Atualiza o formato caso seja dd-mm-yyyy
    var date = parseDate($(this).val());

    if (! isValidDate(date)) {
        // Se a data form inválida, apresenta a data atual
        date = moment().format('YYYY-MM-DD');
    }

    $(this).val(date);
});

O exemplo seguinte contém todo o código e o datepicker que está a ser usado é o Bootstrap Datepicker

See the Pen Simple Bootstrap datepicker example by Luís Cruz (@milz) on CodePen.

Desde a versão 4.0 deste datepicker, passa a ser possível aceitar vários formatos de data sem a necessidade de código adicional.