无法弄清楚为什么结果与使用 DateTime() 指定的日期范围不匹配


Can not figure out why results do not match the date range that was specified with DateTime()

我已经尝试在相关帖子的帮助下自己找到答案,例如:

  • php 中当前月份的第一天使用 date_modify 作为 DateTime 对象

  • PHP strtotime +1 个月行为

  • PHP 日期时间::修改加减月

但不幸的是我找不到我的错误:-/所以我请求你的支持。

我目前正在尝试为活动网站自定义 wordpress 主题,我想通过按月过滤来增强现有的搜索选项。

我有一个选择框,其中包含 1 月至 12 月的所有月份:

<select id="listingFormTime" name="listingFormTime">                            
  <option value=""<?php selected( $time, "" ); ?>><?php _e( "Any Time", "themesdojo" ); ?></option>
  <option value="1"<?php selected( $time, 1 ); ?>><?php _e( "January", "themesdojo" ); ?></option>
  <option value="2"<?php selected( $time, 2 ); ?>><?php _e( "February", "themesdojo" ); ?></option>
  <option value="3"<?php selected( $time, 3 ); ?>><?php _e( "March", "themesdojo" ); ?></option>
 ...
  <option value="12"<?php selected( $time, 12 ); ?>><?php _e( "December", "themesdojo" ); ?></option>
</select>

选择月份时,应从数据库中选取相应的记录并显示。选择"三月"时,应列出所有开始日期在三月的事件,等等。

必要的事件日期作为"meta_key"和"meta_value"存储在附加表中

  • event_start_date --> 例如: 02/20/2016
  • event_start_time --> 例如:下午 3:00
  • event_start_date_number -->例如:1455980400
  • event_end_date -->例如: 02/20/2016
  • event_end_time --> 例如:晚上 7:00
  • event_end_date_number -->例如:1455994800

