2

I'm using date.js to apply conditional formatting to a data grid. The data is parsed from a javascript array. All of my conditions are working correctly, except for this one:

if (val < today && val > '01-01-2000')

val is a string in MM-dd-yyyy format that I can't change. So I used date.js to convert today's date to a string in MM-dd-yyyy format and make the comparison. The problem is that 01-17-2014 is seen as less than 04-08-2013 - since it is comparing strings.

What's the best way around this?

I'd like to make it simple, which is why I converted to strings in the first place, but I'm not sure how to get around the year issue.

Thanks for any help!

var today = new Date.today().toString("MM-dd-yyyy");
var tomorrow = new Date.today().addDays(1).toString("MM-dd-yyyy");
var upcoming = new Date.today().addDays(7).toString("MM-dd-yyyy");

function eXcell_edncl(cell) {
    this.base = eXcell_edn;
    this.base(cell);
    this.setValue = function(val) {
        if (val.indexOf('ACT') >= 0) this.cell.style.backgroundColor="lightgreen";
        else if (val.indexOf('PV') >= 0) this.cell.style.backgroundColor="lightgreen", this.cell.style.fontSize="20px";
        else if (val.indexOf('YES') >= 0) this.cell.style.backgroundColor="lightgreen", this.cell.style.fontSize="20px";
        else if (val < today && val > '01-01-2000') this.cell.style.backgroundColor="red";
        else if (val == today) this.cell.style.backgroundColor="orange";
        else if (val == tomorrow) this.cell.style.backgroundColor="yellow";
        else if (val > tomorrow && val <= upcoming) this.cell.style.backgroundColor="lightyellow";
        else this.cell.style.backgroundColor="";
        this.cell.innerHTML = this.grid._aplNF(val, this.cell._cellIndex);
    }
}
Matt Johnson-Pint
  • 230,703
  • 74
  • 448
  • 575
user1911141
  • 137
  • 1
  • 4
  • 14

4 Answers4

1

The best way around this issue is to not convert your Date objects into Strings. "01-17-2014" < "04-08-2013"evaluates to true because "01" < "04" is true, so whatever is tacked onto those strings will always evaluate the same way. However, using the less than/greater than operators on Date objects will behave as expected. So you can modify your existing if statement to be

if (new Date(val) < new Date(today) && new Date(val) > new Date('01-01-2000'))

and that will resolve your problem, but you are probably better off using the Date objects to begin with.

Default
  • 16,020
  • 3
  • 24
  • 38
  • Thanks. That makes sense. I tried: else if (new Date(val) < new Date(today) && new Date(val) > new Date('01-01-2000')) this.cell.style.backgroundColor="red"; But it isn't turning dates that are indeed less then today to a red background. – user1911141 Apr 08 '13 at 19:07
  • Comparing `Date` instances like this works because the [relational operators `<` and `>`](http://www.ecma-international.org/ecma-262/5.1/#sec-11.8.1) implicitly call the instance's `valueOf()` method (which is inherited from `Date.prototype`), through the internal `ToPrimitive` algorithm, which returns the instance's time value (the same as `getTime()`) . It can work for any other object that has or inherits such a method. – PointedEars Apr 08 '13 at 19:16
  • @user1911141 `new Date('01-01-2000')` does _not_ result in a `Date` instance for January 1, 2000. You want to [RTFM on supported date formats](https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date), or write `new Date(2000, 0, 1)` to be sure (yes, the month is 0-based). – PointedEars Apr 08 '13 at 19:19
  • Tried new Date(2000, 0, 1) but it still isn't recognizing the condition for dates earlier than today. TFTFH though. – user1911141 Apr 08 '13 at 19:56
1

Since you are using date.js you can use its compare function, as described on the documentation:

Date.compare ( Date date1, Date date2 ) : Number

Compares the first date to the second date and returns an number indication of their relative values. -1 = this is lessthan date. 0 = values are equal. 1 = this is greaterthan date.

See the documentation for a code example.

Community
  • 1
  • 1
excentris
  • 471
  • 1
  • 7
  • 25
1

You may not be able to change the format of the date string in the UI, but it should not matter what format it is in in the back-end. You should change the code to use ISO 8601 which was designed to allow easy comparison in string format (among other advantages).

The format of your dates would then be yyyy-MM-dd which would allow you to compare them as strings.

And because it is relevant, check out this XKCD comic if you are still on the fence.

Jesse Webb
  • 43,135
  • 27
  • 106
  • 143
  • Thanks Jesse. This makes the most sense to me, but I'm not sure how to convert my val string from MM-dd-yyyy to yyyy-MM-dd. I tried: var val2 = new Date.val.toString("yyyy-MM-dd"); and var val2 = new Date(val).toString("yyyy-MM-dd"); but neither did the trick. Can you help me with that part? – user1911141 Apr 08 '13 at 19:41
  • @user1911141 I am no expert in JavaScript and especially not with Dates in JavaScript. But [this StackOverflow Q&A](http://stackoverflow.com/questions/1056728/formatting-a-date-in-javascript) might help you out. If you still are having problems, feel free to create a new question about your specific problem and the right people will try to help you out. – Jesse Webb Apr 08 '13 at 20:12
0

Ended up with the following working. Needed to parse the values coming in:

var today = new Date.today().toString("MM-dd-yyyy");
var today2 = new Date.today();
var old = new Date(2000, 0, 1);
var tomorrow = new Date.today().addDays(1).toString("MM-dd-yyyy");
var upcoming = new Date.today().addDays(7).toString("MM-dd-yyyy");

function eXcell_edncl(cell) {
    this.base = eXcell_edn;
    this.base(cell);
    this.setValue = function(val) {
        var val2 = new Date.parse(val);
        if (val.indexOf('ACT') >= 0) this.cell.style.backgroundColor="lightgreen";
        else if (val.indexOf('PV') >= 0) this.cell.style.backgroundColor="lightgreen", this.cell.style.fontSize="20px";
        else if (val.indexOf('YES') >= 0) this.cell.style.backgroundColor="lightgreen", this.cell.style.fontSize="20px";
        else if (val2 < today2 && val2 > old) this.cell.style.backgroundColor="red";
        else if (val == today) this.cell.style.backgroundColor="orange";
        else if (val == tomorrow) this.cell.style.backgroundColor="yellow";
        else if (val > tomorrow && val <= upcoming) this.cell.style.backgroundColor="lightyellow";
        else this.cell.style.backgroundColor="";
        this.cell.innerHTML = this.grid._aplNF(val, this.cell._cellIndex);
    }
}
user1911141
  • 137
  • 1
  • 4
  • 14
  • As default said, your "best" option is to work with date objects and only convert to strings for output. – RobG Apr 09 '13 at 04:13