2

I'm a PHP beginner and been struggling unsuccessfully with the php documentation. Seems a lot of ways to do what I want.

Basically I need a php page to check an "ugly" date/time variable appended to a URL - it must convert it into a usable format and subtract it from the current date/time. If the result is less than 48hrs then the page should redirect to "Page A" otherwise it should redirect to "Page B"

This is what the URL and variable looks like.

http://mysite.com/special-offer.php?date=20130527212930

The $date variable is the YEAR,MONTH,DAY,HOUR,MINUTE,SECOND. I can't change the format of this variable.

I'm guessing PHP can't use that string as it is. So I need to split it somehow into a date format PHP can use. Then subtract that from the current server date/time.

Then put the result into an if/else depending on whether the result is more or less than 48hrs.

Am I right in theory? Can anyone help me with the "practise"?

Thanks!

Mike C
  • 21
  • 1
  • 2
    Take a look at [this question](http://stackoverflow.com/questions/3787540/how-to-get-first-5-characters-from-string-using-php). – rath Jun 05 '13 at 02:14
  • Just [use this](http://www.php.net/manual/en/datetime.createfromformat.php), will work perfectly and its OO. –  Jun 05 '13 at 02:19
  • By the way, have you taken timezones into consideration? – ItalyPaleAle Jun 05 '13 at 22:11

5 Answers5

8

Take a look at the DateTime class and specifically the createFromFormat method (php 5.3+):

$date = DateTime::createFromFormat('YmdHis', '20130527212930');
echo $date->format('Y-m-d');

You might need to adjust the format depending on the use of leading zeros.

jeroen
  • 91,079
  • 21
  • 114
  • 132
  • 1
    Most "elegant". +1 for this. It's amazing what you can do with `2 lines of code`. ;-) – Funk Forty Niner Jun 05 '13 at 02:26
  • Doesn't the `$time` parameter of that function require a time already in an appropriate format from http://us3.php.net/manual/en/datetime.formats.php? – BLaZuRE Jun 05 '13 at 02:27
  • @BLaZuRE No, you set the format combining the characters the function recognizes, check the link to the manual. – jeroen Jun 05 '13 at 02:29
  • @jeroen I understand you set the format using the `$format` parameter, but the documentation wasn't clear what kind of `$time`s were allowed, which is why I asked. The examples given in the docs only show accepted formats. – BLaZuRE Jun 05 '13 at 02:36
  • @BLaZuRE There might be some situations where you would have to double-check, but the OP's format is very easy; just numbers. – jeroen Jun 05 '13 at 02:38
  • (+1) Saw this too, but keep in mind most don't have access to every module, nor can they add it. Nice add tho - for those of us who do! – Bill Ortell Jun 05 '13 at 02:43
  • Thanks, I'm getting there! I've got the string split into the right format and can echo the current server date. What is the advised way to calculate the difference? This is my code, but I get an error about a call to a non-object. format('Y-m-d H:i.s') . "

    "; echo 'Current Date is '; print date('Y-m-d H:i.s

    '); $currentDate = date('m/d/Y'); $interval = $currentDate->diff($signupDate); echo $interval->format('%R%a days'); ?>

    – Mike C Jun 05 '13 at 02:51
  • @MikeJefferies You should use the `DateTime` class for all your dates if you want to compare them. Take a look at @furas answer. – jeroen Jun 05 '13 at 13:49
2

PHP 5 >= 5.3.0

$uglydate = '20130527212930';

// change ugly date to date object
$date_object = DateTime::createFromFormat('YmdHis', $uglydate);

// add 48h
$date_object->modify('+48 hours');

// current date
$now = new DateTime();

// compare dates
if( $date_object < $now ) {
    echo "It was more than 48h ago";
}
furas
  • 134,197
  • 12
  • 106
  • 148
1

You can use a regular expression to read your string and construct a meaningful value.

for example

$uglydate = "20130527212930";
preg_match("/([0-9]{4})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})/", $uglydate, $matches);

$datetime = $matches[1] . "-" . $matches[2] . "-" . $matches[3] . " " . $matches[4] . ":" . $matches[5] . ":" . $matches[6];

//then u can use $datetime in functions like strtotime etc
DevZer0
  • 13,433
  • 7
  • 27
  • 51
  • Why would one use a regexp, which uses a lot of CPU cycles, when a simple for() loop would be enough? No doubt your solution works, but it's damn inefficient! – ItalyPaleAle Jun 05 '13 at 22:10
1

Whoa! you all have WAY too much time on your hands... Nice answers... oh well, i'll pop-in a complete solution...

<?php

$golive = true;

if (preg_match('|^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})|', $_GET['date'], $matches)) {

    list($whole, $year, $month, $day, $hour, $minute, $second) = $matches;

    // php: mktime function (using parameters derived
    $timestamp = mktime($hour,$minute,$second,$month,$day,$year);

    $diff = time()-$timestamp;
    $diffInHours = $diff / 3600 ;

    // if less, than 48
    if ( $diffInHours < 48 ) {
        $location = "http://bing.com";
    } else {
        $location = "http://google.com";
    }

    //
    if ( $golive ) {
        header("Location: ".$location);
        exit();
    } else {
        echo "<p>You are would be sending the customer to:<br><strong>$location</strong>";
    }

} else {

    echo "<p>We're not sure how you got here, but... 'Welcome!'???</p>";

}

That oughta do it.

By the way, on another note, I'd heavily suggest you go back to the sending party of that URL and definitely reconsider how this is being done. As this is VERY easily tweakable (URL date= value), thus not really protecting anything, but merely putting the keys on the front porch next to the 'Guardian Alarms Installed at This House' {sign} :).

ItalyPaleAle
  • 7,185
  • 6
  • 42
  • 69
Bill Ortell
  • 837
  • 8
  • 12
  • Thanks so much for this. This is exactly what I'm after. I'll change the variable name I think to something less obvious. I'm a bit stuck though with the insecure method - its just the only way of getting the info from one site to the other with my current skills/resources. Luckily its not too important that its secure! Thanks again for your help and to everyone else here to contributed solutions. Very useful! – Mike C Jun 05 '13 at 03:04
  • Ah, I see. You should be all set then. – Bill Ortell Jun 07 '13 at 12:44
0

Assuming the input is in the correct format (correct number of characters and all of them digits) you'll need 1 substring of length 4 and the rest of lenght 2. For simplicity I'll ignore the first 2 chars (the 20 part from 2013) with substr

$input=substr($input, 2, strlen($input));

Now I can treat all the remaining elements in the string as 2-char pairs:

$mydate=array(); //I'll store everything in here
for($i=0; $i<=strlen($input)-2; $i+=2){
    $mydate[$a]=substr($input, $i, $i+2);
    $a++;
}

Now I have year, month, day etc. in an array indexed from 0 to 5. For the date difference I'll put the array into mktime:

$timestamp = mktime(mydate[3], mydate[4], mydate[5], mydate[1], mydate[2], mydate[0]);

Finally compare the two timestamps:

if($old_ts - $timestamp > (60*60*48)){
//more than 48 hours
}else{ ... }
rath
  • 3,655
  • 1
  • 40
  • 53