Изменить частицы, если зима в javascript

У меня есть две конфигурации (json) для js частиц. Один из них предназначен для зимнего времени, поэтому он должен быть активен с 21 декабря по 21 марта. Я много чего пробовал, но все равно не работает (не потому, что еще ноябрь :)) Последнее, что я пробовал, это это

var today = new Date();
var tDate = today.getDate();
var tMonth = today.getMonth();

var startingDate = new Date();
var sDate = startingDate.setDate(1);
var sMonth = startingDate.setMonth(10);

var endingDate = new Date();
var eDate = endingDate.setDate(21);
var eMonth = endingDate.setMonth(2);

if (tMonth >= sMonth && tMonth <= eMonth) {
    if (tDate >= sDate && tDate <= eDate) {
        particlesJS.load('particles', '../../Content/Scripts/particles/particles-config-winter.json');
    }
}
else {
    particlesJS.load('particles', '../../Content/Scripts/particles/particles-config.json');
}

Это не имеет смысла, потому что дата начала и окончания - 21. Я пытался сравнить как строку, не вышло. У меня нет идей, как сравнить две даты в javascript. Любая помощь?

🤔 А знаете ли вы, что...
JavaScript имеет множество встроенных объектов, таких как Array, Date и Math.


2
163
3

Ответы:

Решено

Вы можете использовать эту функцию:

function isWinter(dt) {
    const m = dt.getMonth();
    return m == 11 ? dt.getDate() >= 21 : m == 2 ? dt.getDate() < 21 : m < 2;
}

Назовите это сегодняшней датой так:

if (isWinter(new Date())) {  /*....*/ }

Одна из проблем в вашей попытке заключается в том, что методы setMonth и setDate возвращают измененную дату как количество миллисекунд (а не только часть месяца или дня) и изменяют дату вызова метода.

Пояснение к функции:

Тернарное выражение использует эту логику:

  • Если месяц декабрь (11), то верните true, если день месяца равен как минимум 21, или false в противном случае: это то, что оценивает dt.getDate() >= 21 (истина или ложь).
  • В противном случае, если месяц - март (2), тогда верните true, если день месяца меньше 21, или false в противном случае: тот же принцип, что и выше, но в обратном порядке.
  • В противном случае верните true, если месяц предшествует марту (<2), и false в противном случае: это то, что оценивает m < 2.

Манипуляции со свиданием - это всегда борьба. Если вы не возражаете, чтобы библиотеки справились с этим за вас, я бы посоветовал вам взглянуть на MomentJs, который упрощает управление датой и временем. Однако в каждую добавляемую библиотеку вы добавляете ненужный код, который может вам не понадобиться. Поэтому, если вам нужно сделать только несколько манипуляций с датой, это может не стоить того, и Тринкоотвечать идеально подходит, если вам действительно не нужны MomentJs.

Следуя строке ответа trincot, вот как вы делаете то же самое в MomentJs:

function isWinter(date){
  date.year(moment().year()); //Normalize year.
  let winterStart = moment('21-12', 'DD-MM');
  let winterEnd = moment('21-03', 'DD-MM');
  return !date.isBetween(winterEnd, winterStart, 'day')
}
//Tests:
let today = moment('20-12', 'DD-MM');
alert(isWinter(today)); //false
today = moment('21-12', 'DD-MM');
alert(isWinter(today)); //true
today = moment('21-03', 'DD-MM');
alert(isWinter(today)); //true
today = moment('22-03', 'DD-MM');
alert(isWinter(today)); //false
today = moment('22-03-2019', 'DD-MM-YYYY');
alert(isWinter(today)); //false
today = moment('21-03-2019', 'DD-MM-YYYY');
alert(isWinter(today)); //true
<script src = "https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js"></script>

Чтобы объяснить, почему ваш код не работает:

var today = new Date();
var tDate = today.getDate();
var tMonth = today.getMonth();

var startingDate = new Date();

// This sets the date to the first of the month, and sets sDate to a number
// that is the time value of the adjusted date
var sDate = startingDate.setDate(1);

// This sets the month to November and sMonth to the adjusted time value
var sMonth = startingDate.setMonth(10);

var endingDate = new Date();

// As above, this sets endingDate to 21 March and sets eDate and eMonth to numbers
var eDate = endingDate.setDate(21);
var eMonth = endingDate.setMonth(2);

// This will never be true after 1970-01-01 as you're comparing a months to a time values
if (tMonth >= sMonth && tMonth <= eMonth) {
  if (tDate >= sDate && tDate <= eDate) {

Даже если при этом использовались правильные значения, логика не работает, поскольку даже для даты в диапазоне, вы затем сравниваете дату (номер дня), тогда как это следует сравнивать только в том случае, если месяц март или ноябрь, а не какой-либо другой месяц (согласно ответу Тринко).

Будет проще, если вы создадите даты 21 марта и 21 декабря текущего года, а затем посмотрите, попадает ли текущая дата в диапазон. Если да, то это не зима. Если нет, то сейчас зима. Я предполагал, что диапазон является исчерпывающим, измените даты, если это не так.

function isWinter(date = new Date()) {
  var start = new Date(date.getFullYear(), 2, 21);
  var end = new Date(date.getFullYear(), 11, 21);
  return date > start && date < end;
}

[new Date(2018, 0, 1), //  1 Jan 2018, winter
 new Date(2018, 2,21), // 21 Mar 2018, winter
 new Date(2018, 5, 1), //  1 Jun 2018, not winter
 new Date(2018,11,21), // 21 Dec 2018, winter
 new Date()            // Today ...
].forEach(d => console.info(`${d} is ${isWinter(d)?'not ':''}winter`));