2

I'm trying to use JavaScript to loop through a json file which has time periods (starting date/time and ending date/time), and check if now (current date time) falls between any time period in such list.

Following is my code, but can't get where I'm wrong. Any help?

<html>
<script type="text/javascript">
    var data = {
        "period": {
            "startend": [{
                "startDate": "2015-11-17 15:43:37",
                "endDate": "2015-11-18 19:43:37"
            }, {
                "startDate": "2015-12-17 19:43:37",
                "endDate": "2016-01-17 19:43:37"
            }, {
                "startDate": "2015-04-17 19:43:37",
                "endDate": "2015-04-18 19:43:37"
            }]
        }
    }

    var periodArray = data.period.startend;
    var curDate = new Date();
    var datetime = curDate.getFullYear() + '-' + curDate.getMonth() + '-' + curDate.getDate() + ' ' + curDate.getHours() + ':' + curDate.getMinutes() + ':' + curDate.getSeconds();

    for (i = 0; i < periodArray.length ; i++) {
        var obj = periodArray[i]
            if (datetime > obj.startDate && datetime < obj.endDate){
                alert('Falls within period');
            } else {
                alert('Not within any period');
            }
    }
</script>

3
  • obj.startDate is just a String. Might want to do new Date(obj.startDate) and so on to get actual dates out of the strings. Then, presumably the comparison between dates will work. Commented Nov 18, 2015 at 0:57
  • @HunanRostomyan do you mean this: 'if (datetime > new Date(obj.startDate) && datetime < new Date(obj.endDate)){' ? still not working Commented Nov 18, 2015 at 1:06
  • Try that piece of code from my response. It has console.log instead of alert, but everything else should be the same. Commented Nov 18, 2015 at 1:16

2 Answers 2

3

The basic idea is to convert the date strings to actual Date objects so they can be compared with the current date (new Date()). Let's begin by defining a helper function that when initialized, closes over the current date, producing a function that takes a start date and an end date, either in String or in Date form, and returns true if and only if the closed over current date is in the range.

Definition.

// () -> (([String|Date] * [String|Date]) -> Boolean)
// When initialized, closes over the current date and returns
// a predicate on String or Date objects. 
function includesNow() {
  var curDate = new Date();
  return function(start, end) {
    var startDate = (typeof start === "string")
      ? new Date(start) : start;
    var endDate = (typeof end === "string")
      ? new Date(end) : end;
    return (curDate > startDate) && (curDate < endDate);
  };
}

Usage.

With the help of the helper function, we can then pretty easily filter the "current" dates:

// Get the list of (date string) objects.
var allDates = data.period.startend;

// Capture the current date, returning the date range comparator.
var comparator = includesNow();

// Get the list of those (date string) objects `obj`
// that satisfy `comparator(obj.startDate, obj.endDate) === true`.
var currentDates = allDates.filter(function(obj) {
  return comparator(obj.startDate, obj.endDate);
});

// This is a function of current date, so will be empty at some point.
currentDates[0];
// => Object {startDate: "2015-11-17 15:43:37", endDate: "2015-11-18 19:43:37"}

If you know your objects will always be Strings and never actual Date objects, then you can simplify includesNow considerably. If you're interested in the closed range be sure to replace > and < with ≥ and ≤, respectively.

Sign up to request clarification or add additional context in comments.

6 Comments

So I replace my for loop with this? Tried but won't run. My bad luck or I'm getting it wrong?
Thanks much Hunan for your input. How do I finally utilize it with my if else statement to yield the right alert?
@Harry First, replace the lines that declare curDate and datetime with var comparator = includesNow(). Then inside the conditional, instead of datetime > obj.startDate && datetime < obj.endDate do comparator(obj.startDate, obj.endDate).
Hunan, I feel silly for making you crazy and bother you again, but I did exactly as you guided but still not getting results. Following is how my code looks like now.
function includesNow() { var curDate = new Date(); return function(start, end) { var startDate = (typeof start === "string") ? new Date(start) : start; var endDate = (typeof end === "string") ? new Date(end) : end; return (curDate > startDate) && (curDate < endDate); }; } var allDates = data.period.startend; var comparator = includesNow(); var currentDates = allDates.filter(function(obj) { return comparator(obj.startDate, obj.endDate); }); if (comparator(obj.startDate, obj.endDate)){ alert('w'); } else { alert('n'); }
|
0

JSON date is not a date object. It's a string. You're trying to compare a Date obj to a String.

If the JSON date was an ISO formatted date you could do :

var dateStr = JSON.parse(date);
var realDate = new Date(dateStr);

realDate would now have a js date object. Unfortunately in your example the startDate and endDate are not ISO strings.

This would be the easiest/cleanest solution. Otherwise you could always get the JSON date strings and break them apart with substring() and convert the years/months/days with Number(); and then compare them that way?

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.