#javascript #date
Вопрос:
Мне нужно исправить этот код, чтобы получить дату дня, выбранную для определенного месяца, из выбранного. Например, когда пользователь выбирает Октябрь в качестве месяца и вторник в качестве дня, в нем будет указана дата вторника в октябре.
Этот код работает только для понедельника.
Полный код здесь: Скрипка
function getAllInstancesOfDayInMonth(fordate, forday) {
fordate.setDate(1);
var start = getStartDay(fordate, forday)
,month = fordate.getMonth()
,result = [start];
while (fordate.getMonth() == month) {
result.push(new Date(fordate.setDate(fordate.getDate() 7)));
}
return result.slice(0,-1);
function getStartDay(d, forday) {
return d.getDay() != forday
? ( d.setDate( d.getDate() 1 ), getStartDay(d, forday) )
: new Date(d);
}
}
(function () {
document.querySelector('#ddlMonths')
.addEventListener('change', getDays);
var result = document.querySelector('#result');
result.innerHTML = '<h3>Selected day </h3>';
result.innerHTML = getAllInstancesOfDayInMonth(
new Date([2015,1,1].join('/')), 1
).join('n');
function getDays(e){
var year = this.getAttribute('data-year')
,month = this.options[this.selectedIndex].value
,monthstr = this.options[this.selectedIndex].innerHTML;
result.innerHTML = '<h3>all mondays in ' monthstr ' ' year '</h3>';
result.innerHTML = getAllInstancesOfDayInMonth(
new Date([year,month 1,1].join('/')), 1
).join('n');
}
function getAllInstancesOfDayInMonth(fordate, forday) {
fordate.setDate(2);
var start = getStartDay(fordate, forday)
,month = fordate.getMonth()
,result = [start];
while (fordate.getMonth() == month) {
result.push(new Date(fordate.setDate(fordate.getDate() 7)));
}
return result.slice(0,-1);
function getStartDay(d, forday) {
return d.getDay() != forday
? ( d.setDate( d.getDate() 1 ), getStartDay(d, forday) )
: new Date(d);
}
}
}())
Комментарии:
1. Вы имеете в виду, что если выбран месяц и день
Tuesday
, то вы хотите, чтобы все даты этого месяца сохранялисьTuesday
?
Ответ №1:
В вашем коде есть несколько проблем. Давайте рассмотрим их один за другим.
Значения в элементе select для дней не все уникальны. Исправьте их следующим образом:
<select id="ddlDay" class="form-control">
<option value="0">Monday</option>
<option value="1">Tuesday</option>
<option value="2">Wednesday</option>
<option value="3">Thursday</option>
<option value="4">Friday</option>
<option value="5">Saturday</option>
<option value="6">Sunday</option>
</select>
Теперь перейдем к javascript…
Во-первых, ваша getDays
функция вызывается только при изменении элемента выбора месяцев, а не элемента выбора дней. Мы добавляем следующее, чтобы ваш дисплей также обновлялся при изменении дня:
document.querySelector('#ddlDay')
.addEventListener('change', getDays);
Внутри getDays
функции выбранный пользователем день никогда не вызывается, поэтому дисплей привязан к понедельнику. Мы можем исправить это следующим образом:
var year = document.querySelector("#ddlMonths").getAttribute('data-year'),
month = parseInt(document.querySelector("#ddlMonths").value) 1,
monthstr = document.querySelector("#ddlMonths option:checked").innerText,
day = parseInt(document.querySelector("#ddlDay").value) 1,
daystr = document.querySelector("#ddlDay option:checked").innerText;
Этот код определенно мог бы использовать некоторое упрощение, но он просто работает. Обратите внимание, что month
day
переменные и также должны быть преобразованы в соответствующие значения int перед вводом в getAllInstancesOfDayInMonth
функцию.
Наконец, мы обновляем дисплей и соответствующим образом запускаем вышеуказанную функцию:
result.innerHTML = '<h3>all ' daystr 's in ' monthstr ' ' year '</h3>';
result.innerHTML = getAllInstancesOfDayInMonth(
new Date([year,month,1].join('/')), day % 7
).join('n');
Я думаю, что это должно быть все. Рабочую скрипку можно найти здесь: https://jsfiddle.net/m9nvekhd
Комментарии:
1. Нет проблем, я надеюсь, вы видите, что в вашей реализации пошло не так. Я также настоятельно рекомендую взглянуть на общее повторение вашего кода мистером Джоджо, которое намного чище.
Ответ №2:
Я думаю, что у тебя все очень сложно
const
myForm = document.forms['my-form']
, dateYM = { year: 'numeric', month: 'long'}
, dateLong = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' }
, setDays =_=>
{
let dt = new Date(`${myForm.Months.dataset.year}-${myForm.Months.value}-1`)
, mRef = dt.getMonth()
;
myForm.result.innerHTML = `<h3>All ${myForm.Day.selectedOptions[0].textContent}in ${dt.toLocaleDateString('en-US',dateYM)} </h3>n`
;
while ( mRef === dt.getMonth() )
{
if ( dt.getDay() == myForm.Day.value )
myForm.result.innerHTML = dt.toLocaleDateString('en-US',dateLong) 'n'
dt.setDate(dt.getDate() 1)
} }
myForm.oninput = setDays
setDays() // init
body {
font : 12px/15px normal verdana, arial;
margin : 1.5em;
}
output {
display : block;
white-space : pre;
margin-top : 2em;
}
<form name="my-form">
<select name="Months" data-year="2021">
<option value="1" > January </option>
<option value="2" > February </option>
<option value="3" > March </option>
<option value="4" > April </option>
<option value="5" > May </option>
<option value="6" > June </option>
<option value="7" > July </option>
<option value="8" > August </option>
<option value="9" > September </option>
<option value="10"> October </option>
<option value="11"> November </option>
<option value="12"> December </option>
</select>
Select a month to retrieve all
<select id="Day">
<option value="1" >Monday </option>
<option value="2" >Tuesday </option>
<option value="3" >Wednesday </option>
<option value="4" >Thursday </option>
<option value="5" >Friday </option>
<option value="6" >Saturday </option>
<option value="0" >Sunday </option> <!-- sunday JS is 0 -->
</select>
of it
<output name="result"></output>
</form>