json与对象、数组之间的转换

$json = '{"name":"json","age":11}';
$array = array('name'=>'array','age'=>22);
$object = new StdClass;
$object->name = 'object';
$object->age = '33';

echo "json转object<br />";
$var1 = json_decode($json);// json转object
var_dump($var1);

echo "<hr />";
echo "json转array<br />";
$var2 = json_decode($json,true);// json转array
var_dump($var2);

echo "<hr />";
echo "array转json<br />";
$var3 = json_encode($array);// array转json
var_dump($var3);

echo "<hr />";
echo "object转json<br />";
$var4 = json_encode($object);// object转json
var_dump($var4);

PHP关于strtotime、mktime函数获取下一个月的日期遇到的大坑

有个需求是获取给定日期的往后N个月的当日日期,如果该月没有该日数,则取往前一天。


如:$date等于2017-01-31,是1月的最后一天,2月没有31日,2月在平年的最后一天是28日,闰年是29日。希望取到$date的往后3个月当日日期,如果该月没有改日期,则取往前一天。


应该得到


2017-02-28

2017-03-31

2017-04-30



但是PHP几个函数得到的结果都是如果该月没有该日数,则往后延迟


导致了2017-01-31希望取到的往后3个月当日得到的是


2017-03-03

2017-03-31

2017-05-01


得到的结果和需求相差甚远。



幸好可以用mysql填这个坑


SELECT DATE_ADD( '2017-01-31', INTERVAL 1 MONTH ),DATE_ADD( '2017-01-31', INTERVAL 2 MONTH ),DATE_ADD( '2017-01-31', INTERVAL 3 MONTH );


就可以得到和预期一样的结果


2017-02-28

2017-03-31

2017-04-30

date_default_timezone_set('PRC');


$servername = 'localhost';
$dbname = 'test';
$username = 'root';
$password = '123456';
 
@$link = new mysqli($servername, $username, $password, $dbname);
if ($link->connect_error) {
    die('Connection failed: ' . $link->connect_error);
}
$link->set_charset('utf8');



$date = '2017-01-29';
echo "date : {$date}<br /><br />\n";
$cdate = new DateTime($date);
$arr = explode('-', $date);
for ($i=1; $i <= 2; $i++) {
    echo "strtotime +{$i} Month : ".date('Y-m-d',strtotime("+{$i} Month",strtotime($date)))."<br />\n";
    echo "mktime +{$i} Month : ".date("Y-m-d",mktime(0,0,0,$arr[1]+$i,$arr[2],$arr[0]))."<br />\n";
    $cdate->add(new DateInterval("P{$i}M")); // <-- plus 1 month
    echo "DateInterval +{$i} Month : ".$cdate->format('Y-m-d') . "<br />\n";

    $sql = "SELECT DATE_ADD( '{$date}', INTERVAL {$i} MONTH ) AS `nextmonth`;";
    $res = $link->query($sql)->fetch_assoc();
    echo "sql +{$i} Month : ".$res['nextmonth'];
    echo "<br /><br />\n";
}
echo "<hr />\n";

/*
date : 2017-01-29

strtotime +1 Month : 2017-03-01
mktime +1 Month : 2017-03-01
DateInterval +1 Month : 2017-03-01
sql +1 Month : 2017-02-28

strtotime +2 Month : 2017-03-29
mktime +2 Month : 2017-03-29
DateInterval +2 Month : 2017-05-01
sql +2 Month : 2017-03-29
*/



$date = '2017-01-30';
echo "date : {$date}<br /><br />\n";
$cdate = new DateTime($date);
$arr = explode('-', $date);
for ($i=1; $i <= 2; $i++) {
    echo "strtotime +{$i} Month : ".date('Y-m-d',strtotime("+{$i} Month",strtotime($date)))."<br />\n";
    echo "mktime +{$i} Month : ".date("Y-m-d",mktime(0,0,0,$arr[1]+$i,$arr[2],$arr[0]))."<br />\n";
    $cdate->add(new DateInterval("P{$i}M")); // <-- plus 1 month
    echo "DateInterval +{$i} Month : ".$cdate->format('Y-m-d') . "<br />\n";

    $sql = "SELECT DATE_ADD( '{$date}', INTERVAL {$i} MONTH ) AS `nextmonth`;";
    $res = $link->query($sql)->fetch_assoc();
    echo "sql +{$i} Month : ".$res['nextmonth'];
    echo "<br /><br />\n";
}
echo "<hr />\n";
/*
date : 2017-01-30

strtotime +1 Month : 2017-03-02
mktime +1 Month : 2017-03-02
DateInterval +1 Month : 2017-03-02
sql +1 Month : 2017-02-28

strtotime +2 Month : 2017-03-30
mktime +2 Month : 2017-03-30
DateInterval +2 Month : 2017-05-02
sql +2 Month : 2017-03-30
*/
$date = '2017-01-31';
echo "date : {$date}<br /><br />\n";
$cdate = new DateTime($date);
$arr = explode('-', $date);
for ($i=1; $i <= 3; $i++) {
    echo "strtotime +{$i} Month : ".date('Y-m-d',strtotime("+{$i} Month",strtotime($date)))."<br />\n";
    echo "mktime +{$i} Month : ".date("Y-m-d",mktime(0,0,0,$arr[1]+$i,$arr[2],$arr[0]))."<br />\n";

    $cdate = new DateTime($date);
    $cdate->add(new DateInterval("P{$i}M")); // <-- plus 1 month
    echo "DateInterval +{$i} Month : ".$cdate->format('Y-m-d') . "<br />\n";

    $sql = "SELECT DATE_ADD( '{$date}', INTERVAL {$i} MONTH ) AS `nextmonth`;";
    $res = $link->query($sql)->fetch_assoc();
    echo "sql +{$i} Month : ".$res['nextmonth'];
    echo "<br /><br />\n";
}
echo "<hr />\n";

/*
date : 2017-01-31

strtotime +1 Month : 2017-03-03
mktime +1 Month : 2017-03-03
DateInterval +1 Month : 2017-03-03
sql +1 Month : 2017-02-28

strtotime +2 Month : 2017-03-31
mktime +2 Month : 2017-03-31
DateInterval +2 Month : 2017-03-31
sql +2 Month : 2017-03-31

strtotime +3 Month : 2017-05-01
mktime +3 Month : 2017-05-01
DateInterval +3 Month : 2017-05-01
sql +3 Month : 2017-04-30
*/