Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 20800
  • Last Modified:

PHP Convert Date to String

Firstly I should say I am relatively new to PHP programming, to date most of my work has been using classic ASP.  However, since I wanted to use FPDF, a free PDF engine, I have started to use PHP.

So far I have been able to add to and adapt the relevant code without problem, until yesterday.

Our report gets data from a MS SQL database and passes this to various functions to generate a PDF containing a table.  This was working perfectly until I included a date field.

This generates an error on the following line:
$s=str_replace("\r",'',$txt);

Open in new window


I would love to include all the scripts but it would fill a good few pages.  Having said that the error seems self-explanatory - strlen cannot be used with a date field.  Given this variable is then used to set column widths etc. I cannot skip this line (and other string functions are used further down).

Therefore I need to check if $txt is a date, and if so convert to a string, preferably in the format 'd M y' (which I think would give dates like '01 Jan 2013'.  In ASP I could have used

I have tried various suggestions from Google last night, all of which just resulted in the same error on a different line, or a different error.

Any help would be appreciated.
0
John Easton
Asked:
John Easton
  • 8
  • 8
  • 6
2 Solutions
 
Chris StanyonCommented:
Without see some test data (how is your date stored in your DB), it's difficult to be specific. in PHP, you handle dates with the DateTime class.

<?php 
$dateString = "12 January 2013";
$myDate = new DateTime($dateString);
$formattedDate = $myDate->format('d M Y');
echo $formattedDate;
?>

Open in new window

Rather than posting full code, it may help if you could create a small code block with hardcoded database value that illustrates your problem
0
 
John EastonDirectorAuthor Commented:
Sorry for the delay in replying.  I have created a vastly reduced script which will in no way create a PDF, but does generate the same data error.

<?php

$myServer = "mydbserver";
$myUser = "myuser";
$myPass = "mypass";
$myDB = "myDB"; 

//create an instance of the  ADO connection object
$conn = new COM ("ADODB.Connection")
  or die("Cannot start ADO");

//define connection string, specify database driver
$connStr = "PROVIDER=SQLOLEDB;SERVER=".$myServer.";UID=".$myUser.";PWD=".$myPass.";DATABASE=".$myDB; 
  $conn->open($connStr); //Open the connection to the database

//Connect to database
$dbconn = sqlsrv_connect($myServer,array( "UID" => $myUser, "PWD" => $myPass, "Database" => $myDB ));

$sql="SELECT IndStartDate";
$sql.=" FROM Links";
$sql.=" WHERE IndStartDate = '1 January 2001' AND NINumber = 'AA121212D'";
$res=sqlsrv_query($dbconn, $sql) or die('Error: '.print_r(sqlsrv_errors())."<BR>Query: $query");
while($row=sqlsrv_fetch_array($res))
{
$s=str_replace("\r",'',$row['IndStartDate']);
echo($s);
}
echo('Hi');
?>

Open in new window


The error is generated on line $s=str_replace("\r",'',$row['IndStartDate']);

The sql returned 1 row with only 1 field which contains the following:  2001-01-01 00:00:00.000
0
 
Ray PaseurCommented:
Date processing in PHP and MySQL:
http://www.experts-exchange.com/Web_Development/Web_Languages-Standards/PHP/A_201-Handling-date-and-time-in-PHP-and-MySQL.html

What is the text in the error message?  And why are you using the str_replace() function?
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
Chris StanyonCommented:
Much better :)

In your WHILE loop, try the following:

$myDate = new DateTime($row['IndStartDate']);
$formattedDate = $myDate->format('d M Y');
echo $formattedDate;

Open in new window

One thing I'm a little confused about though - why would your date field contain a carriage return in the first place? If things don't work, it may be the way you're storing your date - add var_dump($row['IndStartDate']) into the loop to check the values and make sure it resembles a date string. You might also want to post the exact error message you're receiving.
0
 
John EastonDirectorAuthor Commented:
This line is taken from a function used with FPDF to create a table inside a PDF document.  Why it is needed I do not fully understand, although the next line I believe is used to calculate how many lines the cell needs to be to fit the text - i.e. it automatically word-wraps.

Even if I comment out the str_replace() line it then fails on the strlen() function which is the next line.  I assume all of these are string functions.

I'll read article now.
0
 
Ray PaseurCommented:
Some good learning resources and guidance is available here.  With a background in ASP you will have no trouble learning PHP very quickly!
http://www.experts-exchange.com/Web_Development/Web_Languages-Standards/PHP/A_11769-And-by-the-way-I-am-new-to-PHP.html

Please see http://www.laprbass.com/RAY_temp_jeaston.php

<?php // RAY_temp_jeaston.php
error_reporting(E_ALL);

// strlen cannot be used with a date field
// SEE: http://www.experts-exchange.com/Web_Development/Web_Languages-Standards/PHP/Q_28280868.html

$mydate = date('c', strtotime('1 January 2001'));
$length = strlen($mydate);

echo '<pre>';
echo "<br>1...5...10...15...20...25...";
echo "<br>    |    |    |    |    |   ";
echo "<br>$mydate";
echo "<br>LENGTH = $length";

Open in new window

HTH, ~Ray
0
 
Chris StanyonCommented:
OK. You haven't shown us what your passing to strlen - my guess is an array, which will generate an error - it has to take a string
0
 
Ray PaseurCommented:
Hmm... I'm picking up a code smell.  Where did you find the function that contains these things?
0
 
