#javascript #datetime
#javascript #дата и время
Вопрос:
Если пользователь устанавливает дату на серверной части (с помощью средства выбора даты и времени jQuery), следующая acf_vars.timer
переменная будет выглядеть следующим образом во внешнем интерфейсе:
2021 2 9 13 08 00
У меня есть следующая конструкция в качестве таймера обратного отсчета (CODEPEN):
const [y, month, d, h, minute, s] = acf_vars.timer.split(' ');
// monthIndex in Date Object begins with 0, so we subtract 1
const countDownDate = new Date(y, month - 1, d, h, minute, s).getTime();
const updateCountdown = () => {
const now = new Date().getTime(); // Get today's date and time
const distance = countDownDate - now; // Find distance between now and the countdown date
const expiredTimer = distance <= 0;
let days = Math.floor(distance / (1000 * 60 * 60 * 24));
let hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
let minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
let seconds = Math.floor((distance % (1000 * 60)) / 1000);
if (expiredTimer) {
days = hours = minutes = seconds = 0;
clearInterval(timerInterval);
}
document.querySelectorAll('.ticker').forEach((container) => {
container.children[0].classList.contains('days') amp;amp;
(container.children[0].textContent = days);
container.children[2].classList.contains('hours') amp;amp;
(container.children[2].textContent = hours);
container.children[4].classList.contains('minutes') amp;amp;
(container.children[4].textContent = minutes);
container.children[6].classList.contains('seconds') amp;amp;
(container.children[6].textContent = seconds);
});
};
const timerInterval = setInterval(updateCountdown, 1000);
updateCountdown();
Если пользователь не указывает будущую дату в серверной части, я бы хотел использовать резервный вариант, который автоматически устанавливает таймер обратного отсчета на предстоящее воскресенье в 9 утра. Чтобы решить эту проблему, я попытался установить стандартную countDownDate
переменную, но у меня возникли проблемы с поиском способа автоматически установить день и время на предстоящее воскресенье в 9 утра.
Ответ №1:
Кажется, вам просто нужен способ установить дату на следующее воскресенье в 09:00. В обычном JS это может быть:
/* Get a date for next occurence of Sunday at 09:00
*
* @param {Date} d - start date, default is current date and time
* @returns {Date} for next Sunday at 09:00 after d
*/
function getNextSunday(d = new Date()) {
// Create date for next Sun at 9
let sun = new Date(d.getFullYear(), d.getMonth(), d.getDate() (7 - (d.getDay() || 7)), 9, 0, 0, 0);
// If date is same day but later, move to next Sun
sun <= d? sun.setDate(sun.getDate() 7) : null;
return sun;
}
// Examples
// Next Sunday at 9:00
console.log(getNextSunday().toString());
// Next Sunday after Sun 7 Feb at 8:59:59
console.log(getNextSunday(new Date(2021, 1, 7, 8, 59, 59)).toString());
// Next Sunday after Sun 7 Feb at 9:00
console.log(getNextSunday(new Date(2021, 1, 7, 9)).toString());
Примечания:
d.getDay() || 7
используется так, что если getDay возвращает 0 (воскресенье), он заменяется числом 7. Это означает, что выражение устанавливает sun на текущий день, если это воскресенье, или на следующее воскресенье, если это не так. В противном случае по воскресеньям он будет создавать дату для предыдущего воскресенья.sun <= d? sun.setDate(sun.getDate() 7) : null
используется так, что если текущая дата — воскресенье, но время после указанного времени (в данном случае 9:00), дата переносится на следующее воскресенье в 9:00. Использование составного? :
оператора таким образом — это просто еще один способ записиif (sun <= d) sun.setDate(sun.getDate() 7)
в одной строке. Я предпочитаю, чтобы за операторами if следовал блок, и предпочел бы использовать? :
для простых выражений в отдельных строках.
Комментарии:
1. Это отличное ванильное решение. Два вопроса: не могли бы вы объяснить, когда и почему оператор OR в
(d.getDay() || 7))
будет важен? Посколькуd.getDay()
всегда будет что-то возвращать, почему мы включаем это? И не могли бы вы объяснить, что вы имеете в видуIf date is same day but later, move to next Sun
? Я думаю, что ваши комментарии уже дают отличное представление, я просто хочу убедиться, что я полностью понимаю концепцию при использовании. Спасибо!
Ответ №2:
Moment.js возможно, это то, что вы ищете.
moment().endOf('week').add(1, 'second').add(9, 'hours').toString()
В конце недели используется день начала недели с учетом локали, поэтому вам может потребоваться настроить его, если у вас есть пользователи по всему миру.
Редактировать
Кроме того, если вы не хотите использовать внешние библиотеки, вы можете проверить текущий день недели и час с помощью объекта даты JavaScript.
const day = countDownDate.getDay() // weekday sun = 0, sat = 6
const hour = countDownDate.getHours() // 0 - 23
По вашей логике вы хотели бы получить значение distance
между днем и 0 (также с учетом countDownDate
начала воскресенья) и часом и 9. Однако другой способ реализовать это — проверять текущую дату при каждом обновлении, что может уменьшить ошибку в случае прерывания интервала.
Комментарии:
1. Спасибо за указатель. Как вы думаете, стоило бы потратить усилия на разборку используемых методов, если бы я не хотел использовать
moment
библиотеку?2. Конечно, я обновил свой ответ. Я думал, вас заинтересует moment.js поскольку вы уже использовали jquery.
3. «В конце недели используется день начала недели с учетом локали «, что означает, что вы понятия не имеете, что это будет. Если предполагается установить его на воскресенье григорианского календаря, то сделайте именно это.