-3

I have a list of dates in format dd/mm/yyyy as text I'm trying to make these dates change style or class according to today's date today is february 9th 2016 or 09/02/2016

obviously, there's something wrong, because i want the "if" statements to mark the className as .past

if the year is before 2016 OR
if the month is before today's month (february) AND before today's day of the month (9)

13/01/2016 is marked as future- and i don't know why what am i doing wrong?

var today=new Date();
    var yr = today.getFullYear();
    var da = today.getDate();
    if (da<10){da= "0"+today.getDate()} else {da=today.getDate()};
    var mo = (today.getMonth()+1);
    if (mo<10){mo= "0"+mo} else {mo=mo};

    var cnl = document.getElementsByClassName("lesson");
    var cnd = document.getElementsByClassName("date");
    var cd = document.querySelectorAll('.date');
    for (var i=0;i<cnd.length;i)
    {
      var cd = document.querySelectorAll('.date')[i].innerHTML;
 

    if (
        ( cd.substring(6,10)<yr ) 
   
          ||
  
   (   
     ( 
     cd.substring(3,5) <= (mo)  
      ) 
    
          &&
    
     (
       ( 
     cd.substring(0,2) < (da)  
        ) 
     )
     
   )
    ) 
     {
     cnd[i].className = "past";
  }
  else 
  {
       cnd[i].className = "future";
     }
  
}
    .date {font-size:15px;}
    .past
    {
    font-family:arial;
    font-size:15px;
    direction:rtl;
    text-align:right;
    font-weight:300;
    color:#f11;  
    }
    .future
 {
       font-size:15px;
       direction:rtl;
        text-align:right;
        font-weight:300;
        color:#1f1;  
    }
    <ol>
    <li><span class="date">18/11/2015</span></li>
    <li><span class="date">02/12/2015</span></li>
    <li><span class="date">16/12/2015</span></li>
    <li><span class="date">30/12/2015</span></li>
    <li><span class="date">13/01/2016</span></li>
    <li><span class="date">03/02/2016</span></li>
    <li><span class="date">17/02/2016</span></li>
    <li><span class="date">02/03/2016</span></li>
    <li><span class="date">16/03/2016</span></li>
    <li><span class="date">30/03/2016</span></li>
    <li><span class="date">04/05/2016</span></li>
    <li><span class="date">13/04/2016</span></li>
    <li><span class="date">04/05/2016</span></li>
    <li><span class="date">18/05/2016</span></li>
    <li><span class="date">08/06/2016</span></li>
    </ol>

jsfiddle

Hunter Turner
  • 6,804
  • 11
  • 41
  • 56
