从 Timestamp php 中减去 6 个月的最简单方法是啥

Posted

技术标签:

【中文标题】从 Timestamp php 中减去 6 个月的最简单方法是啥【英文标题】:What is the easiest way to substract 6 months from Timestamp php从 Timestamp php 中减去 6 个月的最简单方法是什么 【发布时间】:2018-06-11 04:39:40 【问题描述】:

我有一个时间戳格式的日期。我需要从中减去 6 个月。这是我目前的做法

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

但我再次需要时间戳格式,因为我将其保存为整数 (laravel)。有没有更好的方法来做到这一点

【问题讨论】:

为什么是mysql标签??? 添加只是因为日期保存为 int mysql 你不应该设置无用的标签.. 【参考方案1】:

像这样

 $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 的源代码,那么这段代码 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 source code。

为了创建,他们只是用当前日期创建一个 DateTime 对象(子对象),然后在其中设置带有时间戳的日期。

他们所做的只是获取6 你给他们*-1 所以它是-6 然后做$this->modify('-6 months') 扩展DateTime 大致等效。

基本上我上面粘贴的所有代码都可以在 3 行中完成。但是,如果是我,我仍然会使用 Carbon,因为它是这样做的“框架”方式,所以它更合适一点。函数调用也很便宜,而且在性能方面你不会真正注意到几纳秒的差异。因此,与往常一样,我会倾向于可读性(在框架内)而不是性能。

我从来没有使用过Carbon,但它看起来很有趣。我可能应该做的更深入,但我一直在考虑做一些非常相似的东西,所以也许我会在 Carbon 中“作曲”......哈哈......我越老越懒,6 岁以前,我会敲击钥匙告诉我有一些非常相似的东西。但是那时作曲家不在,所以...

【讨论】:

其实我不想转换成日期时间格式。我只想要时间戳格式。我想避免类型转换 您可以轻松地从 Datetime 获取时间戳。把它想象成一个日期转换器。 $Datetime->getTimestamp()【参考方案2】:

你可以使用->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

【讨论】:

以上是关于从 Timestamp php 中减去 6 个月的最简单方法是啥的主要内容,如果未能解决你的问题,请参考以下文章

Hive - 如何从 Hive 获取最近几个月的数据?

如何根据上个月的计算更新每个月的期初余额?

Javascript 从日期开始减去增加1个月 [重复]

从 hive 中的日期字段中减去 n 个月

获取下个月的月份

如何从当前日期 PHP 获取最近 7 周、7 个月的日期范围?