JS获取-某一天是某个时间段内的 第几周,星期几

这篇博客介绍如何在JavaScript中确定当前日期是学期的第几周和星期几,适用于课程表显示本周课程的需求。内容包括如何根据学期起始时间进行计算。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


    最近做课程表,要将所有课程显示到一个课程格子里,默认加载本周课程,于是就需要知道本周是这个学期的第几周,引出本文主要内容:


    首先,这个学期的开始时间是要知道的,然后根据学期的开始时间计算本周是第几周,今天是星期几。


    

function(){  
    /* 
     * 说明: 
     * 本代码将周一作为每周的开始 
     */  
  
    function TodayInfo(start) {  
        var WEEKLEN = 7, // 一周7天
            WEEKDAYS = ["日", "一", "二", "三", "四", "五", "六"],  
            weekInfo = {"week": null, "day": null}, // 初始化返回信息,默认第null周,星期null  
            oneDay = 24 * 60 * 60 * 1000, // 一天的毫秒时长  
            weekLeave, // 开学当天所在周剩余天数  
            weekStart, // 开学当天start是星期几  
            today, // 今天  
            dateDiff, // 今天与开学当天日期差  
            sDate; //开学之日,日期对象  
        var rDateStr = /\d{4}[\/-]\d{1,2}[\/-]\d{1,2}/g; // 简单的日期格式校验:2013/12/19  
        if (!rDateStr.test(start)) {  
            alert("请使用合法的开学日期!!!");  
            return weekInfo;  
        }  
        sDate = new Date(star
<think>我们有一个数组,每个元素包含day, hour, minute等字段。要求按day分组,然后对同一天内的时间点(hour和minute)进行处理:只考虑minute为0的整点,然后按hour的连续性划分时间段(连续的小时数构成一个时间段)。 例如:某一天有[1,2,3,5,6,9]这些整点,那么连续的时间段就是[1-3], [5-6], [9](单独一个点也算一个时间段),所以这一天有3个时间段。 步骤: 1. 按day分组,同时过滤掉minute不为0的数据(因为只考虑整点)。 2. 对同一天的数据,提取hour,并去重(避免同一小时多次出现)和排序。 3. 遍历排序后的hour数组,将连续的小时合并为一个时间段(即相邻两个数差值为1则连续)。 4. 统计每个day的时间段数量,或者记录每个时间段(返回具体的时间段起止)。 但是,用户的问题中并没有要求返回具体的时间段,而是要求每天有时间段。不过,为了扩展性,我们可以返回一个对象,包含每天的时间段列表(每个时间段用起止小时表示)以及时间段数量。 根据用户需求,我们可以有两种返回形式: a) 返回每天的时间段数量(如:{day1: 3, day2: 2}) b) 返回每天的时间段列表(如:{day1: [[1,3],[5,6],[9,9]], day2: [...]}) 由于问题描述是“查看每天有时间段”,所以主要返回数量。但考虑到后续可能也需要具体时间段,我们可以设计函数返回包含详细信息的对象。 设计函数如下: 输入:数组,元素结构如示例 输出:一个对象,以day为键,值为一个对象,包含: count: 时间段数量 periods: 时间段列表,每个时间段是一个包含起始小时和结束小时的数组(如果只有一个小时,则起始和结束相同) 注意:day字段在输入中可能是数字(如0,1)或字符串(如"2024-06-01"),但示例中是数字0,1。因此,我们按原样作为键。 步骤: 1. 分组:将同一天的数据放在一起,同时过滤掉minute不为0的项。 2. 对每一天,提取所有hour,去重并排序(升序)。 3. 遍历排序后的hour数组,合并连续的小时。 - 初始化一个空数组用于存放当前连续时间段(currentPeriod),以及一个结果数组(periods)。 - 遍历每个小时,如果当前小时与前一个连续(即当前小时等于上一个连续小时的下一个),则继续当前时间段;否则,将当前时间段结束(保存)并开始新的时间段。 4. 将当前时间段保存到结果数组。 具体实现: 例如:一天的小时数组为 [1,2,3,5,6,9] 初始化:currentStart=1, currentEnd=1 遍历: i=1: 当前小时2,上一个小时1,连续:currentEnd=2 i=2: 当前小时3,连续:currentEnd=3 i=3: 当前小时5,与3不连续(5-3=2>1),则将[1,3]保存,重置currentStart=5, currentEnd=5 i=4: 当前小时6,连续:currentEnd=6 i=5: 当前小时9,与6不连续,保存[5,6],重置currentStart=9, currentEnd=9 最后保存[9,9] 因此得到三个时间段:[1,3], [5,6], [9,9] 代码实现:</think>根据您的需求,我将编写一个JavaScript函数,按天分组并统计每天的连续时间段数量。以下是实现方案: ### 解决方案代码 ```javascript function groupConsecutiveTimePeriods(data) { // 1. 按day字段分组,并过滤minute不为0的数据 const groupedByDay = data.reduce((acc, item) => { if (item.minute !== 0) return acc; // 只处理整点数据 const day = item.day; if (!acc[day]) acc[day] = new Set(); // 使用Set自动去重 acc[day].add(item.hour); return acc; }, {}); // 2. 处理每天的数据,统计连续时间段 const result = {}; for (const day in groupedByDay) { // 将Set转为数组并排序 const hours = Array.from(groupedByDay[day]).sort((a, b) => a - b); let count = 0; let currentStart = null; // 3. 遍历排序后的小时数组 for (let i = 0; i < hours.length; i++) { // 如果是第一个小时或与前一个不连续 if (i === 0 || hours[i] !== hours[i - 1] + 1) { // 结束当前时间段计数 if (currentStart !== null) count++; // 开始新的时间段 currentStart = hours[i]; } // 如果是最后一个小时,结束当前时间段 if (i === hours.length - 1 && currentStart !== null) { count++; } } result[day] = count; } return result; } ``` ### 使用示例 ```javascript // 测试数据 const testData = [ {day: 0, hour: 1, minute: 0}, {day: 0, hour: 2, minute: 0}, {day: 0, hour: 3, minute: 0}, {day: 0, hour: 5, minute: 0}, {day: 0, hour: 6, minute: 0}, {day: 0, hour: 9, minute: 0}, {day: 1, hour: 10, minute: 0}, {day: 1, hour: 11, minute: 0}, {day: 1, hour: 12, minute: 0}, {day: 1, hour: 14, minute: 0}, ]; // 执行函数 console.log(groupConsecutiveTimePeriods(testData)); /* 输出: { "0": 3, // [1-3], [5-6], [9] 共3个时间段 "1": 2 // [10-12], [14] 共2个时间段 } */ ``` ### 关键逻辑说明 1. **数据分组与过滤**: - 使用`reduce()`按`day`字段分组 - 使用`Set`自动去除重复的小时数据 - 过滤掉`minute !== 0`的非整点数据 2. **连续性检测算法**: ```javascript for (let i = 0; i < hours.length; i++) { if (i === 0 || hours[i] !== hours[i - 1] + 1) { // 开始新时间段 } // 处理时间段结束 } ``` - 当小时值不连续时(差值不为1),结束当前时间段计数 - 单个整点视为独立时间段 3. **时间复杂度**: - 分组:$O(n)$ - 排序:$O(m \log m)$(m为每天的小时数) - 总体:$O(n + m \log m)$ ### 扩展功能 如果需要获取具体的时间段范围(而不仅是数量),可修改函数为: ```javascript function getDetailedTimePeriods(data) { // ...(同前分组逻辑) const detailedResult = {}; for (const day in groupedByDay) { const hours = Array.from(groupedByDay[day]).sort((a, b) => a - b); const periods = []; let start = hours[0]; for (let i = 1; i <= hours.length; i++) { if (i === hours.length || hours[i] !== hours[i - 1] + 1) { periods.push([start, hours[i - 1]]); if (i < hours.length) start = hours[i]; } } detailedResult[day] = periods; } return detailedResult; } ``` ### 相关问题 1. 如何处理跨天的连续时间段(如23点到次日1点)? **解决方案**:添加日期计算逻辑,使用`Date`对象处理时间连续性[^3] 2. 如果数据中存在分钟非零的干扰项,如何优化过滤逻辑? **建议**:添加预处理步骤`data.filter(item => item.minute === 0)` 3. 如何扩展此函数以返回具体的连续时间段(如["1:00-3:00"])? **方案**:修改返回结构,使用模板字符串格式化时间段 ```javascript return `${start}:00-${end}:00`; ``` 4. 当数据量极大时(如百万级记录),如何优化性能? **优化策略**: - 使用Map代替Object提高分组效率 - 分批处理数据(分页或流式处理) - 使用Web Workers并行处理[^5]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值