kaospan
  • 3
  • 3
  • Include whatever ("[mcve]") code you have in the question itself, don't just link to it. That rule is there for the purpose of making the site more useful to others in future, and easier for us to provide you with valid/useful answers without having trek around the Internet. – David Thomas Feb 09 '16 at 14:57
  • 2
    13/01/2016 _is_ in the past. Or... No, I can't have time travelled, can I? – somethinghere Feb 09 '16 at 15:04
  • 1
    Your logic is flawed: January 13th is before today's month but not before today's day (13 > 9). – JJJ Feb 09 '16 at 15:08
  • 1
    Possible duplicate of [Compare two dates with JavaScript](http://stackoverflow.com/questions/492994/compare-two-dates-with-javascript) – JJJ Feb 09 '16 at 15:09

1 Answers1

1

The best way of doing this is to parse the string as a date and check it against the current date. Here's a simple function to convert your DMY date into a Date instance:

function dmyToDate(dmy) {
    var parts = dmy.split('/');
    parts[1] -= 1; // Months are 0-indexed
    return new Date(parts[2], parts[1], parts[0]);
}

Now you can loop through each of your elements and compare their date against the current date, adding a class if necessary.

var i = 0;
var il = cnd.length;

while (i < il) {

    if (dmyToDate(cnd[i].textContent) < today) {
        cnd[i].className = 'past';
    } else {
        cnd[i].className = 'future';
    }

    i += 1;

}

Edit

In order to test for today, you need to reduce the timestamp for today down to the nearest day. This can be done with a couple of basic utility functions.

// You can just write
// var day = 86400000
// but I find that spelling it out like this is easier to understand.
var day = 1000 * 60 * 60 * 24;

function numberToNearest(number, nearest, method) {

    var prop = 'round';

    if (typeof method === 'string' && typeof Math[method] === 'function') {
        prop = method;
    }

    return Math[prop](number / nearest) * nearest;

}

function getDayStart(date) {

    if (typeof date !== 'number' || !(date instanceof Date)) {
        date = Date.now();
    }

    return numberToNearest(date, day, 'floor');

}

var today = getDayStart();

Now the loop just needs an extra clause.

var i = 0;
var il = cnd.length;
var cndElem;
var cndDate;

while (i < il) {

    cndElem = cnd[i];
    cndDate = dmyToDate(cndElem.textContent);

    if (cndDate < today) {
        cndElem.className = 'past';
    } else if (cndDate > today) {
        cndElem.className = 'future';
    } else {
        cndElem.className = 'present';
    }

    i += 1;

}

Edit 2

See my JSFiddle example for a working version.

James Long
  • 4,629
  • 1
  • 20
  • 30
  • thanks James - one thing --> i += 1; jumps by 2 elements = but i+=0 works fine – kaospan Feb 09 '16 at 15:27
  • Not within the `while` loop I provided. `i += 0` adds nothing to the variable `i` so if you're already increasing `i` in another part of your loop, just remove `i += 0`. – James Long Feb 09 '16 at 15:31
  • `++i` is less to type. ;-) Also consider `while (il--)` and replace *i* with *il*. – RobG Feb 09 '16 at 22:55
  • Another question : i want to add an "else if" in between the if and else so that else if (dmyToDate(cnd[i].textContent) == today) so that when the day is equal to today - it will be a different class - the == doesn't work - neither does = or === - so how do i do it? – kaospan Feb 10 '16 at 14:24
  • @kaospan - that takes more characters to explain than this comment will allow. I've edited the the post to show how it's done. – James Long Feb 10 '16 at 15:02
  • Thanks again James- it surely is more complex than I expected. It doesn't work for me - I tried adding it to the end of the first loop , also tried deleting that loop, played around with the order of vars and such. what i'm getting is either all of the dates change to present - or every second date. I am probably messing up the scope. can you please let me know what I need so that it works for all past, present and future. and in case you were wondering - I styled a new class ".present" in CSS – kaospan Feb 10 '16 at 16:18
  • @kaospan - looks like `getDayStart()` shouldn't be used with `dmyToDate()` since that's already at the start of the day. Sorry about that. I've added a fiddle showing all the code necessary. – James Long Feb 10 '16 at 16:51
  • I don't see how it works - the JSfiddle shows that instead of text you changed the class to class="date js-today" - which shows today's date in dd/m/yyyy format - it's missing the "0" before the 2 - and most importantly it's not colored to green. I want it to read the text as is and recognize that it's today's date - not add today's date automatically – kaospan Feb 10 '16 at 18:37
  • to fix the month so that it adds a 0 in case of 1 digit i added this : var mo = (today.getMonth()+1); if (mo<10){mo= "0"+mo} else {mo=mo}; but still doesn't change to class .present - it's changed to .past – kaospan Feb 11 '16 at 06:06
  • for some reason i changed the 24 hours of a day to 22 hours and it worked - does if pickup GMT clock or my local time ? cause my local time is actually GMT + 2 - THIS WORKS var day = 1000 * 60 * 60 * 22; – kaospan Feb 11 '16 at 06:16
  • ACTUALLY that's on the fiddle only . . BUT if i don't us the class "date js-today" and use today's date as a string - IT DOESN'T WORK still – kaospan Feb 11 '16 at 06:25
  • ok sorry about that last comment- i changed the date on my system instead of changing the list date - and it works with 22 only (24, 23, 21, 20 are all past) – kaospan Feb 11 '16 at 06:34