Ответы пользователя по тегу Работа с датой/временем
  • Как сгенировать массив из времени с интервалом?

    Удобно работать с объектами Date.
    const makeDate = HHMM => {
      const [H, M] = HHMM.split(':').map(Number);
      const D = new Date();
      D.setHours(H);
      D.setMinutes(M);
      D.setSeconds(0);
      return D;
    };
    
    const oo = n => n.toString().padStart(2, '0'); // 5 => '05'
    
    const fillTime = (startHHMM, finishHHMM, intervalMinutes) => {
      let startDate = makeDate(startHHMM);
      let finishDate = makeDate(finishHHMM);
      if (startDate > finishDate) { // объекты Date можно так сравнивать
        [startDate, finishDate] = [finishDate, startDate]; // поменять местами
      }
    
      const dates = [];
      const D = new Date(startDate);
      while (D <= finishDate) {
        dates.push(new Date(D));
        D.setMinutes(D.getMinutes() + intervalMinutes);
      }
    
      return dates.map(D => [D.getHours(), D.getMinutes()].map(oo).join(':'));
    };
    
    console.log(fillTime('15:56', '18:15', 17));
    // [ "15:56", "16:13", "16:30", "16:47", "17:04", "17:21", "17:38", "17:55", "18:12" ]
    Ответ написан
    1 комментарий
  • Как узнать даты до определённого числа?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Объект Date в JavaScript умеет всё что нужно.
    Парсить дату:
    const D = new Date('2022-08-01'); // объект Date с указанной датой


    Добавлять дни:
    const D = new Date(); // сегодня, сейчас
    D.setDate( D.getDate() + 1 ); // завтра
    месяц, год – при надобности изменятся автомагически.
    Ответ написан
    1 комментарий
  • Как лучше реализовать постоянный отсчёт времени и суммирование значений?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    Надо ли иметь в БД статичное значение баллов? Может, оставить свойство вычисляемым — когда требуется узнать про конкретного пользователя, сколько у него баллов — выполняется поиск купленных им карточек за последние 10 дней и до сих пор активных, и суммируются.

    Либо можно обновлять базу cron-задачей. Округлить до какого-то интервала времени: 1 сутки (если все в одном городе), или 1 час, если пользователи со всех частей света. Карта начинает действовать в ближайший следующий «момент» после активации. В ближайшую полночь, скажем.

    1000 пользователей по 5 карточек — это не нагрузка, всё легко отработает.
    Ответ написан
    1 комментарий
  • Как получить разницу между двумя датами в днях и в часах в плагине datetimepicker?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Сначала получить разницу между двумя объектами Date в часах.
    Затем посмотреть, сколько в эти часы влезает целых суток, и вычесть их.

    const diffHours = Math.ceil((endDate - startDate) / 36e5); // точно в бОльшую сторону округлять?
    const days = Math.floor(diffHours / 24);
    const hours = diffHours - days * 24;
    
    console.log(`Срок аренды: ${days} дней и ${hours} часов`);
    Ответ написан
    1 комментарий
  • Как сделать алгоритм, выполняющий команду в определенное время?

    Время стоит хранить в Unix time. Получили от пользователя часы и его пояс, сразу перевели в timestamp, сохранили целое число.

    Как отправлять. Есть системные механизмы, например cron в Linux. Можно попробовать сделать свой велосипед по мотивам: в общем это бесконечный цикл, который смотрит, не пора ли что-ньть сделать «сейчас».
    Ответ написан
  • Как форматировать дату?

    const months_RU = 'Января,Февраля,Марта,Апреля,Мая,Июня,Данунаф,Лень,Дальше,Сами'
      .split(',');
    const parseDate = d => d.split('.')
      .reduce((acc, c, i) => (acc.unshift(i & 1 ? months_RU[+c - 1] : +c), acc), [])
      .join(' ');


    Использование: parseDate('2020.06.01') // "1 Июня 2020"

    Как это работает:
    По точкам разбить в массив строк ['2020', '06', '01'];
    собрать в массив задом-наперёд (день, месяц, год) – вставить в начало массива .unshift();
    Месяц – элемент нечётный, последний бит = 1, проверка i & 1 вернёт 1 только для месяца;
    месяц заменить на название из массива. Там нумерация с 0, поэтому -1.
    Остальные (год и дату) просто сделать из строки – числом, через унарный оператор +
    Получится массив [1, 'Июня', 2020]
    Склеить его элементы в строку через пробел: join(' ')
    Ответ написан
    Комментировать
  • Как вычесть из сегодняшней даты 3 дня и сравнить с условной датой, и если до условной даты остается 3 дня то выдать сообщение?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    const gotTime = (dateStr, days) => {
      const che = new Date(dateStr); // дата события
      che.setDate(che.getDate() - days); // N дней до события
      return che - new Date() > 0; // ещё не наступила граница N-дней-до-события
    }
    
    gotTime('2019-11-14T09:07:02.376+00:00', 3); // true
    
    // сегодня 2019-10-15
    gotTime('2019-10-19T09:07:02.376+00:00', 3); // true
    gotTime('2019-10-18T09:07:02.376+00:00', 3); // false
    gotTime('2019-10-17T09:07:02.376+00:00', 3); // false
    Ответ написан
    Комментировать
  • Как получить весь список дней в году вида 03/10/2019?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Надо создать объект Datе в текущем году, установить его на 1-е января setDate(1), setMonth(0) и прибавлять по 1 дню. Месяца перевернутся автомагически.

    Для форматирования mm/dd/yyyy можно использовать локальный формат дат для США, указав в опциях, что даты и месяц выводить как 2-цифры.
    const dates = [];
    const options = { year: 'numeric', month: '2-digit', day: '2-digit' };
    const d = new Date();
    d.setMonth(0);
    d.setDate(1);
    const year = d.getFullYear();
    while(d.getFullYear() === year) {
      dates.push(d.toLocaleDateString('en-US', options));
      d.setDate(d.getDate() + 1);
    }
    
    /*
    01/01/2019
    01/02/2019
    01/03/2019
    01/04/2019
    01/05/2019
    01/06/2019
    01/07/2019
    01/08/2019
    01/09/2019
    01/10/2019
    ...
    */
    Ответ написан
    1 комментарий
  • Как высчитывать количество дней до определенной даты?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Разбить строку по точке в массив [дата, месяц, год], у сегодняшней даты сбросить часы, минуты, секунды, миллисекунды на ноль - чтобы тоже начало дня было. Посчитать разницу двух дат в миллисекундах, перевести в сутки:
    function daysTill(ddmmyyyy) {
    	let dd, mm, yyyy;
    	[dd, mm, yyyy] = ddmmyyyy.split('.');
    	const Till = new Date(yyyy, mm-1, dd);
    	const Now = new Date();
    	return Math.floor((Till - Now) / 864e5);
    }
    	
    daysTill("01.03.2019") // 13
    Ответ написан
    Комментировать
  • Как найти конец недели?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    function getEndOfWeek() {  
      const D = new Date();
      D.setDate(D.getDate() - D.getDay() + (D.getDay() ? 7 : 0));
      D.setHours(23, 59 - D.getTimezoneOffset(), 59, 0);
      return D.toISOString().slice(0, 19).replace('T', ' ').replace(/-/g,'/');
    }
    
    getEndOfWeek() // 2019/02/17 23:59:59
    Ответ написан
    Комментировать
  • Как получить число и месяц, преобразов переменную на php?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    Можно получить время, скажем, понедельника на этой неделе через относительный формат времени strtotime('monday this week'); (только на англ.)
    $rusdate='ПТ 18:00';
    list($dow, $hours, $minutes) = sscanf($rusdate, "%s %d:%d");
    
    $rusweek = explode(',','ВС,ПН,ВТ,СР,ЧТ,ПТ,СБ');
    $ndow = array_search($dow, $rusweek);
    
    date_default_timezone_set('Europe/Moscow'); // если не настроен PHP
    $time = strtotime('monday this week') + 86400 * $ndow + 3600 * $hours + 60 * $minutes;
    echo date('Y-m-d H:i:s', $time);
    // 2018-10-13 18:00:00
    Ответ написан
  • Как вывести текущую дату + завтрашнюю или послезавтрашнюю?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Можно менять номер дня — прибавлять дни, не боясь выйти за рамки месяца:
    const today = new Date(); // сегодня, сейчас. 22 сентября
    
    const tomorrow = new Date();
    tomorrow.setDate( tomorrow.getDate() + 1); // +1 день, 23 сентября, это же время.
    
    const plus13days = new Date();
    plus13days.setDate( plus13days.getDate() + 13); // +13 дней, 5 октября
    Ответ написан
    Комментировать
  • Как получить предыдущую дату с moment.js?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    moment не пользуюсь, поэтому на чистом JS можно создать дату на сейчас, установить ей нужные день и месяц (1 августа).
    Если дата получилась больше, чем сейчас, надо отнять 1 год:
    var D = new Date();
    D.setDate(1);
    D.setMonth(7);   // 0: Янв, 1: Фев, ... 7: Август
      D.setHours(12);  // опционально
      D.setMinutes(0); // опционально
      D.setSeconds(0); // опционально
    if(D.getTime() > new Date().getTime()) D.setFullYear( D.getFullYear() - 1);
    
    D.toString() // Tue Aug 01 2017 12:00:00 GMT+0300 (MSK)
    
    // и можно из Даты создать объект moment:
    var m = moment(D);


    Наверняка, точно такой же фокус можно провести и с объектом самого moment.
    Ответ написан
    Комментировать
  • Как можно получить массив дат от определенной даты?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Сделать объект даты на тот момент, и прибавлять по дню.

    var D = new Date("2017-08-27")
      , Till = new Date()
      , result = []
    ;
    
    function pad(s){ return ('00' + s).slice(-2)}
    
    while( D.getTime() < Till.getTime()) {
      result.push( '' + D.getFullYear() +'-'+ pad(D.getMonth()+1) +'-'+ pad(D.getDate()));
      D.setDate( D.getDate()+1);
    }
    //  2017-08-27,2017-08-28,2017-08-29,2017-08-30,2017-08-31
    Ответ написан
    Комментировать
  • Как сделать автоматическую смену даты js?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    var dt = new Date();
    var date = dt.getDate();
    if( date < 15) dt.setDate(1); // до 15-го числа будет 1-е
    else dt.setDate(15); // после 15-го – 15-е
    
    // Display the month, day, and year. getMonth() returns a 0-based number.
    var day = dt.getDate();
    var month = dt.getMonth()+1;
    var year = dt.getFullYear();
    document.write(day + '-' + month + '-' + year);
    Ответ написан
    Комментировать
  • Как сделать, чтобы меньшие числа давали больше очков?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    Буквально ваши правила реализуются подобным JavaScript кодом – с условиями:
    function getPostScore(time) {
      var diff = Math.floor((new Date()).getTime()/1000) - time;
      if( diff <= 3600) return 50000;
      else if( diff <= 7200) return 25000;
      else if( diff <= 10800) return 10000;
      else return 0;
    }
    
    getPostScore(1493487180); // 10000


    Но ступенчатость значений, наверное, не вполне оправдана и лучше будет какой-то гладкой функцией. Например, вида y = k / x
    af5c49df83bb430f9f7ba91b2c6bc147.png
    С коэффициентом k = 50000 * 3600 она удачно захватывает и вторую точку. Но плоха тем, что ближе к нулю зашкаливает в +бесконечность.

    Наверное, для вашей задачи уместнее S-образная кривая – сигмоида, задаваемая формулой вида y = 1 / (1 + e-x) Примерно подобрал коэффициенты:
    ecd0f96a15224fe2ac9fb125e7305b8f.png
    function getPostSigma(time){
      var diff = Math.floor((new Date()).getTime()/1000) - time;
      return Math.round( 10000 + 40000 / (1 + Math.exp((diff-6800)/700)));
    }
    
    getPostSigma(1493531780); // 49998
    getPostSigma(1493522780); // 11545
    Ответ написан
    Комментировать
  • Как вычислить точную разницу между датами в годах?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Создаём два объекта Date, день рождения и сейчас. Чтобы гарантированно правильно получить из текстовой строки объект даты, надо привести её сначала к формату ISO 8601 – самое простое, заменить пробел на букву "T". Но такая дата будет в часовом поясе UTC, надо её скорректировать, добавив минуты из getTimezoneOffset(). Например, дата "2014-09-12 00:00:00" по Мск, это 11 сентября 21:00 по UTC. При сравнении из «сейчас» будем брать время по UTC – getUTCMonth() и т.п.

    Получив две даты, сравним их месяца, даты. Если нужна бОльшая точность, то ещё и часы, минуты, секунды:
    var sqlDT = "2014-09-12 00:00:00";
    var BD = new Date( sqlDT.replace(' ','T'));
    var Now = new Date();
    BD.setMinutes( BD.getMinutes() + Now.getTimezoneOffset()); // в UTC
    
    if( BD.getMonth() === Now.getUTCMonth()
      && BD.getDate() === Now.getUTCDate()
    ) {
      // ура! День рождения!
    }


    P.s. альтернативный вариант – подключить здоровенную библиотеку для работы с датами и временем – MomentJS, и найти подходящие методы в ней.
    Ответ написан
    Комментировать