1
\$\begingroup\$

For example I have 2 dates (year and month) like :

2013-03

2013-01 <-- Jan. current month.

2012-10

So my code is :

// Get current month and year
$m = date('m');
$y = date('Y');

// So I do something to get highest date so result is..
$highest = "2013-03";

// Current month and year
$current = $y."-".$m;


// So I do something to get lowest date so result is..
$lowest = "2012-10";


// My idea is get lower month from variables

function do_lower($date){
    $date = explode("-",$date);
    $y = $date[0];
    $m = $date[1];

    if($m != "01") {
        $m = $m-1;
        $m = sprintf('%02d',$m);
        return $y."-".$m;
    } else {
       return ($y-1)."-12";
    }

}


// This is my simple function to get result between high and low 

function different($h,$l) {
    global $data;
    $h = do_lower($h);
    if($h!=$l){
        $data[] = $h;
        different($h,$l);
    }
}

Then .. to do all functions like.. (JSON)

$data[] = $highest;
different($highest,$current);
$data[] = $current;
different($current,$lowest);
$data[] = $lowest;

So my result is correct

["2013-03","2013-02","2013-01","2012-12","2012-11","2012-10"]

Anyone can review my code ?

Thanks so much

\$\endgroup\$
2
  • \$\begingroup\$ I'm confused. What's your end goal? Are you trying to list, in descending order, all dates between two given dates? \$\endgroup\$
    – Corbin
    Commented Jan 9, 2013 at 9:24
  • \$\begingroup\$ Yes you think right , Edited my code @Corbin \$\endgroup\$
    – l2aelba
    Commented Jan 9, 2013 at 9:27

1 Answer 1

3
\$\begingroup\$

There's not really much to review here since it's such a short snippet, but a few things:


I tend to avoid manipulating dates as strings. With just a year-month format it's actually fine since there's no odd rules. It's generally a lot safer to use DateTime though (or even strtotime/date). The problem with dates and times are that they are not simple units. There are complex, ever-changing 'business rules' (of sorts) that surround dates and times and cause huge headaches.

As said though, you're fine with year-date format since there's no gotcha's.

Just for consistency sake though, I would work with a standardized date format and use a date-time specific API.

For example:

$start = new DateTime(date('Y-m')); //First of this month
$end = new DateTime('2013-03'); //March 1st
$oneDay = new DateInterval('P1D');
$dates = array();
for (; $end >= $start; $end->sub($oneDay)) {
    $dates[] = $end->format('Y-m');
}

$dates is then an array in the format you want. This code is quite ugly, but unfortunately I've never been able to figure out a way to manipulate dates in PHP that isn't ugly.


Here's a strtotime/date based version:

$start = strtotime(date('Y-m'));
$end = strtotime('2013-03');
$dates = array();
while ($end >= $start) {
    $dates[] = date('Y-m', $end);
    $end = strtotime(date('Y-m-d', $end) . ' +1 day');
}

Rather than the strtotime call, you could just use 864000 seconds. I'd have to think for a few minutes to make sure that won't have any DST mistakes though. Once again, a situation where I like to keep date operations as abstracted away as possible. 864000 is a lie since not all days have 24 hours (at least not in places that observe DST).


If I were to go with a string approach, your do_lower function is basically what I'd use. It's named rather poorly though since it has no mention of what it's 'lowering' or what 'lowering' even means. Also, I would probably use a strict comparison against 01.

The problem with a purely string based approach is that it's not very reusable. Your function has a very specific input format and a very specific output format. Anything else and it breaks.

If you pass around DateTime's instead, dates are no longer represented as a string. They're represented as a type that is much more appropriate for such a complicated system. They're represented as a type that is aware that they are a date.

\$\endgroup\$
2
  • \$\begingroup\$ Oh ! Nice answer , I will try your in my code :D thanks so much \$\endgroup\$
    – l2aelba
    Commented Jan 9, 2013 at 10:00
  • 1
    \$\begingroup\$ @l2aelba Glad to help :) \$\endgroup\$
    – Corbin
    Commented Jan 9, 2013 at 10:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.