如何在 javascript 中查找给定周范围的日期

How to Find dates for given week range in javascript

提问人:V.J. 提问时间:9/10/2022 最后编辑:MarkusV.J. 更新时间:9/14/2022 访问量:177

问:

假设有一个重复的工作日范围,

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...

因此,我们需要找出相应日期/时间的确切日期,并且根据当前日期,日期可以在过去或将来。简而言之,我需要检查当前日期是否在给定范围内。

这是我到目前为止的代码:

    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 的代码。

JavaScript jQuery 日期时间

评论

0赞 traktor 9/10/2022
也许是一个框架挑战:为什么“需要检查当前日期是否在给定范围内”?为什么不扫描这些范围,看看当前的工作日和时间是否适合其中的一个或多个?在编写代码以使用该结构之前,设计需要访问的范围天数和时间的数据结构可能会有所帮助。
0赞 RobG 9/10/2022
范围仅为日期和时间,没有日期。您可以将范围转换为日期数和时间,因此第一个示例是 11300 到 21400。周二凌晨 3 点将是 20300,因此属于该范围。超过一周边界的范围将需要一些特殊处理。
0赞 kmoser 9/10/2022
这些重复范围采用什么格式?请提供数据结构的示例,而不仅仅是英文描述。
0赞 V.J. 9/12/2022
请在 jsfiddle 中找到所有详细信息。您可以根据需要修改 jsfiddle 代码的泛化。
0赞 Deniz Karadağ 9/14/2022
一个一般的问题,你说只有白天,没有日期。那么,你怎么知道某件事不是未来 2 周还是过去 2 周呢?或者周期是 10 天但不是 3 天(可以是周一到周三,但可以是下周周三)?数据有一定的规则吗?例如周期永远不会超过 7 天,显示的数据永远不会超过 7 天/之前,时间总是相同的,等等。

答:

0赞 IT goldman 9/14/2022 #1

在您的允许下,我将简化数据结构。基本上代码很短,我们用天、时间工作。然后,我们可以计算每个偏移小时数。然后很容易检查范围内的存在。0..600..23

// 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))