Я хочу сделать массив предыдущего месяца 1-го и последнего дня. Из моего стартового \DateTime $date=2018-04-30. Когда я меняю свой начальный \DateTime на 2018-05-31, и мой ожидаемый результат представляет собой массив, содержащий:
[
['2018-03-01', 2018-03-31],
['2018-02-01', 2018-02-28],
['2018-01-01', 2018-01-31],
['2018-01-01', 2018-03-31],
['2017-03-01', 2018-03-31],
]
На данный момент я сделал:
$monthAgoStart = clone $date;
$monthAgoEnd = clone $date;
$month2agoStart = clone $date;
$month2agoEnd = clone $date;
$month3agoStart = clone $date;
$month3agoEnd = clone $date;
$currentYearStart = clone $date;
$yearAgo = clone $date;
$monthAgoStart->modify('first day of previous month');
$monthAgoEnd->modify('last day of previous month');
$month2agoStart->modify('first day of this month')->modify('-2 months');
$month2agoEnd = new \DateTime($month2agoEnd->modify('-1 months')->format('y-m-0'));
$month3agoStart= new \DateTime($month3agoStart->modify('-3 months')->format('y-m-1'));
$month3agoEnd = new \DateTime($month3agoEnd->modify('-3 months')->format('y-m-0'));
$currentYearStart->modify('first day of January');
$yearAgo->modify('-12 months');
Массив результатов:
$dates = [
'ago1month' => ["start" => $monthAgoStart, "end" => $monthAgoEnd],
'ago2month' => ["start" => $month2agoStart, "end" => $month2agoEnd],
'ago3month' => ["start" => $month3agoStart, "end" => $month3agoEnd],
'yearStart' => ["start" => $currentYearStart, "end" => $monthAgoEnd],
'yearAgo' => ["start" => $yearAgo, "end" => $monthAgoEnd],
];
Мой код генерирует:
{"ago1month":{
"start":{"date":"2018-03-01"},
"end":{"date":"2018-03-31"}
},
"ago2month":{
"start":{"date":"2018-02-01"},
"end":{"date":"2018-02-28 "}
},
"ago3month":{
"start":{"date":"2018-01-01 "},
"end":{"date":"2017-12-31"}
},
"yearStart":{
"start":{"date":"2018-01-01"},
"end":{"date":"2018-03-31"}
},
"yearAgo":{
"start":{"date":"2017-04-30"},
"end":{"date":"2018-03-31 "}
}
}
Как лучше всего решить мою проблему? Я планировал сделать строки и создать new DateTime для каждой записи массива, но хочу убедиться, нет ли другого способа сделать это.
Все еще ошибаюсь:
"yearAgo":{ "start":{"date":"2017-04-30"}}"ago3month":{"end":{"date":"2017-12-31"}}
Почему -12 месяцев с 30 апреля или 31 мая вернет 2017-03-01?
@Xatenev кажется, что только первые 3 строки относятся к предыдущим месяцам, последние две должны быть в последнем квартале и в прошлом году
Я думаю, вам было бы намного легче, если бы вы использовали DateTimeImmutable вместо DateTime. Вам не нужно ничего клонировать, и вы избежите изменения ваших базовых объектов при их изменении.
Такое ощущение, что у вас есть рабочий код. Если вам нужен совет по уточнению, возможно, перейдите на CodeReview. Если у вас есть «проблема», мне это непонятно.
@mickmackusa Мой код работает не так, как ожидалось. Я не хочу, чтобы использовалась какая-либо функция format, и мой код работал. Должен ли я создавать new DateTime (string) для каждого элемента моего массива? Других решений нет?
@mickmackusa Перекрестно размещено и скоро будет закрыто на Code Review. Вопрос должен был быть убран здесь вместо того, чтобы размещать перекрестные сообщения.
@Mast выглядит так, как будто OP вытащил его Я сказал, что вопрос мне непонятен.






При получении последнего дня месяца вы должны использовать t из Формат даты.
Вы также можете упростить свой код и упростить его чтение, клонируя $ date, когда вам это нужно, или используя DateTimeImmutable.
$month3agoEnd = (clone $date)->modify('-3 months')->format('Y-m-t');
Как и ожидалось, это 2018-03-31. Использование Y-m-0 возвращает 2018-03-0, который вы обработали внутри нового объекта \ DateTime, поэтому ваш код фактически записывается как:
$month3agoEnd = new DateTime('2018-03-0');
Это фактически возвращает новый экземпляр DateTime, установленный на 2018-02-28, поэтому я не уверен, как вам удалось получить 2017-12-31.
$month3agoEnd = (clone $date)->modify('-3 months')->format('Y-m-t'); А как насчет решения php 5.6?
@pvaitonis Это не будет работать в версии 5.6, но срок службы версии 5.6 почти подошел к концу, и я не знаю ни одного дистрибутива ОС, поддерживающего версию 5.6 дольше. Поэтому я бы не рекомендовал создавать новые проекты для 5.6. php.net/supported-versions.php. Вы все равно можете использовать DateTimeImmutable или просто использовать clone $ date в отдельной строке.
Я не понимаю ваш ожидаемый массив. Особенно
['2018-01-01', 2018-01-31], ['2018-01-01', 2018-03-31],. Вы имели в виду 2018-01-31 вместо 2018-03-31? Но тогда он будет дублироваться с приведенным выше ..