Como calcular diferença de datas em DIAS?

reinaldo_vieira
Tera Contributor

Boa tarde, pessoal.

 

Estou trabalhando em um desafio que solicita calcular a diferença de datas em 2 campos de um formulário do Service Portal e impor bloqueios/mensagens do tipo error, a depender do resultado.

 

Calculating difference between two dates - Service Catalog form.jpeg

 

Os dois campos no formulário são do tipo Data (e não Data/Hora).

Dá pra fazer direto por Client Script ou é melhor uma combinação Script Include GlideAJAX + Catalog Client Script onChange pra isso?

 

Importante:
- Data em "data_inicio_emprestimo" NÃO PODE ser inferior a data atual. Caso seja, o campo exibirá uma mensagem de texto do tipo error e o formulário não poderá ser enviado.

- A diferença de data entre os campos (data_inicio_emprestimo / data_final_emprestimo) deve ser de no máximo 7 dias. Caso a diferença seja maior que 7 dias, o campo exibirá uma mensagem de texto do tipo error e o formulário não poderá ser enviado.

1 ACCEPTED SOLUTION

Flavio Tiezzi
Kilo Sage

Boa tarde, Reinaldo!

 

Pelo o que eu vi, o formato da data dos campos que você está utilizando é no padrão dd/MM/yyyy, certo? Na documentação do GlideDate, o formato esperado para o subtract é no padrão yyyy-MM-dd

 

Acredito que atualizando o código dessa forma deve atender o seu requisito:

 

Obs: No client script, ao utilizar o método getXMLAnswer, não é necessário chamar o XML Document todo. Pode utilizar direto a resposta do server - Aqui tem um tópico sobre o assunto

 

//CLIENT SCRIPT
function onChange(control, oldValue, newValue, isLoading) { //Variable name = data_final_emprestimo
    if (isLoading || newValue == '') {
        return;
    }

    //Type appropriate comment here, and begin script below
    var startDate = g_form.getValue('data_inicio_emprestimo');
    var endDate = g_form.getValue('data_final_emprestimo');
    var maxDays = 7;


    var ga = new GlideAjax('global.DifferDates');
    ga.addParam('sysparm_name', 'calcularDias');
    ga.addParam('sysparm_start', startDate);
    ga.addParam('sysparm_end', endDate);
    ga.getXMLAnswer(callback);

    function callback(response) {
        //var answer = response.responseXML.documentElement.getAttribute('answer');
        if (response > maxDays) {
            g_form.showFieldMsg('data_final_emprestimo', 'Você ultrapassou o limite de 7 dias. Por favor, escolha um período mais curto', 'error');
        } else {
            alert('Deu errado...'); //to check if Script Include and Client Script are running ok
        }

    }

}

//SCRIPT INCLUDE
var differDates = Class.create();
differDates.prototype = Object.extendsObject(AbstractAjaxProcessor, {

    transformDate: function(date) {

        date = date.split('/');
        return date = date[2] + '-' + date[1] + '-' + date[0];
    },


    calcularDias: function() {
        var from = new GlideDate();
        //from.setDisplayValue(this.transformDate('01/10/2023'));
        from.setDisplayValue(this.transformDate(this.getParameter('sysparm_start')));

        var to = new GlideDate();
        //to.setDisplayValue(this.transformDate('01/11/2023'));
        to.setDisplayValue(this.transformDate(this.getParameter('sysparm_end')));

        var difference = GlideDate.subtract(from, to);
        var days = difference.getDayPart();

        return days;


    },

    type: 'differDates'
});

 

 

 

 

 

 

 

 

 

View solution in original post

5 REPLIES 5

reinaldo_vieira
Tera Contributor

Até o momento, eu montei um Script Include e um Catalog Client Script, desta forma. Mas é exibida uma mensagem de erro no console e eu não sei por qual motivo.

 

SCRIPT INCLUDE:

 

var DifferDates = Class.create();
DifferDates.prototype = Object.extendsObject(AbstractAjaxProcessor, {
 
    calcularDias: function() {
        var from = this.getParameter('sysparm_start');
        var to = this.getParameter('sysparm_end');
        var duration = GlideDate.subtract(from, to);
 
gs.info(duration + '@Reinaldo'); //To catch logs
    },
 
    type: 'DifferDates'
});
 
CATALOG CLIENT SCRIPT:
 

