Replace date with dynamic date format in given string - php

My string is given below.
$str = 'Hi $name. This is a reminder of your appointment at $dateformat("h:i A") on $dateformat("M d,Y").';
Suppose date is (coming from DB),
$appoinmentDate = '2019-02-02'
Now, I want to do following things with string
replace $name with John(name is coming from DB)
replace $dateformat("h:i A") with 08:52 AM (time is coming from DB)
$dateformat("M d,Y") should be replace with date("M d,Y",$appoinmentDate) and its result
should be Feb 02,2019 Like this
Important thing: $dateformat("h:i A") and $dateformat("M d,Y") will be dynamic it can be any possible date format
Can any one please help me to find out the solution?

You could use a regular expression that parses $str looking for any word starting with a $, and possibly followed by a ("...") sequence.
If there is a parentheses sequence, take all between the "" and use this as date format in a DateTime->format() call.
Finally, do 1 sprintf() with all the replacements and date/time insertions done at runtime
EDIT
Try this testscript :
<?php
//creating test string
$teststr='Hi $name. This is a reminder of your appointment at $dateformat("h:i A") on $dateformat("M d,Y").' ;
// parse all date format matches
$regex= "/[\$]dateformat\(?\"?([^\"]*)\"\)/" ;
$DTmatches=Array();
// try to match all $dateformat() occurences
if (preg_match_all($regex, $teststr, $DTmatches) )
{
echo sprintf("Found following matches: %s \r\n", print_r($DTmatches,true));
// replace this with your DB timestamp
$theDT = new DateTime("now", new DateTimeZone("UTC")) ;
// count the occurences
$nofOccurences = count($DTmatches[0]) ;
// run over each occurence
for ($i=0; $i < $nofOccurences; $i++)
$teststr = str_replace( $DTmatches[0][$i], $theDT->format($DTmatches[1][$i]), $teststr ) ;
}
else
echo "no dateformat() found" ;
echo sprintf("Replaced test string is: %s \r\n", $teststr) ;
?>

$copy_date = 'Hi test. This is a reminder of your appointment at $dateformat("h:i A") on $dateformat("M d,Y").';
$str = preg_replace('/\$dateformat\(\"h:i A\"\)/', date("h:i A"), $copy_date);
$str1 = preg_replace('/\$dateformat\(\"...../', "", $str);
$str2 = preg_replace('/\"\)/', "'Your Date'", $str1);
In the above code you can replace first date with date format and in other you can set date or text instead of Your date.
If you want to replace both data then remove date("h:i A").

Related

Explode() String Breaking Array Into Too Many Elements

I am working on scraping and then parsing an HTML string to get the two URL parameters inside the href. After scraping the element I need, $description, the full string ready for parsing is:
<a target="_blank" href="CoverSheet.aspx?ItemID=18833&MeetingID=773">Description</a><br>
Below I use the explode parameter to split the $description variable string based on the = delimiter. I then further explode based on the double quote delimiter.
Problem I need to solve: I want to only print the numbers for MeetingID parameter before the double quote, "773".
<?php
echo "Description is: " . htmlentities($description); // prints the string referenced above
$htarray = explode('=', $description); // explode the $description string which includes the link. ... then, find out where the MeetingID is located
echo $htarray[4] . "<br>"; // this will print the string which includes the meeting ID: "773">Description</a><br>"
$meetingID = $htarray[4];
echo "Meeting ID is " . substr($meetingID,0,3);
?>
The above echo statement using substr works to print the meeting ID, 773.
However, I want to make this bulletproof in the event MeetingID parameter exceeds 999, then we would need 4 characters. So that's why I want to delimit it by the double quotes, so it prints all numbers before the double quotes.
I try below to isolate all of the amount before the double quotes... but it isn't seeming to work correctly yet.
<?php
$htarray = explode('"', $meetingID); // split the $meetingID string based on the " delimiter
echo "Meeting ID0 is " . $meetingID[0] ; // this prints just the first number, 7
echo "Meeting ID1 is " . $meetingID[1] ; // this prints just the second number, 7
echo "Meeting ID2 is " . $meetingID[2] ; // this prints just the third number, 3
?>
Question, why is the array $meetingID[0] not printing the THREE numbers before the delimiter, ", but rather just printing a single number? If the explode function works properly, shouldn't it be splitting the string referenced above based on the double quotes, into just two elements? The string is
"773">Description</a><br>"
So I can't understand why when echoing after the explode with double quote delimiter, it's only printing one number at a time..
The reason you're getting the wrong response is because you're using the wrong variable.
$htarray = explode('"', $meetingID);
echo "Meeting ID0 is " . $meetingID[0] ; // this prints just the first number, 7
echo "Meeting ID1 is " . $meetingID[1] ; // this prints just the second number, 7
echo "Meeting ID2 is " . $meetingID[2] ; // this prints just the third number, 3
echo "Meeting ID is " . $htarray[0] ; // this prints 773
There's an easier way to do this though, using regular expressions:
$description = '<a target="_blank" href="CoverSheet.aspx?ItemID=18833&MeetingID=773">Description</a><br>';
$meetingID = "Not found";
if (preg_match('/MeetingID=([0-9]+)/', $description, $matches)) {
$meetingID = $matches[1];
}
echo "Meeting ID is " . $meetingID;
// this prints 773 or Not found if $description does not contain a (numeric) MeetingID value
There is a very easy way to do it:
Your Str:
$str ='<a target="_blank" href="CoverSheet.aspx?ItemID=18833&MeetingID=773">Description</a><br>';
Make substr:
$params = substr( $str, strpos( $str, 'ItemID'), strpos( $str, '">') - strpos( $str, 'ItemID') );
You will get substr like this :
ItemID=18833&MeetingID=773
Now do whatever you want to do!

