Im trying to make something which retrieves event data, but when it tries to echo some special tokens I get weird text back.
This is the code:
foreach( $new_html->find( 'div#desc' ) as $desc ) {
echo $desc;
echo "</br>";
}
and this is what it returns:
ClubCuccini Persian Valentines Party
▀▀▀▀ Friday 12th February 2016 ▀▀▀▀
ClubCuccini would like to invite you all to one of the most romantic and exciting events of the year in L8 Club , one of the most exclusive place in London.
but it should be returning:
▀▀▀▀ Friday 12th February 2016 ▀▀▀▀
ClubCuccini would like to invite you all to one of the most romantic and exciting events of the year in L8 Club , one of the most exclusive place in London.
Any ideas how to get the good text form?
Related
To get the second Friday of next year I used second Friday of Januar next year, however, this returns the wrong date. (It's not only the second or Friday, this concerns every date in this fashion)
See following example
$FIRST_FRI_JAN_NEXT_YEAR_TEXT = 'second friday of january next year';
$jan1 = new DateTime($FIRST_FRI_JAN_NEXT_YEAR_TEXT ); // = 22-01-08 // wrong date
$FIRST_FRI_JAN_NEXT_YEAR_NUMBER = 'second friday of 2022-01';
$jan2 = new DateTime($FIRST_FRI_JAN_NEXT_YEAR_NUMBER); // = 22-01-14 // right date
Online Demo
Is there a reason for that or is this a bug?
It is not a bug. “Second Friday in January next year” is interpreted as “second Friday in January” of this year and “next year” as +1 year. With long expressions it is not always clear in which order they are processed. It is usually better to do this in several steps.
$jan2 = date_create('next year')->modify('second friday of january'); //2022-01-14
Set-up
I've decided to try a little bit of PHP myself, I'm a total beginner.
I run a WooCommerce shop and want to dynamically display the expected delivery date range on each product page.
The delivery date range is today's date plus 3 and plus 4 days, e.g. today is the of 10th October so the delivery date range is 13 and 14 October. On each product page it should therefore mention,
Delivery between Oct 13 and Oct 14
I know where to write the code such that it displays where I want it to appear on the product pages.
I also know how to dynamically update the delivery dates.
Problem
Echo mixes the variables, instead of,
Delivery between Oct 13 and Oct 14
it states,
Delivery between and Oct 13Oct 14
My Code
function my_custom_action() {
$plus3 = strtotime("+3 day");
$plus4 = strtotime("+4 day");
$date_low = date('M d', $plus3);
$date_high = date('M d', $plus4);
$start_text = _e('Delivery between ','woodmart');
$end_text = _e(' and ','woodmart');
echo $start_text, $date_low, $end_text, $date_high ;
};
add_action( 'woocommerce_single_product_summary', 'my_custom_action', 15 );
I need $start_text and $end_text in functions so the strings are translatable.
Preferably I also have the months (e.g. Oct) translatable, but for now I'd already be very happy to know how I get all variables echoed in the desired order.
This can be resolved using string interpolation.
for eg.
$name = "PHP";
echo "I am reading {$name}POT";
// output: I am reading PHPPOT
here's the link to a much more detailed reference : variable-interpolation-in-php
I have a simple document that I need to split up into events (by day), unfortunately the document contains other useless info (such as event details) which I'll need to crawl through to retrieve the info. An except of this document looks like this:
10th March 2015
Baseball 10:00 Please remember to bring your bats
Soccer 14:00 over 18s only
11th March 2015
Swimming 10:00 Children only
Soccer 14:00 Over 14s team training
My initial plan was to use preg_spit to try and split the string at the date, then loop over each one, however I need to maintain the structure of the document.
Ideally I'd like to return the data into an array like:
arr[
'days' =>[
'date' => '10th MArch 2015'
'events' => ['Baseball 10:00', 'Soccer 14:00'],
]
]
How would I best go about doing this? Regex isn't my strongest suit, but I know enough to capture the days ([0-9]{1,2}[a-z]{2}/s[a-z]+/s[0-9]{4}) and the events ([a-Z]+/s[0-9]{2}:[0-9]{2}).
You can use this regex:
/(?:\b(\d+th\h+.*?\d{4})\b|\G)\s+(\S+\h+\d{2}:\d{2}\b).*?(?=\s+(?>\S+\h+\d{2}:\d{2}|\d+th\h+|\z))/i
And then a bit of PHP code to loop through the result.
RegEx Demo
This is what I came up with. I used explode() to split out the different sections and then to split up the lines. I didn't use preg_match() until the very end to get the specific sport/time.
<?php
$text = <<<EOD
10th March 2015
Baseball 10:00 Please remember to bring your bats
Soccer 14:00 over 18s only
11th March 2015
Swimming 10:00 Children only
Soccer 14:00 Over 14s team training
EOD;
$days = array();
if( $sections = explode("\n\n",$text) ){
foreach($sections as $k=>$section){
$events = array();
$lines = explode("\n",$section);
$day = $lines[0];
unset($lines[0]);
if($lines){
foreach($lines as $line){
preg_match("/(\w+)\s(\d){2}:(\d){2}/",$line,$matches);
if(isset($matches[0])){
$events[] = $matches[0];
}
}
}
$days[$k] = array(
'day' => $day,
'events' => $events
);
}
}
echo '<pre>',print_r($days),'</pre>';
I'm building a local events calendar which takes RSS feeds and website scrapes and extracts event dates from them.
I've previously asked how to extract dates from text in PHP here, and received a good answer at the time from MarcDefiant:
function parse_date_tokens($tokens) {
# only try to extract a date if we have 2 or more tokens
if(!is_array($tokens) || count($tokens) < 2) return false;
return strtotime(implode(" ", $tokens));
}
function extract_dates($text) {
static $patterns = Array(
'/^[0-9]+(st|nd|rd|th|)?$/i', # day
'/^(Jan(uary)?|Feb(ruary)?|Mar(ch)?|etc)$/i', # month
'/^20[0-9]{2}$/', # year
'/^of$/' #words
);
# defines which of the above patterns aren't actually part of a date
static $drop_patterns = Array(
false,
false,
false,
true
);
$tokens = Array();
$result = Array();
$text = str_word_count($text, 1, '0123456789'); # get all words in text
# iterate words and search for matching patterns
foreach($text as $word) {
$found = false;
foreach($patterns as $key => $pattern) {
if(preg_match($pattern, $word)) {
if(!$drop_patterns[$key]) {
$tokens[] = $word;
}
$found = true;
break;
}
}
if(!$found) {
$result[] = parse_date_tokens($tokens);
$tokens = Array();
}
}
$result[] = parse_date_tokens($tokens);
return array_filter($result);
}
# test
$texts = Array(
"The focus of the seminar, on Saturday 2nd February 2013 will be [...]",
"Valentines Special # The Radisson, Feb 14th",
"On Friday the 15th of February, a special Hollywood themed [...]",
"Symposium on Childhood Play on Friday, February 8th",
"Hosting a craft workshop March 9th - 11th in the old [...]"
);
$dates = extract_dates(implode(" ", $texts));
echo "Dates: \n";
foreach($dates as $date) {
echo " " . date('d.m.Y H:i:s', $date) . "\n";
}
However, the solution has some downsides - for one thing, it can't match date ranges.
I'm now looking for a more complex solution that can extract dates, times and date ranges from sample text.
Whats the best approach for this? It seems like I'm leaning back toward a series of regex statements run one after the other to catch these cases. I can't see a better way of catching date ranges in particular, but I know there must be a better way of doing this. Are there any libraries out there just for date parsing in PHP?
Date / Date Range samples, as requested
$dates = [
" Saturday 28th December",
"2013/2014",
"Friday 10th of January",
"Thursday 19th December",
" on Sunday the 15th December at 1 p.m",
"On Saturday December 14th ",
"On Saturday December 21st at 7.30pm",
"Saturday, March 21st, 9.30 a.m.",
"Jan-April 2014",
"January 21st - Jan 24th 2014",
"Dec 30th - Jan 3rd, 2014",
"February 14th-16th, 2014",
"Mon 14 - Wed 16 April, 12 - 2pm",
"Sun 13 April, 8pm",
"Mon 21 - Wed 23 April",
"Friday 25 April, 10 – 3pm",
"The focus of the seminar, on Saturday 2nd February 2013 will be [...]",
"Valentines Special # The Radisson, Feb 14th",
"On Friday the 15th of February, a special Hollywood themed [...]",
"Symposium on Childhood Play on Friday, February 8th",
"Hosting a craft workshop March 9th - 11th in the old [...]"
];
The function I'm currently using (not the above) is about 90% accurate. It can catch date ranges, but has difficulty if a time is also specified. It uses a list of regex expressions and is very convoluted.
UPDATE: Jan 6th, 2014
I'm working on code that does this, working on my original method of a series of regex statements run one after the other. I think I'm close to a working solution that can pretty much extract almost any date/time range / format from a piece of text. When I'm done I'll post it here as an answer.
I think you can sum up the regex in your question like the one below.
(?<date_format_1>(?<day>(?i)\b\s*[0-9]+(?:st|nd|rd|th|)?)(?<month>(?i)\b\s*(?:Jan(?:uary)?|Feb(?:ruary)?|Mar(?:ch)?|etc))(?<year>\b\s*20[0-9]{2}) ) |
(?<date_format_2>(?&month)(?&day)(?!\s+-)) |
(?<date_format_3>(?&day)\s+of\s+(?&month)) |
(?<range_type_1>(?&month)(?&day)\s+-\s+(?&day))
Flags: x
Description
Demo
http://regex101.com/r/wP5fR4
Discussion
By using recursive subpatterns, you reduce the complexity of the final regex.
I have used a negative lookahead in the date_format_2 because it would match partially range_type_1. You may need to add more range type depending on your data. Don't forget to check other partterns in case of partial match.
Another solution would consist in build small regexes in different string variables and then concatenate them in PHP to build a bigger regex.
I'm using PHP and MySQL. I have a page that displays meetings created by people with a link to view details. Right now I'm using just a simple table to display everything sorted by date. The table in the database is called 'meetings' and there are 3 columns -
'meetingid' (int)
'time' (datetime)
'creator' (text)
My problem is that it looks a little messy and difficult to read when there are quite a few meetings created since they are all in just one big clump. I'd like to split them up by week (starting Monday, ending Sunday - or Sunday-Saturday if that's easier). I've linked to a doc at the bottom showing what I currently have (first page) and something more like what I want (second page). The week labels (ex. September 3rd - September 9th) would need to only go on for as long as there are meetings booked. So, if the latest meeting is October 7th then the last week shown should be 'October 1st - October 7th'. Figuring out how to separate them by month seems easy enough but I can't wrap my head around how to do it by week. I'm assuming that there's some php date function that will help greatly with this but I can't find it. Hoping you all can help.
What is the best way to do this?
I haven't decided yet whether or not I'd want the weeks where there are no meetings to show the week label or not. (Ex. There are no meetings between September 10th - September 16th. - so do or do not show that label.
Link to examples (no need to sign into google)
https://docs.google.com/document/d/16cvRfPmovNBsx9QQ0U5qhVoW8bo0xjEABil3wTtEUrA/edit
Use date("W") to get the week number of the year.Then you can separate your results according to the week number.
Without knowing how your data is structured; you could use the week number returned by the date() function to keep track of which week you are in and break it up that way.
$currentWeekNumber = -1;
$rows = array(
array('id' => 5, 'started_by' => 'Ben', 'when' => '2012-09-06 09:00:00'),
array('id' => 6, 'started_by' => 'Julie', 'when' => '2012-09-07 18:00:00'),
array('id' => 18, 'started_by' => 'Ben', 'when' => '2012-09-18 20:00:00')
);
foreach($rows as $row) {
$eventSeconds = strtotime($row['when']);
$rowWeek = intval(date('W', $eventSeconds));
if( $rowWeek !== $currentWeekNumber && $currentWeekNumber !== -1) {
echo "----- Week Break ------\n";
}
$currentWeekNumber = $rowWeek;
echo "Meeting #{$row['id']}, started by {$row['started_by']}, occurs at ".strftime('%c', $eventSeconds)."\n";
}
Which produces the following output:
Meeting #5, started by Ben, occurs at Thu Sep 6 09:00:00 2012
Meeting #6, started by Julie, occurs at Fri Sep 7 18:00:00 2012
----- Week Break ------
Meeting #18, started by Ben, occurs at Tue Sep 18 20:00:00 2012