function onChange(control, oldValue, newValue, isLoading) {    //Variable name = data_final_emprestimo
if (isLoading || newValue == '') {
return;
}

//Type appropriate comment here, and begin script below
var startDate = g_form.getValue('data_inicio_emprestimo');
var endDate = g_form.getValue('data_final_emprestimo');
var maxDays = 7;

 

var ga = new GlideAjax('global.DifferDates');
ga.addParam('sysparm_name', 'calcularDias');
ga.addParam('sysparm_start', startDate);
ga.addParam('sysparm_end', endDate);
ga.getXMLAnswer(callback);

function callback(response) {
var answer = response.responseXML.documentElement.getAttribute('answer');
if (answer > maxDays) {
g_form.showFieldMsg('data_final_emprestimo', 'Você ultrapassou o limite de 7 dias. Por favor, escolha um período mais curto', 'error');
} else {
alert('Deu errado...'); //to check if Script Include and Client Script are running ok
}

}

}

Flavio Tiezzi
Kilo Sage

Boa tarde, Reinaldo!

 

Pelo o que eu vi, o formato da data dos campos que você está utilizando é no padrão dd/MM/yyyy, certo? Na documentação do GlideDate, o formato esperado para o subtract é no padrão yyyy-MM-dd

 

Acredito que atualizando o código dessa forma deve atender o seu requisito:

 

Obs: No client script, ao utilizar o método getXMLAnswer, não é necessário chamar o XML Document todo. Pode utilizar direto a resposta do server - Aqui tem um tópico sobre o assunto

 

//CLIENT SCRIPT
function onChange(control, oldValue, newValue, isLoading) { //Variable name = data_final_emprestimo
    if (isLoading || newValue == '') {
        return;
    }

    //Type appropriate comment here, and begin script below
    var startDate = g_form.getValue('data_inicio_emprestimo');
    var endDate = g_form.getValue('data_final_emprestimo');
    var maxDays = 7;


    var ga = new GlideAjax('global.DifferDates');
    ga.addParam('sysparm_name', 'calcularDias');
    ga.addParam('sysparm_start', startDate);
    ga.addParam('sysparm_end', endDate);
    ga.getXMLAnswer(callback);

    function callback(response) {
        //var answer = response.responseXML.documentElement.getAttribute('answer');
        if (response > maxDays) {
            g_form.showFieldMsg('data_final_emprestimo', 'Você ultrapassou o limite de 7 dias. Por favor, escolha um período mais curto', 'error');
        } else {
            alert('Deu errado...'); //to check if Script Include and Client Script are running ok
        }

    }

}

//SCRIPT INCLUDE
var differDates = Class.create();
differDates.prototype = Object.extendsObject(AbstractAjaxProcessor, {

    transformDate: function(date) {

        date = date.split('/');
        return date = date[2] + '-' + date[1] + '-' + date[0];
    },


    calcularDias: function() {
        var from = new GlideDate();
        //from.setDisplayValue(this.transformDate('01/10/2023'));
        from.setDisplayValue(this.transformDate(this.getParameter('sysparm_start')));

        var to = new GlideDate();
        //to.setDisplayValue(this.transformDate('01/11/2023'));
        to.setDisplayValue(this.transformDate(this.getParameter('sysparm_end')));

        var difference = GlideDate.subtract(from, to);
        var days = difference.getDayPart();

        return days;


    },

    type: 'differDates'
});

 

 

 

 

 

 

 

 

 

Olá, @Flavio Tiezzi 

 

Testei aqui sua solução e deu certo, muitíssimo obrigado!

 

Gostaria apenas de entender mais umas coisas, se for possível. Por exemplo: o que essa função aqui faz, exatamente? E esses índices de array?

 

transformDate: function(date) {
date = date.split('/');
return date = date[2] + '-' + date[1] + '-' + date[0];
},

 

E eu também gostaria de saber como faço para que o campo data_inicio_emprestimo aponte uma mensagem de erro caso a data escolhida seja inferior a atual.

 

Obrigado desde já.

Boa tarde!

A função basicamente é para fazer uma manipulação na string. Quando a gente usa o metódo split, ele transforma a string que foi passada em um array. Nesse caso, eu passei como parâmetro para o método a "/", pois o formato que está vindo do formulário é no padrão dd/MM/yyyy, então basicamente a data é dividida considerando a "/". Algo nesse sentido:

 

 

var date = '01/11/2023';
var split = date.split('/');

/*Resultado:
[
  "01", 
  "11",
  "2023"
]
*/

 

 

 

 

 

E após dar o split, usei os índices do array para deixar no formato que o GlideDate espera: yyyy-MM-dd

 

E para fazer a validação no campo caso a data selecionada seja inferior a atual, eu acredito que a forma mais simples seria por UI Policy - Tem um tópico aqui sobre esse tipo de validação utilizando UI Policy. 

 

Espero ter ajudado de alguma forma,

 

Flavio.