laravel — Какой самый простой способ вычесть 6 месяцев из переполнения стека Timestamp

У меня есть дата в формате отметки времени. Из которого мне нужно вычесть из него 6 месяцев. Это нынешний способ, которым я делаю это

 $begin = Carbon::createFromTimestamp($begin, Timezone::IST)->subMonths(6);

Но мне снова нужен формат отметки времени, так как я сохраняю это как целое число (laravel). Есть ли лучший способ сделать это

0

Решение

Как это

 $Datetime = new DateTime($time);
$Datetime->modify('-6 months');
echo $Datetime->format('Y-m-d');

http://php.net/manual/en/class.datetime.php

ОБНОВИТЬ

Что это?

Но мне снова нужен формат отметки времени, так как я сохраняю это как целое число (laravel). Есть ли лучший способ сделать это

Я имею в виду, как выглядит int. Вы можете использовать что-то вроде этого DateTime::createfromformat( 'Y-m-d', '2018-01-01') А затем вывести его как метку времени с $Datetime->gettimestamp();

Таким образом, полный код будет близок к:

$Datetime- = DateTime::createfromformat( '{your date format}', $datestring);
$Datetime->modify('-6 months');
$timestamp = $Datetime->gettimestamp();

Вы не должны вычитать произвольное количество секунд, потому что это не учитывает високосные годы или месяцы с нечетными днями. Для этого предусмотрены относительные форматы даты и времени, поэтому лучше их использовать.

UPDATE2 (для углерода)

Если вы посмотрите на источник для Carbon это расширение DateTime и, таким образом, вероятно, обеспечивает ту же функциональность и немного больше. Так что даже это может сработать Carbon::createFromTimestamp($begin, Timezone::IST)->subMonths(6)->gettimestamp()

Как показывает этот бит из источника углерода

public function diffInSeconds(Carbon $dt = null, $abs = true)
{
$dt = $dt ?: static::now($this->getTimezone());
$value = $dt->getTimestamp() - $this->getTimestamp();
return $abs ? abs($value) : $value;
}

конкретно $this->getTimestamp(), это не является большим сюрпризом, поскольку расширяет DateTime. Тем не менее, я бы избегал использования публичной собственности timestamp поскольку он нарушает протокол черного ящика (это то, что я называю (BBP)), где класс должен быть черным ящиком для его функциональности. И вы должны получать доступ только к данным из класса, используя его общедоступный интерфейс (интерфейсы которого не содержат свойств). Это только мое мнение.

Теперь, если вы действительно хотите копаться в исходном коде для углерода, то этот код Carbon::createFromTimestamp($begin, Timezone::IST)->subMonths(6) вероятно делает что-то очень похожее на это:

$this->datetime = new Datetime($begin, Timezone::IST);
$this->datetime->modify('-6 months');

конкретно

class Carbon extends DateTime{

//-------- create---------

public static function createFromTimestamp($timestamp, $tz = null)
{
return static::now($tz)->setTimestamp($timestamp);
}

public static function now($tz = null)
{
return new static(null, $tz);
}
/*
the code "new static" can be a bit confusing, but this is just
one of many ways to call "new Carbon()", which in turn is calling
new "DateTime()". They use static so if you extended Carbon it will
work (as opposed to using "new self") a.k.a "new static" uses late
static binding.  And they also use static, because it's cleaner then
doing something like "new __CLASS__", which I believe will not let
you pass in arguments (without assigning the class name to a
variable). Where as new static($arg) works fine.  In any case it's
generally preferred to use something like "new static" then to
reference the class name directly as in "new Carbon".  Obviously
this is so if the class name changes there are no repercussions on
the code, no code to update.
*/

//-------- subMonth ---------
public function subMonth($value = 1)
{
return $this->subMonths($value);
}

public function subMonths($value)
{
return $this->addMonths(-1 * $value);
}

public function addMonths($value)
{
if (static::shouldOverflowMonths()) {
return $this->addMonthsWithOverflow($value);
}
return $this->addMonthsNoOverflow($value);
}

public function addMonthsWithOverflow($value)
{
return $this->modify((int) $value.' month');
}

public function addMonthWithOverflow($value = 1)
{
return $this->addMonthsWithOverflow($value);
}

}

Таким образом, он вызывает 4 или 6 дополнительных вызовов функций, но в конце концов он в основном одинаков. Взяты прямо из исходный код github.

Для создания они просто делают DateTime объект (дочерний) с текущим днем, а затем установить в нем дату с отметкой времени.

Все, что они делают, это принимают 6 вы даете им *-1 так что это -6 затем делать $this->modify('-6 months') который как бы расширяется DateTime примерно эквивалентно.

В основном весь код, который я вставил выше, может быть выполнен в 3 строки. Но если бы это был я, я бы все еще использовал Carbon, так как это «каркасный» способ сделать это, так что это немного более правильно. Кроме того, вызовы функций довольно дешевы, и в плане производительности вы не заметите разницу в несколько наносекунд. Поэтому, как всегда, я бы склонялся к удобочитаемости (в рамках), а не к производительности.

В качестве стороны я никогда не использовал Carbon но выглядит интересно. Я углубился немного глубже, чем, наверное, следовало бы, но я думал сделать что-то очень похожее, так что, возможно, я буду просто «композитором» в Carbon … смеется … Чем старше я становлюсь, тем лениче я, 6 лет назад я бы просто забил ключи, скажи, что у меня есть что-то очень похожее на это. Но композитора тогда не было, так что …

1

Другие решения

Вы можете просто использовать ->timestamp:

$begin = Carbon::createFromTimestamp($begin, Timezone::IST)->subMonths(6)->timestamp;

Но если вы сохраняете эту и все другие даты в БД в качестве отметок времени, вы можете установить $dateFormat собственность на U:

protected $dateFormat = 'U';

Затем, $begin Laravel будет автоматически преобразован в экземпляр Carbon. Итак, вы можете просто сделать это:

$begin->setTimezone(IST')->subMonths(6);

А затем просто сохраните его обратно в БД без ручного преобразования его обратно в метку времени.

https://laravel.com/docs/5.5/eloquent-mutators#date-mutators

0

По вопросам рекламы [email protected]