Nano Hash - криптовалюты, майнинг, программирование

Получить последние 12 месяцев в PHP

Итак, вот интересная проблема, которую я узнал сегодня.

Мне нужно заполнить массив за последние 12 месяцев, начиная с последнего месяца. Таким образом, в августе 2011 года последние 12 месяцев будут с сентября 2010 года по июль 2011 года. Для этого я использую:

for ($i = 1; $i <= 12; $i++)
    $months[] = date("Y-m%", strtotime("-$i months"));

Приведенный выше код отлично работает 30 августа. Я получаю последние 12 месяцев:

array
    0 => string '2011-07%' (length=8)
    1 => string '2011-06%' (length=8)
    2 => string '2011-05%' (length=8)
    3 => string '2011-04%' (length=8)
    4 => string '2011-03%' (length=8)
    5 => string '2011-02%' (length=8)
    6 => string '2011-01%' (length=8)
    7 => string '2010-12%' (length=8)
    8 => string '2010-11%' (length=8)
    9 => string '2010-10%' (length=8)
    10 => string '2010-09%' (length=8)
    11 => string '2010-08%' (length=8)

Но когда я запускаю это 31 августа, я получаю:

array
    0 => string '2011-07%' (length=8)
    1 => string '2011-07%' (length=8)
    2 => string '2011-05%' (length=8)
    3 => string '2011-05%' (length=8)
    4 => string '2011-03%' (length=8)
    5 => string '2011-03%' (length=8)
    6 => string '2011-01%' (length=8)
    7 => string '2010-12%' (length=8)
    8 => string '2010-12%' (length=8)
    9 => string '2010-10%' (length=8)
    10 => string '2010-10%' (length=8)
    11 => string '2010-08%' (length=8)

Я пробовал и Windows, и Unix. У кого-нибудь есть решение для этого?

31.08.2011

Ответы:


1

Я уверен, что у кого-то есть более элегантное решение, но вы могли бы начать обратный отсчет с 1 числа этого месяца.

for ($i = 1; $i <= 12; $i++) {
    $months[] = date("Y-m%", strtotime( date( 'Y-m-01' )." -$i months"));
}
31.08.2011
  • Я думаю, что вещь «первого месяца» довольно необходима, если не взломать какую-нибудь безумную функцию библиотеки PHP (которую я даже не хочу делать для однострочного цикла) и тот факт, что она использует хорошо известные функции в трех строках очень читабельность — это то, что, по моему мнению, делает это решение блестящим, merci! 28.02.2013

  • 2

    Это потому, что не в каждом месяце есть 31 число. Итак, strtotime() переходит на следующий месяц. то есть 4/31 = 5/1.

    Для этого лучше использовать mktime(), так как он тупее, чем strtotime().

    ОБНОВИТЬ

    Чтобы воспользоваться преимуществами умной функции, такой как strtotime(), и не отслеживать год для mktime(), я предлагаю следующее:

    $month = time();
    for ($i = 1; $i <= 12; $i++) {
      $month = strtotime('last month', $month);
      $months[] = date("r", $month);
    }
    print_r($months);
    

    Настройте логику и оптимизируйте по своему усмотрению.

    31.08.2011
  • Это кажется очевидным. Но почему в первом примере это работает и для февраля (всего 28 дней)? 01.09.2011
  • Сотрите это. Первый пример неверен. Я не понимаю, что для 8/30. Я получаю два марша. 01.09.2011
  • Нет, +1 месяц это не 30 дней. Ваше первое объяснение было правильным, оно просто увеличивает «цифру месяца» и переполняется до первого дня следующего месяца. 01.09.2011
  • Если кто-то хочет сгенерировать будущие месяцы, замените последний месяц следующим месяцем. использование этих последних и следующих слов точно даст последний и следующий месяцы соответственно. использование знаков + или - усложнено, поскольку оно добавляет или уменьшает 30 дней, в то время как все месяцы не имеют 30 дней одинаково. То есть в феврале это оказывается неверным вариантом. 07.04.2016

  • 3

    Я думаю, это сработает:

    $this_month = date("n", time());
    $this_year = date("Y", time());
    $months_array = array();
    for ($i = $this_month - 1; $i > ($this_month - 13); $i--) {
        echo "$i<br>";
        if ($i < 1) {
            $correct_month_number = $i + 12;
            $months_array[] = array($correct_month_number, $this_year - 1);
        }
        else {
            $months_array[] = array($i, $this_year);
        }
    }
    echo "<pre>"; var_dump($months_array); echo "</pre>";
    

    Типы данных немного свободны, но это выполняет свою работу. Хорошая вещь в этом заключается в том, что функция date() вызывается только один раз для текущего месяца и года. Остальная логика — простая математика. Не нужно беспокоиться о продолжительности каждого месяца.

    Затем вы можете использовать массив $months_array для создания всего, что вам нужно.

    27.09.2018

    4

    Я хотел бы предложить альтернативное решение, используя DatePeriod.

    Здесь есть ряд предостережений, на которые следует обратить внимание. Во-первых, вы не хотите, чтобы такие вещи, как информация о часовом поясе или день/время, мешали вам. Вас интересует только месяц. Таким образом, мы можем нормализовать часть этой информации, чтобы предотвратить такие осложнения, как переполнение, проблемы с переходом на летнее время и т. д. Поскольку вы можете легко попасть в эту ловушку только в определенные даты/время, когда происходят эти редкие события.

    $start = new DateTime;
    $start->setDate($start->format('Y'), $start->format('n'), 1); // Normalize the day to 1
    $start->setTime(0, 0, 0); // Normalize time to midnight
    $start->sub(new DateInterval('P12M'));
    $interval = new DateInterval('P1M');
    $recurrences = 12;
    
    foreach (new DatePeriod($start, $interval, $recurrences, true) as $date) {
        echo $date->format('F, Y'), "\n"; // attempting to make it more clear to read here
    }
    

    Выход:

    February, 2019
    March, 2019
    April, 2019
    May, 2019
    June, 2019
    July, 2019
    August, 2019
    September, 2019
    October, 2019
    November, 2019
    December, 2019
    January, 2020
    
    30.01.2020

    5

    Радости разной продолжительности месяца. strtotime задается буквально, берет «31 августа» и пытается сделать «31 сентября», которого не существует. Таким образом, вы в конечном итоге с 1 октября или что-то в этом роде. Более безопасный подход таков:

    for ($i = 1; $i <= 12; $i++) {
        $months[] = date("Y-m%", mktime(0, 0, 0, $i, 1, 2011));
    }
    

    Strtotime иногда волшебен, но он ненадежен и, конечно, не «быстр».

    31.08.2011
  • Что происходит, когда год становится 2012? изменить mktime(.,.,.,.,.,date('Y')) ? 01.09.2011
  • да, если вам это нужно, чтобы всегда приспосабливаться к текущему году. 01.09.2011
  • Все еще не работает, если последние 12 месяцев охватывают более 2 лет, как в примере. (т.е. 2011–2010 годы) 01.09.2011
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..