优化mysql日期生成器?

时间:2012-08-15 09:39:10

标签: php mysql date

我有一个接受($year, $month = null, $day = null)

的功能

基本上一年必须传递,但月和日是可选的 如果它们没有被传入,那么它将范围设置为最大可能。

所以:call | result

(2012, 08, 15) | ['2012-08-15', '2012-08-15']  
(2012, 08)     | ['2012-08-01', '2012-08-31']
(2012, 02)     | ['2012-02-01', '2012-02-29']
(2012)         | ['2012-01-01', '2012-12-31']
()             | false

我有下面的代码,但对我来说似乎不必要复杂,有人能想到更好的版本吗?

if (!is_null($year)) {

  //year
  $from = $year . '-';
  $to   = $year . '-';

  //month
  if (!is_null($month)) {
    $from .= sprintf('%02d', $month) . '-';
    $to   .= sprintf('%02d', $month) . '-';

    //day
    if (!is_null($day)) {
      $from .= sprintf('%02d', $day);
      $to   .= sprintf('%02d', $day);
    } else {
      $from .= '01';
      $to   .= sprintf('%02d', cal_days_in_month(CAL_GREGORIAN, $month, $year));
    }

  } else {
    $from .= '01-31';
    $to   .= '12-31';
  }
  return array($from, $to);
}
return false;

3 个答案:

答案 0 :(得分:2)

首先,我会稍微改变设计,以便更容易使用:

function my_func_your_func_date_func($year, $month = null, $day = null)
{
    if (NULL === $year)
        return false;

    $mask = '%04d-%02d-%02d';
    $from = vsprintf($mask, date_pad_first($year, $month, $day));
    $to   = vsprintf($mask, date_pad_last($year, $month, $day));

    return array($from, $to);
}

然后是这些辅助函数:

function date_pad_first($year, $month = NULL, $day = NULL)
{
    if (NULL === $month)
        $month = 1;

    if (NULL === $day)
        $day = 1;

    return array($year, $month, $day);
}

function date_pad_last($year, $month = NULL, $day = NULL)
{
    if (NULL === $month)
        $month = 12;

    if (NULL === $day)
        $day = cal_days_in_month(CAL_GREGORIAN, $month, $year);

    return array($year, $month, $day);
}

然后我可能想要提取这两个相似的外观函数和参数之间的差异,但我不确定。


如果您希望在一个函数中使用它(如果未设置$day,则使用稍微不同的语义重置$month),这需要使用if进行分支:< / p>

function my_func_your_func_date_func($year, $month = null, $day = null)
{
    if (NULL === $year)
        return false;

    $from[-1] = $year;
    $to = $from;

    if (NULL === $month) {
        $from += [1, 1];
        $to += [12, 31];
    } else {
        $from[2] += [$month, 1];
        $to[2] += [$month, cal_days_in_month(CAL_GREGORIAN, $month, $year)];
    }

    $mask = '%04d-%02d-%02d';
    return array(
        vsprintf($mask, $from),
        vsprintf($mask, $to)
    );
}

如果有一个12月的时间少于或超过31天,此功能也将无效。

答案 1 :(得分:0)

$format = '%d-%02d-%02d';

$to = $from = array ('year' => $year);

if ( ! is_null ($month) )
{
    $to['month'] = $from['month'] = $month;

    if ( ! is_null ($day) )
    {
        $to['day'] = $from['day'] = $day;
    }
    else
    {
        $from['day'] = '01';
        $to['day'] = cal_days_in_month(CAL_GREGORIAN, $month, $year);
    }
}
else
{
    $from += ['month' => '01', 'day' => '01'];
    $to += ['month' => '12', 'day' => '31'];
}

return array (
    vsprintf ($format, $from),
    vsprintf ($format, $to)
);

这样的东西?

答案 2 :(得分:0)

function my_func_your_func_date_func($year, $month = NAN, $day = NAN) 
{
  if (!is_null($year)) {

  $from_month = max(1, $month);
  $to_month = min($month,12);

  $from_day = max(1,$day);
  $to_day = min($day,cal_days_in_month(CAL_GREGORIAN, $max_m, $year));

  $from = sprintf('%s-%02d-%02d',$year,$from_month,$from_day);
  $to = sprintf('%s-%02d-%02d',$year,$to_month,$to_day);

  return array($from,$to);
  }
  return false;
}

了解minmax如何处理NAN - http://www.php.net/manual/en/function.min.php#101058