首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何从PHP中指定的日期获取当前年度季度开始/结束、最后季度开始/结束的时间戳

问如何从PHP中指定的日期获取当前年度季度开始/结束、最后季度开始/结束的时间戳
EN

Stack Overflow用户
提问于 2021-11-18 22:57:29
回答 2查看 226关注 0票数 0

在PHP中是否有任何库或已准备好使用函数来方便计算时间戳?

我要得到:

  1. unixtimestamp:当前季度的第一秒钟,当前季度的
  2. unixtimestamp:最后一秒钟,前一季度的
  3. unixtimestamp:第一秒钟,前一季度的
  4. unixtimestamp:最后一秒钟,

问题:

  • 时区,
  • 在示例3)和4)

中开始了这一年

你是怎么计算的?我的代码看起来很复杂..。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-11-19 10:31:04

我给你写了一个函数。

代码语言:javascript
复制
function getTimestampFromQuarter(string $quarterName = 'current', string $returnTimestamp = 'start', string $timezone = 'UTC', int $year = null): int {

    $dt = new DateTime();
    $dt->setTimezone(new DateTimeZone($timezone));


    // if year not defined, we use current year
    $year = $year ?? date('Y');

    // current month
    $month = date("n");

    // current quarter number
    $quarter = ceil($month / 3);

    // we are looking for previous quarter
    if (in_array(strtolower($quarterName), ['previous','last'])) {
        $quarter--;
        if (0 == $quarter) {
            $quarter = 4;
            $year--;
        }
    }

    // we are looking for next quarter
    elseif (in_array(strtolower($quarterName), ['next'])) {
        $quarter++;
        if (4 == $quarter) {
            $quarter = 1;
            $year++;
        }
    }

    $quarterFirstMonth = (12 / 4) * ($quarter - 1) + 1; // first month of quarter
    $quarterLastMonth = (12 / 4) * ($quarter - 1) + 3; // last month of quarter


    if ('start'==$returnTimestamp) {
        $dt->setDate($year, $quarterFirstMonth, 1);
        $dt->setTime(0, 0, 0);
    }
    elseif ('end'==$returnTimestamp) {

        // looking for month days count
        $ts = new DateTime();
        $ts->setDate($year, $quarterLastMonth, 1);
        $ts->setTimezone(new DateTimeZone($timezone));
        $day = date('t', $ts->getTimestamp());
        unset($ts);


        $dt->setDate($year, $quarterLastMonth, $day);
        $dt->setTime(23, 59, 59);
    }

    return $dt->getTimestamp();
}

的使用很简单:

1..本季度第一秒钟:

代码语言:javascript
复制
echo getTimestampFromQuarter('current', 'start');
// output: 1633046400 (equals to Friday 1. October 2021 0:00:00)

2..本季度的最后一秒:

代码语言:javascript
复制
echo getTimestampFromQuarter('current', 'end'); 
// output: 1640995199 (equals to Friday 31. December 2021 23:59:59)

3..上一季度的第一秒钟:

代码语言:javascript
复制
echo getTimestampFromQuarter('previous', 'start'); 
// output: 1625097600 (equals to Thursday 1. July 2021 0:00:00)

4..上一季度的最后一秒:

代码语言:javascript
复制
echo getTimestampFromQuarter('previous', 'end'); 
// output: 1633046399 (equals to Thursday 30. September 2021 23:59:59)

5..下一季度的第一秒钟:

代码语言:javascript
复制
echo getTimestampFromQuarter('next', 'start'); 
// output: 1640995200 (equals to Saturday 1. January 2022 0:00:00)

6..下一季度的最后一秒:

代码语言:javascript
复制
echo getTimestampFromQuarter('next', 'end'); 
// output: 1648771199 (equals to Thursday 31. March 2022 23:59:59)
票数 1
EN

Stack Overflow用户

发布于 2021-11-19 12:24:16