Scrape the date from a HTML page

I am writing a PHP HTML page scraper program and I need to find out the date it has been updated.
I did this $html = file_get_html(xyz.com) to get the HTML. One line of the HTML has the date like this 10/24/2016.
I did this:
if (strpos($html, '7nbsp;') !== false) {
if (strpos($html, ' </a>') !== false) {
echo "How to print drawing date--here!";
}
Now here is the dilemma, I cannot search 10/24/2016 because I have no way of knowing when the new date is when the site is updated, it could be 10/30/2016 or 11/12/2016...
Ideally, I would like the date to be in a string, like $date = "11/17/2016".
How do I search the date itself?
This code will work for you:
preg_match('/\ ([0-9]{1,2}\/[0-9]{1,2}\/[0-9]{4})/', $html, $matches);
This is a regex that searches for a date (as long as the date is in correct format). Founded matches will be stored in '$matches' variable.
#krasipenkov was close, but the OP asked for it to be in $date var:
$html = 'lblah
balh asdf asd
<mickey mouse="disney">f3rt6wergsdfg 1/19/2016 <more stuff="here">etc
asdf';
preg_match('/\ ([0-9]{1,2}\/[0-9]{1,2}\/[0-9]{4})/', $html, $matches);
$date = $matches[1];
echo "your date found is $date";
[see it run] http://sandbox.onlinephpfunctions.com/code/27419098cf4bc48a5ca2c683b046679b6c0af85c

PHP Convert Full Date To Short Date

I need a PHP script to loop through all .html files in a directory and in each one find the first instance of a long date (i.e. August 25th, 2014) and then adds a tag with that date in short format (i.e. <p class="date">08/25/14</p>).
Has anyone done something like this before? I'm guessing you'd explode the string and use a complex case statement to convert the month names and days to regular numbers and then implode using /.
But I'm having trouble figuring out the regular expression to use for finding the first long date.
Any help or advice would be greatly appreciated!
Here's how I'd do it in semi-pseudo-code...
Loop through all the files using whatever floats your boat (glob() is an obvious choice)
Load the HTML file into a DOMDocument, eg
$doc = new DOMDocument();
$doc->loadHTMLFile($filePath);
Get the body text as a string
$body = $doc->getElementsByTagName('body');
$bodyText = $body->item(0)->textContent; // assuming there's at least one body tag
Find your date string via this regex
preg_match('/(January|February|March|April|May|June|July|August|September|October|November|December) \d{1,2}(st|nd|rd|th)?, \d{4}/', $bodyText, $matches);
Load this into a DateTime object and produce a short date string
$dt = DateTime::createFromFormat('F jS, Y', $matches[0]);
$shortDate = $dt->format('m/d/y');
Create a <p> DOMElement with the $shortDate text content, insert it into the DOMDocument where you want and write back to the file using $doc->saveHTMLFile($filePath)
I incorporated the helpful response above into what I already had and it seems to work. I'm sure it's far from ideal but it still serves my purpose. Maybe it might be helpful to others:
<?php
$dir = "archive";
$a = scandir($dir);
$a = array_diff($a, array(".", ".."));
foreach ($a as $value) {
echo '</br>File name is: ' . $value . "<br><br>";
$contents = file_get_contents("archive/".$value);
if (preg_match('/(January|February|March|April|May|June|July|August|September|October|November|December) \d{1,2}(st|nd|rd|th)?, \d{4}/', $contents, $matches)) {
echo 'the date found is: ' . $matches[0] . "<br><br>";
$dt = DateTime::createFromFormat('F jS, Y', $matches[0]);
$shortDate = $dt->format('m/d/y');
$dateTag = "\n" . '<p class="date">' . $shortDate . '</p>';
$filename ="archive/".$value;
$file = fopen($filename, "a+");
fwrite($file, $dateTag);
fclose($file);
echo 'Date tag added<br><br>';
} else {
echo "ERROR: No date found<br><br>";
}
}
?>
The code assumes the files to modify are in a directory called "archive" that resides in the same directory as the script.
Needed the two different preg_match lines because I found out some dates are listed with the ordinal suffix (i.e. August 24th, 2005) and some are not (i.e. August 24, 2005). Couldn't quite puzzle out exactly how to get a single preg_match that handles both.
EDIT: replaced double preg_match with single one using \d{1,2}(st|nd|rd|th)? as suggested.

Bug with strtotime()

The Simple HTML DOM library is used to extract the timestamp from a webpage. strtotime is then used to convert the extracted timestamp to a MySQL timestamp.
Problem: When strtotime() is usede on a valid timestamp, NULL is returned (See 2:). However when Simple HTML DOM is not used in the 2nd example, everything works properly.
What is happening, and how can this be fixed??
Output:
1:2013-03-03, 12:06PM
2:
3:1970-01-01 00:00:00
var_dump($time)
string(25) "2013-03-03, 12:06PM"
PHP
include_once(path('app') . 'libraries/simple_html_dom.php');
// Convert to HTML DOM object
$html = new simple_html_dom();
$html_raw = '<p class="postinginfo">Posted: <date>2013-03-03, 12:06PM EST</date></p>';
$html->load($html_raw);
// Extract timestamp
$time = $html->find('.postinginfo', 0);
$pattern = '/Posted: (.*?) (.).T/s';
$matches = '';
preg_match($pattern, $time, $matches);
$time = $matches[1];
echo '1:' . $time . '<br>';
echo '2:' . strtotime($time) . '<br>';
echo '3:' . date("Y-m-d H:i:s", strtotime($time));
2nd Example
PHP (Working, without Simple HTML DOM)
// Extract posting timestamp
$time = 'Posted: 2013-03-03, 12:06PM EST';
$pattern = '/Posted: (.*?) (.).T/s';
$matches = '';
preg_match($pattern, $time, $matches);
$time = $matches[1];
echo '1:' . $time . '<br>';
echo '2:' . strtotime($time) . '<br>';
echo '3:' . date("Y-m-d H:i:s", strtotime($time));
Output (Correct)
1:2013-03-03, 12:06PM
2:1362312360
3:2013-03-03 12:06:00
var_dump($time)
string(19) "2013-03-03, 12:06PM"
According to your var_dump(), the $time string you extracted from the HTML code is 25 characters long.
The string you see, "2013-03-03, 12:06PM", is only 19 characters long.
So, where are those 6 extra characters? Well, it's pretty obvious, really: the string you're trying to parse is really "<date>2013-03-03, 12:06PM". But when you print it into an HTML document, that <date> is parsed as an HTML tag by the browser.
To see it, use the "View Source" function in your browser. Or, much better yet, use htmlspecialchars() when printing any variables that are not supposed to contain HTML code.

Regex to extract timestamp from a text in PHP

I have the following bit of text (or some similar variation of it):
Recurring Event
First start: 2010-09-16 17:00:00 EDT
Duration: 4800
Event Status: confirmed
I need to select the timestamp of the "First Start" field and the duration.
Normally I would split the string at the colons, but since the timestamp contains them, it sort of becomes problematic. I'm not so good with regular expressions, but does anyone know one that will be able to select the two bits of data I need?
cheers,
Mike
Assuming the format stays this way you can search for ": ", i.e. a colon followed by a space. The string following this would be your data.
For a simple non-regex solution, find the first : with strpos($input, ":"), then the rest of the line will have the value.
$content = '
Recurring Event
First start: 2010-09-16 17:00:00 EDT
Duration: 4800
Event Status: confirmed
';
$contentArray = explode('EDT' , $content);
$head = trim($content[0]);
//$head will contain 'Recurring Event First start:2010-09-16 17:00:00 '
$headArray = explode(' ' , $head);
$timeStamp = trim(end($headArray)); //which will have 17:00:00
You can do:
if(preg_match('/First start: ([-\d :]+)/',$input,$m)) {
$timeStamp = trim($m[1]);
}else{
$timeStamp = '';
}
if(preg_match('/Duration: (\d+)/',$input,$m)) {
$duration = $m[1];
}else{
$duration = '';
}

Categories