发现我可以使用DateTime((;并且可以选择修改和使用相对格式。因此,首先我为每个月添加了以下 12 个查询:

if($time == 1) { 
$dt_min = new DateTime('2015-12-31'); // January
$dt_max = clone($dt_min);
$dt_max->modify('+1 month'); 
$end_date = $dt_max->format('m/d/Y'); 
$date = $end_date." 23:59:59"; 
$event_start_date_number = strtotime($date); erzeugen
$time_args = array(
    'key'     => 'event_start_date_number',  
    'value'   => $event_start_date_number, 
    'compare' => '<=',
    'orderby' => 'value',
    'order'   => 'ASC',
);

} elseif($time == 2) {
$dt_min = new DateTime('2016-01-31');  // February
$dt_max = clone($dt_min);
$dt_max->modify('+1 month');
$end_date = $dt_max->format('m/d/Y');
$date = $end_date." 23:59:59";
$event_start_date_number = strtotime($date);
$time_args = array(
    'key'     => 'event_start_date_number', 
    'value'   => $event_start_date_number, 
    'compare' => '<=',
    'orderby' => 'value',
    'order'   => 'ASC',
);
...
} elseif($time == 12) { ...

然后我读到"modify('+1 month'(;"可能会导致问题,并发现我的结果在二月份完美运行,但从三月份开始,结果不再正确。

所以我试图找到另一种解决方案,并尝试使用另一种相对格式:$dt_max->modify('2016 年 1 月的最后一天'(; 而不是 $dt_max->modify('+1 个月'(;

    if($time == 1) {
$dt_min = new DateTime('2016-01-01'); 
$dt_max = clone($dt_min);
$dt_max->modify('last day of January 2016'); 
$end_date = $dt_max->format('m/d/Y'); 
$date = $end_date." 23:59:59"; 
$event_start_date_number = strtotime($date);
$time_args = array(
    'key'     => 'event_start_date_number',
    'value'   => $event_start_date_number, 
    'compare' => '<=',
    'orderby' => 'value',
    'order'   => 'ASC',
);

} elseif($time == 2) {
$dt_min = new DateTime('2016-02-01');
$dt_max = clone($dt_min);
$dt_max->modify('last day of February 2016');
$end_date = $dt_max->format('m/d/Y');
$date = $end_date." 23:59:59";
$event_start_date_number = strtotime($date);
$time_args = array(
    'key'     => 'event_start_date_number', 
    'value'   => $event_start_date_number, 
    'compare' => '<=',
    'orderby' => 'value',
    'order'   => 'ASC',
);

不幸的是,这里的结果相同 - 二月很好,但在三月也显示了二月的事件。在四月,显示了二月和三月的事件。似乎下个月的事件只是简单地添加的,我不知道为什么;-(

我以为每次将新的日期时间((设置为月初时,持续时间是有限的?!

如果这是一个愚蠢的问题,我非常抱歉 - 我不是开发人员,编程技能很差,但愿意学习。非常感谢您的帮助和经验。


使用后:

var_dump($dt_min );
var_dump($dt_max );
var_dump($date );
var_dump($end_date );
var_dump($event_start_date_number );

我首先按预期得到结果,所以我可以确定变量充满了信息并且日期时间正常工作:

$dt_min --> object(DateTime)#5820 (3) { ["date"]=> string(26) "2016-01-01 00:00:00.000000" ["timezone_type"]=> int(3) ["timezone"]=> string(3) "UTC" } 
$dt_max --> object(DateTime)#5819 (3) { ["date"]=> string(26) "2016-01-31 00:00:00.000000" ["timezone_type"]=> int(3) ["timezone"]=> string(3) "UTC" } 
$date --> string(19) "01/31/2016 23:59:59" 
$end_date --> string(10) "01/31/2016" 
$event_start_date_number  = int(1454284799) // 01. Februar 2016, 00:59:59 UTC+1

但有两个问题令人困惑:

$event_开始日期_数字 = int(1454284799(//01.二月 2016, 00:59:59 UTC+1

在我的理解中,UNIX 时间中生成的 $event_start_date_number 应该是 01/31/2016 23:59:59。但是在解码它时,1 月份我的时区(GMT +1 柏林(似乎有 +1 小时,从 3 月开始,我的时区(GMT +2 柏林(的时区为 +2 小时 - 我想这是由于夏令时,但我必须考虑这一点才能显示正确的事件。

有没有办法影响时区,或者我可以从 Unix 时间戳中减去 -1 或 -2 小时吗?

我想出的第二个问题是:

(...)
$time_args = array(
    'key'     => 'event_start_date_number', 
    'value'   => $event_start_date_number, 
    'compare' => '<=',
    'orderby' => 'value',
    'order'   => 'ASC',
);

可能是我只选择开始日期小于我定义的结束日期的事件吗?这可以解释为什么上个月的所有事件总是列-,-

我以为我会限制事件选择的持续时间

$dt_min = new DateTime('2016-02-01');
$dt_max = clone($dt_min);
$dt_max->modify('last day of February 2016');

但是在数组中,似乎没有限制应从哪个起点列出事件。

有没有办法增强数组,只列出event_start_date_number在 $dt_min 和 dt_max 之间的事件?

好吧,

我自己想通了

有没有办法影响时区,或者我可以从 Unix 时间戳中减去 -1 或 -2 小时吗?

我通过编辑冬季和夏季的开始日期和时间来解决此问题和快速而肮脏的修复来修复此 +1/+2 小时问题 - 即使我知道会有几天问题仍然会发生:

//WINTER (January, February, March, November, December)
$dt_min = new DateTime('2015-12-31'); // --> 01.01.2016
(...) 
$start = $start_date." 23:00:01"; // --> 00:00:01 (+1 hour)
(...)
$end = $end_date." 22:59:59"; // --> 23:59:59 (+1 hour)
//SUMMER (April - October)
$dt_min = new DateTime('2015-03-31'); // --> 01.04.2016
(...) 
$start = $start_date." 22:00:01"; // --> 00:00:01 (+2 hours)
(...)
$end = $end_date." 21:59:59"; // --> 23:59:59 (+2 hours)

对于第二个问题,我找到了更好的解决方案,没有解决方法

有没有办法增强数组,只列出event_start_date_number在 $dt_min 和 dt_max 之间的事件?

} elseif($time == 4) {
$dt_min = new DateTime('2016-03-31');
$dt_max = clone($dt_min);
$dt_max->modify('last day of April 2016');
// additionally defined a start date for the range based on $dt_min
$start_date = $dt_min->format('m/d/Y');
$start = $start_date." 22:00:01";  
$start_date_number = strtotime($start);
$end_date = $dt_max->format('m/d/Y');
$end = $end_date." 21:59:59"; 
$event_start_date_number = strtotime($end);
// found out that I can have an array in an array ^^ to define the date range
$time_args = array(
'key'     => 'event_start_date_number', 
'value'   => array ($start_date_number, $event_start_date_number),  
'compare' => 'BETWEEN',
'orderby' => 'value',
'order'   => 'ASC',
);  

现在我的问题已经"解决",因为在选择月份时会列出正确的事件。