编辑:我添加了第三个参数,以便能够从任何地方调用函数--时间戳支持的部分。第一个参数现在应该支持数值(偏移),因此'previous‘和-1应该给出相同的结果。

除此之外..。在我答案的底部检查测试用例块可能是最简单的。

代码语言:javascript
复制
function getQuarterTimestamp(string $quarter, string $timeOfDay, int $timestamp = null) : int {
    $timestamp = $timestamp ?? time();
    if ($timestamp < 0) {
        throw new InvalidArgumentException("Bad timestamp argument");
    }

    // Offset to start of current quarter
    $currentMonthQuarterOffset = - (date('n', $timestamp) + 2) % 3;

    switch($quarter) {
        case 'next':
            $currentMonthQuarterOffset += 3; // Move forward 1 quarter
            break;
        case 'current':
            break;
        case 'previous':
            $currentMonthQuarterOffset -= 3; // Move back 1 quarter
            break;
        case is_numeric($quarter):
            $currentMonthQuarterOffset += 3*$quarter; // Move the number of quarters in $quarters
            break;
        default:
            throw new InvalidArgumentException("Bad quarter argument");
            break;
    }

    switch($timeOfDay) {
        case 'start':
            $dayOffset = 'first';
            $timeOffset = '00:00:00';
            break;
        case 'end':
            $currentMonthQuarterOffset += 2; // Default is start, move to end of quarter
            $dayOffset = 'last';
            $timeOffset = '23:59:59';
            break;
        default:
            throw new InvalidArgumentException("Bad timeOfDay argument");
            break;
    }

    $dateTimeStr = "{$dayOffset} day of {$currentMonthQuarterOffset} month ".date('Y-m-d', $timestamp)." {$timeOffset}";

    return (new DateTime($dateTimeStr))->getTimeStamp();
}

..and这里有一些测试代码(注释是11月28日运行后的输出):

代码语言:javascript
复制
echo date("Y-m-d H:i:s\n", getQuarterTimestamp('previous', 'start')); // 2021-07-01 00:00:00
echo date("Y-m-d H:i:s\n", getQuarterTimestamp('previous', 'end')); // 2021-09-30 23:59:59
echo date("Y-m-d H:i:s\n", getQuarterTimestamp('current', 'start')); // 2021-10-01 00:00:00
echo date("Y-m-d H:i:s\n", getQuarterTimestamp('current', 'end')); // 2021-12-31 23:59:59
echo date("Y-m-d H:i:s\n", getQuarterTimestamp('next', 'start')); // 2022-01-01 00:00:00
echo date("Y-m-d H:i:s\n", getQuarterTimestamp('next', 'end')); // 2022-03-31 23:59:59

echo date("Y-m-d H:i:s\n", getQuarterTimestamp('previous', 'start', strtotime('2021-01-23 01:01:01'))); // 2020-10-01 00:00:00
echo date("Y-m-d H:i:s\n", getQuarterTimestamp('previous', 'end', strtotime('2021-01-23 01:01:01'))); // 2020-12-31 23:59:59

echo date("Y-m-d H:i:s\n", getQuarterTimestamp(-4, 'start', strtotime('2021-01-23 01:01:01'))); // 2020-01-01 00:00:00
echo date("Y-m-d H:i:s\n", getQuarterTimestamp(-4, 'end', strtotime('2021-01-23 01:01:01'))); // 2020-03-31 23:59:59

echo date("Y-m-d H:i:s\n", getQuarterTimestamp('current', 'start', strtotime('2021-01-23 01:01:01'))); // 2021-01-01 00:00:00
echo date("Y-m-d H:i:s\n", getQuarterTimestamp('current', 'end', strtotime('2021-01-23 01:01:01'))); // 2021-03-31 23:59:59

备注: case is_numeric($quarter)部件的工作是因为对case行进行了仔细的排序,而且在技术上是不正确的语法,最好将其移出switch(并删除默认情况下的异常)。如果有人想让我这么做,我可以写一个这样的版本。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70027797

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档