
在许多应用场景中,我们可能需要一个计数器,其增长逻辑并非简单地持续累加,而是需要根据特定的时间条件进行控制。例如,一个任务进度计数器可能只在工作日的工作时间内进行计数,在周末或非工作时间暂停,但仍需显示当前的累积值。此外,计数器可能还需要在每个月初自动重置。
本教程将详细讲解如何使用JavaScript实现这样一个智能计数器,它具备以下核心功能:
实现此智能计数器需要精确的日期和时间判断,以及对历史数据的正确累积。以下是实现的关键步骤:
首先,我们需要获取当前的日期和时间信息,包括年份、月份、日期、星期几、小时和分钟。
立即学习“Java免费学习笔记(深入)”;
var currentDate = new Date(); var currentDay = currentDate.getDay(); // 0: Sunday, 1: Monday, ..., 6: Saturday var currentHour = currentDate.getHours(); var currentMinutes = currentDate.getMinutes(); var currentDayOfMonth = currentDate.getDate(); // 当前月份的日期 (1-31)
为了使计数器灵活可配置,我们将工作日的范围和工作时间段定义为变量。
var weekEndDays = [0, 6]; // 周末,0代表周日,6代表周六 var startHour = 6; // 工作开始小时 var endHour = 20; // 工作结束小时
基于这些定义,我们可以判断当前是否为周末或非工作时间:
var isWeekend = weekEndDays.indexOf(currentDay) > -1; // 判断是否为周末 var isOutsideWorkingHours = currentHour < startHour || currentHour >= endHour; // 判断是否在工作时间外
计数器的初始值需要根据当前月份中已经过去的工作日及其工作时间内已过去的分钟数来计算。
PrestaShop是一款针对web2.0设计的全功能、跨平台的免费开源电子商务解决方案,自08年1.0版本发布,短短两年时间,发展迅速,全球已超过四万家网店采用Prestashop进行布署。Prestashop基于Smarty引擎编程设计,模块化设计,扩展性强,能轻易实现多种语言,多种货币浏览交易,支持Paypal等几乎所有的支付手段,是外贸网站建站的佳选。Prestashop是目前为止,操作最
169
计算已过去的工作日: 我们需要遍历当前月份中从1号到前一天的所有日期,统计其中属于工作日的数量。
var daysSinceStart = 0;
for (let i = 1; i < currentDayOfMonth; i++) {
let checkDate = new Date(currentDate.getFullYear(), currentDate.getMonth(), i);
// 排除周末
if (weekEndDays.indexOf(checkDate.getDay()) === -1) {
daysSinceStart++;
}
}特殊情况处理: 如果当前是工作日,并且工作时间已经结束(例如,现在是晚上9点,但今天下午8点工作就结束了),那么今天也应该被算作一个完整的已过去工作日。
// 如果今天是工作日,且当前时间已超出工作结束时间,则将今天也算作一个完整的工作日
if (!isWeekend && isOutsideWorkingHours && currentHour >= endHour) {
daysSinceStart++;
}计算当前工作日已过去的分钟数: 如果当前处于工作日且在工作时间内,我们需要计算从工作开始时间到当前时间已经过去了多少分钟。
var minutesSinceStartOfDay = 0;
if (!isWeekend && !isOutsideWorkingHours) {
minutesSinceStartOfDay = (currentHour - startHour) * 60 + currentMinutes;
}计数器的初始值是已过去工作日的总分钟数,加上当前工作日已过去的分钟数。每天的工作分钟数是 (endHour - startHour) * 60。
var workingMinutesPerDay = (endHour - startHour) * 60; var counter = daysSinceStart * workingMinutesPerDay + minutesSinceStartOfDay;
使用 setInterval 定时器每分钟更新计数器。关键在于,在 setInterval 的回调函数内部,再次检查当前时间是否符合增量条件。如果符合,则 counter++;如果不符合,则只显示当前值而不增量。
var intervalId = setInterval(function() {
// 每次增量前重新获取并判断当前时间
var now = new Date();
var currentDayNow = now.getDay();
var currentHourNow = now.getHours();
var isWeekendNow = weekEndDays.indexOf(currentDayNow) > -1;
var isOutsideWorkingHoursNow = currentHourNow < startHour || currentHourNow >= endHour;
if (isWeekendNow || isOutsideWorkingHoursNow) {
console.log('Counter (paused):', counter); // 暂停时也显示值
} else {
counter++;
console.log('Counter (active):', counter);
}
// 可选:添加月底重置逻辑,需要更精确的日期判断
// 如果是月底最后一天且工作时间已过,或下个月1号,则重置
// 这里为了简洁,不在setInterval内做复杂重置,通常在页面加载时计算初始值即可
// 或者通过外部调度任务在每月1号凌晨触发重置
}, 60000); // 60000毫秒 = 1分钟重要提示: setInterval 并不是处理精确时间间隔的最佳方式,尤其是在长时间运行的应用中,它可能会受到浏览器标签页不活跃、系统休眠等因素的影响导致不准确。对于需要高度精确的计数,更好的方法是在页面加载时根据当前时间精确计算出应有的值,并仅在需要时进行刷新显示。然而,对于本例中的分钟级增量,setInterval 已经足够演示基本逻辑。
将上述逻辑整合到 startCounter 函数中:
function startCounter() {
// 获取当前日期和时间
var currentDate = new Date();
var currentDay = currentDate.getDay(); // 0: Sunday, 1: Monday, ..., 6: Saturday
var currentHour = currentDate.getHours();
var currentMinutes = currentDate.getMinutes();
var currentDayOfMonth = currentDate.getDate(); // 当前月份的日期 (1-31)
// 定义工作日和工作时间
var weekEndDays = [0, 6]; // 周末:周日(0), 周六(6)
var startHour = 6; // 工作开始小时 (6 AM)
var endHour = 20; // 工作结束小时 (8 PM)
// 判断当前是否为周末或非工作时间
var isWeekend = weekEndDays.indexOf(currentDay) > -1;
var isOutsideWorkingHours = currentHour < startHour || currentHour >= endHour;
// 计算当前月份已过去的工作日天数
var daysSinceStart = 0;
for (let i = 1; i < currentDayOfMonth; i++) {
let checkDate = new Date(currentDate.getFullYear(), currentDate.getMonth(), i);
if (weekEndDays.indexOf(checkDate.getDay()) === -1) { // 如果不是周末
daysSinceStart++;
}
}
// 如果今天是工作日,且当前时间已超出工作结束时间,则将今天也算作一个完整的工作日
if (!isWeekend && isOutsideWorkingHours && currentHour >= endHour) {
daysSinceStart++;
}
// 计算当前工作日已过去的分钟数
var minutesSinceStartOfDay = 0;
if (!isWeekend && !isOutsideWorkingHours) {
minutesSinceStartOfDay = (currentHour - startHour) * 60 + currentMinutes;
}
// 计算每天的工作分钟数
var workingMinutesPerDay = (endHour - startHour) * 60;
// 初始化计数器:已过去工作日总分钟数 + 当前工作日已过去分钟数
var counter = daysSinceStart * workingMinutesPerDay + minutesSinceStartOfDay;
// 在控制台显示初始状态
if (isWeekend || isOutsideWorkingHours) {
console.log('Counter paused. Current value:', counter);
} else {
console.log('Counter starting. Current value:', counter);
}
// 每分钟增量计数器
var intervalId = setInterval(function() {
// 在每次增量前重新判断当前时间,以应对时间流逝
var now = new Date();
var currentDayInInterval = now.getDay();
var currentHourInInterval = now.getHours();
var isWeekendInInterval = weekEndDays.indexOf(currentDayInInterval) > -1;
var isOutsideWorkingHoursInInterval = currentHourInInterval < startHour || currentHourInInterval >= endHour;
// 检查是否需要每月重置
// 这是一个简化的重置逻辑,更健壮的方案可能需要服务器端或持久化存储来确保重置的准确性
// 如果当前是新月份的第一天,且之前计数器是上个月的,则重置
// 这里假设页面刷新会重新计算,但对于持续运行的场景,需要更复杂的判断
if (now.getDate() === 1 && currentDate.getMonth() !== now.getMonth()) {
// 如果月份变化到新月份的1号,则重置计数器
// 重新计算当月1号的初始值
currentDate = now; // 更新当前日期
currentDay = currentDate.getDay();
currentHour = currentDate.getHours();
currentMinutes = currentDate.getMinutes();
currentDayOfMonth = currentDate.getDate();
isWeekend = weekEndDays.indexOf(currentDay) > -1;
isOutsideWorkingHours = currentHour < startHour || currentHour >= endHour;
daysSinceStart = 0; // 新月份从0天开始
minutesSinceStartOfDay = 0;
if (!isWeekend && !isOutsideWorkingHours) {
minutesSinceStartOfDay = (currentHour - startHour) * 60 + currentMinutes;
}
counter = daysSinceStart * workingMinutesPerDay + minutesSinceStartOfDay;
console.log('Counter reset for new month. New value:', counter);
return; // 重置后本次不增量
}
if (isWeekendInInterval || isOutsideWorkingHoursInInterval) {
console.log('Counter (paused):', counter);
} else {
counter++;
console.log('Counter (active):', counter);
}
}, 60000); // 每分钟执行一次
// 页面加载时显示初始值
console.log('Initial Counter Value on page load:', counter);
}
// 启动计数器
startCounter();通过上述JavaScript代码和逻辑,我们成功构建了一个能够根据特定工作日和工作时间进行增量,并在非工作时间暂停但显示当前值的智能计数器。该方案考虑了历史累积和月度重置的需求,为构建时间敏感型应用提供了基础。开发者可以根据自身需求,进一步优化其持久化、精确性和用户界面集成。
以上就是JavaScript实现基于工作时间段的智能计数器的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号