John EastonDirectorAuthor Commented:
@ChrisStanyon:  I agree a datetime field shouldn't contain a carriage return, but this section needs to handle multiple data types - I assume including memo fields.

As for trying the code you supplied, I get a new error:

Fatal error: Uncaught exception 'Exception' with message 'DateTime::__construct() expects parameter 1 to be string, object given' in C:\[file_path]\test.php:25 Stack trace: #0 C:\[file_path]\test.php(25): DateTime->__construct(Object(DateTime)) #1 {main} thrown in C:\inetpub\STSDev\Reports\rp_Management\test.php on line 25
0
 
John EastonDirectorAuthor Commented:
@Ray_Raseur: Original functions come from either FPDF or one of the additional scripts on their website.  Then modified to work with MS SQL rather than mySQL.  Then modified again to change bits of layout.  All worked well until I tried to use a datetime field.

To be fair, my modifications are only a couple of lines of code so far, and not around this section!
0
 
John EastonDirectorAuthor Commented:
Also, I should note PHP (and the site I am writing) is running on Windows under IIS7.5.  It shouldn't make a difference, but I've known stranger things.
0
 
Chris StanyonCommented:
Right - that tells me that the data coming from your database needs closer examination. Create your while() loop like this and report back:

while($row=sqlsrv_fetch_array($res)) {
    var_dump($row);
}

Open in new window

It will give you detailed information about what is being returned from your DB and then we can figure out ho to create a date from it. I don't ever use MS SQL, so it may be something simple in the format or type of the returned data that we need to address.
0
 
Chris StanyonCommented:
One thing of note for you to get your head around. PHP is loosely typed, so when you pull a Date from a database, it doesn't come into PHP as a Date type - normally it just comes in as a string. You then create a PHP DateTime object from that string, so you can use the date based function on it. The var_dump($row) should clarify that.
0
 
John EastonDirectorAuthor Commented:
Not very easy to read, but the output is:

array(2) { [0]=> object(DateTime)#2 (3) { ["date"]=> string(19) "2001-01-01 00:00:00" ["timezone_type"]=> int(3) ["timezone"]=> string(13) "Europe/London" } ["IndStartDate"]=> object(DateTime)#2 (3) { ["date"]=> string(19) "2001-01-01 00:00:00" ["timezone_type"]=> int(3) ["timezone"]=> string(13) "Europe/London" } }
0
 
Chris StanyonCommented:
Right. That makes more sense. Your data is being returned as an array of DateTime Objects, so we need to grab the 'date' property.

Try this:

while($row=sqlsrv_fetch_array($res)) {
   $myDate = new DateTime($row['IndStartDate']->date);
   $formattedDate = $myDate->format('d M Y');
   echo $formattedDate;
}

Open in new window

0
 
John EastonDirectorAuthor Commented:
This seems to be making some progress.  I now get a notice...
   Notice: Undefined property: DateTime::$date in C:\[path]\test.php on line 25

But, I guess a notice is ok to ignore?

I now need to put this back in the main function, but obviously this will only work if it is a date.  Therefore how do I wrap this in something like:

if(IS_DATE(...) {
  do code...
}
0
 
Ray PaseurCommented:
You can make var_dump() easier to read with echo '<pre>' just before it ;-)
0
 
Chris StanyonCommented:
A notice is not OK to ignore. You're much better off dealing with it rather than leaving it. You should check whether the property is defined before using it. If it is, is there any reason why it wouldn't be a date - that doesn't really make sense:

while($row=sqlsrv_fetch_array($res)) {
   if (property_exists($row['IndStartDate'], 'date')):
      $myDate = new DateTime($row['IndStartDate']->date);
      $formattedDate = $myDate->format('d M Y');
      echo $formattedDate;
   endif;
}

Open in new window

0
 
Ray PaseurCommented:
Please see: http://php.net/manual/en/function.sqlsrv-fetch-array.php

This function returns twice as much information as you need (making it the least efficient way to access the query results set), and makes for unnecessary fiddly punctuation in the PHP programming.  You might find you like the data retrieved by this, instead.  Var_dump() will lead you to the right choice.

http://www.php.net/manual/en/function.sqlsrv-fetch-object.php

You can use either the DateTime object or the date() function to format timestamps into dates.
0
 
Ray PaseurCommented:
And +1 for ChrisStanyon's comment on the Notice.  By default PHP suppresses Notice messages and some novice programmers think that it's OK to leave things that way.  Unfortunately an undefined variable is a Notice-level condition and a simple typo can cause a script to fail but with the Notice suppressed, PHP won't tell you what is wrong.  So always display Notices and fix the underlying cause.
0
 
Chris StanyonCommented:
Further to Ray's note about using sqlsrv_fetch_object instead of sqlsrv_fetch_array. If you do that, then your code gets a lot easier:

while($row=sqlsrv_fetch_object($res)) {
   if ($row->IndStartDate instanceof DateTime) {
      echo $row->IndStartDate->format('d M Y');	
   }
}

Open in new window

0
 
John EastonDirectorAuthor Commented:
Thanks to both ChrisStanyon and Ray_Paseur.  The last comment (using fetch_object) worked when updating the function.  At last I now have a PDF with date columns.

Thanks for all you help.
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 8
  • 8
  • 6
Tackle projects and never again get stuck behind a technical roadblock.
Join Now