Solved

PHP Convert Date to String

Posted on 2013-10-30
22
12,451 Views
Last Modified: 2013-10-30
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
Comment
Question by:JEaston
  • 8
  • 8
  • 6
22 Comments
 
LVL 42

Expert Comment

by:Chris Stanyon
ID: 39611272
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
 
LVL 10

Author Comment

by:JEaston
ID: 39611482
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
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 39611505
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
 
LVL 42

Expert Comment

by:Chris Stanyon
ID: 39611521
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
 
LVL 10

Author Comment

by:JEaston
ID: 39611525
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
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 39611532
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
 
LVL 42

Expert Comment

by:Chris Stanyon
ID: 39611537
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
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 39611541
Hmm... I'm picking up a code smell.  Where did you find the function that contains these things?
0
 
LVL 10

Author Comment

by:JEaston
ID: 39611543
@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
 
LVL 10

Author Comment

by:JEaston
ID: 39611555
@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
 
LVL 10

Author Comment

by:JEaston
ID: 39611561
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
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 42

Expert Comment

by:Chris Stanyon
ID: 39611564
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
 
LVL 42

Expert Comment

by:Chris Stanyon
ID: 39611575
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
 
LVL 10

Author Comment

by:JEaston
ID: 39611576
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
 
LVL 42

Expert Comment

by:Chris Stanyon
ID: 39611626
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
 
LVL 10

Author Comment

by:JEaston
ID: 39611666
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
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 39611670
You can make var_dump() easier to read with echo '<pre>' just before it ;-)
0
 
LVL 42

Expert Comment

by:Chris Stanyon
ID: 39611685
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
 
LVL 108

Assisted Solution

by:Ray Paseur
Ray Paseur earned 150 total points
ID: 39611694
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
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 39611699
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
 
LVL 42

Accepted Solution

by:
Chris Stanyon earned 350 total points
ID: 39611799
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
 
LVL 10

Author Closing Comment

by:JEaston
ID: 39611836
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

Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

Suggested Solutions

Author Note: Since this E-E article was originally written, years ago, formal testing has come into common use in the world of PHP.  PHPUnit (http://en.wikipedia.org/wiki/PHPUnit) and similar technologies have enjoyed wide adoption, making it possib…
Nothing in an HTTP request can be trusted, including HTTP headers and form data.  A form token is a tool that can be used to guard against request forgeries (CSRF).  This article shows an improved approach to form tokens, making it more difficult to…
Learn how to match and substitute tagged data using PHP regular expressions. Demonstrated on Windows 7, but also applies to other operating systems. Demonstrated technique applies to PHP (all versions) and Firefox, but very similar techniques will w…
In this fifth video of the Xpdf series, we discuss and demonstrate the PDFdetach utility, which is able to list and, more importantly, extract attachments that are embedded in PDF files. It does this via a command line interface, making it suitable …

708 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now