How to Find dates for given week range in javascript

Viewed 110

Lets say there is a recurring range of weekday,

Start : Monday 1 PM 
End : Tuesday 2 PM 

Start : Friday 12 AM 
End : Monday 12 AM 

Start : Saturday 12 AM 
End : Wednesday 12 AM 

etc...

So we need to find out exact date for corresponding day/time and date can in past or future depending on current date. In short I need to check if current date is falling in given range or not.

This is my code so far:

    var day_values = {
        "Sunday": 0,
        "Monday": 1,
        "Tuesday": 2,
        "Wednesday": 3,
        "Thursday": 4,
        "Friday": 5,
        "Saturday": 6,
    }

    var time_zone = "America/New_York";

    const convertTZ = (date, tzString) => {
        return new Date((typeof date === "string" ? new Date(date) : date).toLocaleString("en-US", { timeZone: tzString }));
    }

    const convertTime12to24 = (hours, modifier) => {
        if (hours === '12') {
            hours = '00';
        }
        if (modifier === 'PM') {
            hours = parseInt(hours, 10) + 12;
        }
        return parseInt(hours);
    }

    function nextDate(day_details) {
        var dayIndex = day_values[day_details[0]];
        var today = convertTZ(new Date(), time_zone);
        today.setDate(today.getDate() + (dayIndex - 1 - today.getDay() + 7) % 7 + 1);
        today.setHours(convertTime12to24(day_details[1], day_details[2]), 0, 0);
        return today;
    }

    function get_start_end_dates(start_details, end_details) {
        var start_day_index = day_values[start_details[0]];
        var end_day_index = day_values[end_details[0]];
        var date = convertTZ(new Date(), time_zone); // current date-time in user time zone,
        var now_day_index = date.getDay();

        var start_day_index_diff = now_day_index - start_day_index
        var end_day_index_diff = now_day_index - end_day_index

        var start_date, end_date;
        //case 1 both days are greater or less than current day
        if ((start_day_index_diff < 0 && end_day_index_diff < 0) || (start_day_index_diff > 0 && end_day_index_diff > 0)) {
            start_date = nextDate(start_details)
            end_date = nextDate(end_details)
        }
        //case 2 both on same current day
        else if (start_day_index_diff == 0 && end_day_index_diff == 0) {
            start_date = convertTZ(new Date(), time_zone)
            start_date.setHours(convertTime12to24(start_details[1], start_details[2]), 0, 0);;
            end_date = convertTZ(new Date(), time_zone)
            end_date.setHours(convertTime12to24(end_details[1], end_details[2]), 0, 0);
        }
        //case 3 start before current and end after current
        else if (start_day_index < now_day_index && end_day_index > now_day_index) {
            //start_date
            end_date = nextDate(end_details)
        }
        //case 4 end before current and start after current


        return { start_date, end_date };
    }
    //case 1
    //var repeat_start = "Monday 1 AM".split(" ")
    //var repeat_end = "Monday 2 AM".split(" ")
    //var dates = get_start_end_dates(repeat_start, repeat_end);
    //
    //var repeat_start = "Friday 1 AM".split(" ")
    //var repeat_end = "Friday 2 AM".split(" ")
    //var dates = get_start_end_dates(repeat_start, repeat_end);
    //
    //var repeat_start = "Thursday 1 AM".split(" ")
    //var repeat_end = "Thursday 2 AM".split(" ")
    //var dates = get_start_end_dates(repeat_start, repeat_end);
    //
    //var repeat_start = "Wednesday 1 AM".split(" ")
    //var repeat_end = "Thursday 2 PM".split(" ")
    //var dates = get_start_end_dates(repeat_start, repeat_end);

    //case 2
    //var repeat_start = "Saturday 12 AM".split(" ")
    //var repeat_end = "Saturday 2 AM".split(" ")
    //var dates = get_start_end_dates(repeat_start, repeat_end);

    //case 3
    //var repeat_start = "Friday 1 AM".split(" ")
    //var repeat_end = "Sunday 2 AM".split(" ")
    //var dates = get_start_end_dates(repeat_start, repeat_end);

    var repeat_start = "Monday 1 AM".split(" ")
    var repeat_end = "Saturday 1 AM".split(" ")
    var dates = get_start_end_dates(repeat_start, repeat_end);

    //ToDo once dates are available for corrosponding week range, we can easily check if now time is falling is between them or not

https://jsfiddle.net/vg23code/ogjb1wqu/ jsfiddle of code.

1 Answers

With your permission I will simplify the data structure. Basically the code is short, we work with days 0..6, time 00..23. Then we can calculate the offset hours for each. Then it's easy to check existence in range.

// days: 0..6 starting sunday
// hours: 0..23 starting midnight
// time zone: dont care

var ranges = [
  {start_day: 0, start_time: 09, end_day: 0, end_time: 17},
  {start_day: 1, start_time: 12, end_day: 3, end_time: 12},
  {start_day: 5, start_time: 00, end_day: 6, end_time: 23},
]

function normalize_hours(day, time) {
  return day * 24 + time;
}

var d = new Date('2022-09-14 04:00:00');
var day = d.getDay();
var time = d.getHours();
var now = normalize_hours(day, time)

var found = [];
ranges.forEach(function(range) {
  var start = normalize_hours(range.start_day, range.start_time)
  var end = normalize_hours(range.end_day, range.end_time)
  if (now >= start && now <= end) {
    found.push(range)
  }
})

console.log(d + " matches ranges: " + JSON.stringify(found))

Related