Jonathan Ortega
Jonathan Ortega

Reputation: 19

Get days from substract to dates using Moment.js

I want to set a countdown for events, so only on the case the event hasn't started, a countdown of the days before the event shows. The dates are stored on the database like this DD-MM-YYYY, so I convert them using Moment.js, but I still don't get the remaining days. Here is my code

moment.locale('es');
        var hoy = moment().format("DD-MM-YYYY");
        var finicio = moment("20-01-2015", "DD-MM-YYYY").format("DD-MM-YYYY");
        var ffin = moment("19-01-2015", "DD-MM-YYYY").format("DD-MM-YYYY");
        $(function () {
            if (finicio < hoy) {
                $("#estadoevento").text("EXPIRADO");
            }
            else if (finicio > hoy) {
                $("#estadoevento").text("EN ESPERA");
                var contador = moment(finicio).diff(moment(hoy));
                var espera = moment.duration(contador);
                var restante = espera.asDays();
                $("#contador").text("FALTAN " + restante + " DÍAS");
            }
            else {
                $("#estadoevento").text("EN ESTE MOMENTO");
            }
        });

But I don't get the values, I don't know if I have to redeclare my variables, currently the code just shows a message on a span tag if event is expired, incoming or today, and works correctly.

Variable finicio is the one that contains the starting date for the event, so if the event starts on five days, I wan't to get that number, I tried, but it returns a 0 value. I'm using jQuery too.

contador variable is the substract of the two dates, variable espera gets the duration of contador, and finally restante changes into days, but I don't know where my code is wrong.

Upvotes: 0

Views: 1280

Answers (2)

Jonathan Ortega
Jonathan Ortega

Reputation: 19

With the help I got here, I post correct code for anyone interested

moment.locale('es');//Spanish Language for Moment
        var hoy = moment();//Get client systemd date
        var finicio = moment("08-02-2015", "DD-MM-YYYY");//A date for event start
        var ffin = moment("12-02-2015", "DD-MM-YYYY");//A date for event end
        $(function () {
            if (hoy.isSame(finicio, "day")) {
                $("#estadoevento").text("EN ESTE MOMENTO");
            }//To compare todays date with event start date
            else if (hoy.isBefore(finicio)) {
                $("#estadoevento").text("EN ESPERA");
                var falta = finicio.diff(hoy);
                var duracionfalta = moment.duration(falta);
                var faltante = Math.round(duracionfalta.asDays());
                $("#contador").text("FALTAN " + faltante + " DÍAS");
            }//If event hasn't started yet, this shows the amount of days remaining
            else {
                $("#estadoevento").text("EXPIRADO");
            }//When the event already passed
        });

Upvotes: 0

DanielST
DanielST

Reputation: 14133

Okay, a couple of things.

Format returns strings

.format() outputs a string.

So when you do finicio < hoy you are comparing which string is greater. This would be fine if the strings were formatted as YYYY-MM-DD (largest to smallest) but when they have days first, this will not compare them correctly.

Instead, use isBefore isSame and isAfter. And use them with the actual moment objects:

var hoy = moment(); // No .format
var finicio = moment("20-01-2015", "DD-MM-YYYY");
var ffin = moment("19-01-2015", "DD-MM-YYYY");

if( hoy.isAfter(finicio) ){ ... }

Creating a moment from a string

This:

var contador = moment(finicio).diff(moment(hoy));

is the same as

var contador = moment('20-01-2015').diff(moment('20-01-2015'));

because finicio and how are strings, not moment objects.

Which means you are creating two moment objects from strings without telling moment how they are formatted. If you run moment('20-01-2015') alone, you will get an error.

The code will work if you make finicio and hoy moment objects instead of strings. Or if you provide formatting strings: moment(finicio,"DD-MM-YYYY").

As before, I recommend just removing the .format when you create hoy,finicio and ffin so that you have moment objects to work with.

Edit: Granularity

The other thing with you can do with isBefore isSame and isAfter is set granularity.

moment().isSame('2015-02-06'); // false, because time is different
moment().isSame('2015-02-06', 'day'); // true, because anything smaller than days is ignored

Here's the JSFiddle from the comments fixed with granularity.

Upvotes: 1

Related Questions