Given an arbitrary string, for example ("I'm going to play croquet next Friday" or "Gadzooks, is it 17th June already?"), how would you go about extracting the dates from there?
If this is looking like a good candidate for the too-hard basket, perhaps you could suggest an alternative. I want to be able to parse Twitter messages for dates. The tweets I'd be looking at would be ones which users are directing at this service, so they could be coached into using an easier format, however I'd like it to be as transparent as possible. Is there a good middle ground you could think of?
If you have the horsepower, you could try the following algorithm. I'm showing an example, and leaving the tedious work up to you :)
//Attempt to perform strtotime() on each contiguous subset of words...
//1st iteration
strtotime("Gadzooks, is it 17th June already")
strtotime("is it 17th June already")
strtotime("it 17th June already")
strtotime("17th June already")
strtotime("June already")
strtotime("already")
//2nd iteration
strtotime("Gadzooks, is it 17th June")
strtotime("is it 17th June")
strtotime("17th June") //date!
strtotime("June") //date!
//3rd iteration
strtotime("Gadzooks, is it 17th")
strtotime("is it 17th")
strtotime("it 17th")
strtotime("17th") //date!
//4th iteration
strtotime("Gadzooks, is it")
//etc
And we can assume that strtotime("17th June") is more accurate than strtotime("17th") simply because it contains more words... i.e. "next Friday" will always be more accurate than "Friday".
I would do it this way:
First check if the entire string is a valid date with strtotime(). If so, you're done.
If not, determine how many words are in your string (split on whitespace for example). Let this number be n.
Loop over every n-1 word combination and use strtotime() to see if the phrase is a valid date. If so you've found the longest valid date string within your original string.
If not, loop over every n-2 word combination and use strtotime() to see if the phrase is a valid date. If so you've found the longest valid date string within your original string.
...and so on until you've found a valid date string or searched every single/individual word. By finding the longest matches, you'll get the most informed dates (if that makes sense). Since you're dealing with tweets, your strings will never be huge.
Inspired by Juan Cortes's broken link based off Dolph's algorithm, I went ahead and wrote it up myself. Note that I decided to just return on first successful match.
<?php
function extractDatetime($string) {
if(strtotime($string)) return $string;
$string = str_replace(array(" at ", " on ", " the "), " ", $string);
if(strtotime($string)) return $string;
$list = explode(" ", $string);
$first_length = count($list);
for($j=0; $j < $first_length; $j++) {
$original_length = count($list);
for($i=0; $i < $original_length; $i++) {
$temp_list = $list;
for($k = 0; $k < $i; $k++) unset($temp_list[$k]);
//echo "<code>".implode(" ", $temp_list)."</code><br/>"; // for visualizing the tests, if you want to see it
if(strtotime(implode(" ", $temp_list))) return implode(" ", $temp_list);
}
array_pop($list);
}
return false;
}
Inputs
$array = array(
"Gadzooks, is it 17th June already",
"I’m going to play croquet next Friday",
"Where was the dog yesterday at 6 PM?",
"Where was Steve on Monday at 7am?"
);
foreach($array as $a) echo "$a => ".extractDatetime(str_replace("?", "", $a))."<hr/>";
Outputs
Gadzooks, is it 17th June already
is it 17th June already
it 17th June already
17th June already
June already
already
Gadzooks, is it 17th June
is it 17th June
it 17th June
17th June
Gadzooks, is it 17th June already => 17th June
-----
I’m going to play croquet next Friday
going to play croquet next Friday
to play croquet next Friday
play croquet next Friday
croquet next Friday
next Friday
I’m going to play croquet next Friday => next Friday
-----
Where was Rav Four yesterday 6 PM
was Rav Four yesterday 6 PM
Rav Four yesterday 6 PM
Four yesterday 6 PM
yesterday 6 PM
Where was the Rav Four yesterday at 6 PM? => yesterday 6 PM
-----
Where was Steve Monday 7am
was Steve Monday 7am
Steve Monday 7am
Monday 7am
Where was Steve on Monday at 7am? => Monday 7am
-----
Something like the following might do it:
$months = array(
"01" => "January",
"02" => "Feberuary",
"03" => "March",
"04" => "April",
"05" => "May",
"06" => "June",
"07" => "July",
"08" => "August",
"09" => "September",
"10" => "October",
"11" => "November",
"12" => "December"
);
$weekDays = array(
"01" => "Monday",
"02" => "Tuesday",
"03" => "Wednesday",
"04" => "Thursday",
"05" => "Friday",
"06" => "Saturday",
"07" => "Sunday"
);
foreach($months as $value){
if(strpos(strtolower($string),strtolower($value))){
\\ extract and assign as you like...
}
}
Probably do a nother loop to check for other weekDays or other formats, or just nest.
Use the strtotime php function.
Of course you would need to set up some rules to parse them since you need to get rid of all the extra content on the string, but aside from that, it's a very flexible function that will more than likely help you out here.
For example, it can take strings like "next Friday" and "June 15th" and return the appropriate UNIX timestamp for the date in the string. I guess that if you consider some basic rules like looking for "next X" and week and month names you would be able to do this.
If you could locate the "next Friday" from the "I'm going to play croquet next Friday" you could extract the date. Looks like a fun project to do! But keep in mind that strtotime only takes english phrases and will not work with any other language.
For example, a rule that will locate all the "Next weekday" cases would be as simple as:
$datestring = "I'm going to play croquet next Friday";
$weekdays = array('monday','tuesday','wednesday',
'thursday','friday','saturday','sunday');
foreach($weekdays as $weekday){
if(strpos(strtolower($datestring),"next ".$weekday) !== false){
echo date("F j, Y, g:i a",strtotime("next ".$weekday));
}
}
This will return the date of the next weekday mentioned on the string as long as it follows the rule! In this particular case, the output was June 18, 2010, 12:00 am.
With a few (maybe more than a few!) of those rules you will more than likely extract the correct date in a high percentage of the cases, considering that the users use correct spelling though.
Like it's been pointed out, with regular expressions and a little patience you can do this. The hardest part of coding is deciding what way you are going to approach your problem, not coding it once you know what!
Following Dolph Mathews idea and basically ignoring my previous answer, I built a pretty nice function that does exactly that. It returns the string it thinks is the one that matches a date, the unix datestamp of it, and the date itself either with the user specified format or the predefined one (F j, Y).I wrote a small post about it on Extracting a date from a string with PHP. As a teaser, here's the output of the two example strings:
Input: “I’m going to play croquet next Friday”
Output: Array (
[string] => "next friday",
[unix] => 1276844400,
[date] => "June 18, 2010"
)
Input: “Gadzooks, is it 17th June already?”
Output: Array (
[string] => "17th june",
[unix] => 1276758000,
[date] => "June 17, 2010"
)
I hope it helps someone.
Based on Dolph's suggestion, I wrote out a function that I think serves the purpose.
public function parse_date($text, $offset, $length){
$parseArray = preg_split( "/[\s,.]/", $text);
$dateTest = implode(" ", array_slice($parseArray, $offset, $length == 0 ? null : $length));
$date = strtotime($dateTest);
if ($date){
return $date;
}
//make the string one word shorter in the front
$offset++;
//have we reached the end of the array?
if($offset > count($parseArray)){
//reset the start of the string
$offset = 0;
//trim the end by one
$length--;
//reached the very bottom with no date found
if(abs($length) >= count($parseArray)){
return false;
}
}
//try to find the date with the new substring
return $this->parse_date($text, $offset, $length);
}
You would call it like this:
parse_date('Setting the due date january 5th 2017 now', 0 , 0)
What you're looking for a is a temporal expression parser. You might look at the Wikipedia article to get started. Keep in mind that the parsers can get pretty complicated, because this really a language recognition problem. That is commonly a problem tackled by the artificial intelligence/computational linguistics field.
Majority of suggested algorithms are in fact pretty lame. I suggest using some nice regex for dates and testing the sentence with it. Use this as an example:
(\d{1,2})?
((mon|tue|wed|thu|fri|sat|sun)|(monday|tuesday|wednesday|thursday|friday|saturday|sunday))?
(\d{1,2})? (\d{2,4})?
I skipped months, since I'm not sure I remember them in the right order.
This is the easiest solution, yet I will do the job better than other compute-power based solutions. (And yeah, it's hardly a fail-proof regex, but you get the point). Then apply the strtotime function on the matched string. This is the simplest and the fastest solution.
Related
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 wan't to get a PHP date() from specified weekday in a given week.
For example:
Weekday: Thursday - in week:8 - year:13 (means 2013).
I would like to return a date from these specified values. The phpdate will in this case return: "21 Feb 2013", which is a Thursday in week 8 of 2013.
Please fill in this php-method:
function getDateWithSpecifiedValues($weekDayStr,$week,$year) {
//return date();
}
Where the example:
getDateWithSpecifiedValues("Tuesday",8,13);
will return a phpdate of "19 Feb 2013"
First, you have to define what you mean by "week of the year". There are several different definitions. Does the first week start on Jan 1? On the first Sunday or Monday? Is it number 1 or 0?
There is a standard definition, codified in ISO 8601, which says that weeks run from Monday through Sunday, the first one of the year is the one with at least 4 days of the new year in it, and that week is number 1. Your example expected output is consistent with that definition.
So you can convert the values by putting them into a string and passing that string to strptime, along with a custom format string telling it what the fields in the string are. For example, the the week number itself should be indicated in the format string by %V.
For the weekday, the format depends on how you want to provide it as input to your function. If you have the full name (e.g. "Thursday"), that's %A. If you have the abbreviated name (e.g. "Thu"), that's %a. If you have a number (e.g. 4), that's either %w (if Sundays are 0) or %u (if Sundays are 7). (If you're not sure, you can always just use %w and pass the number % 7.)
Now, the year should be %G (full year) or %g (just the last two digits). It's different from the normal calendar year fields (%Y for 2014 and %y for 13) because, for example, week 1 of 2014 actually started on December 30, 2013, which obviously has a '%Y' of 2013 where we want 2014. However, the G fields don't work properly with strptime, so you'll have to use the Y's.
For example:
$date_array = strptime("$weekDayStr $week $year", '%A %V %y');
That's a good start, but the return value of strptime is an array:
array('tm_sec' => seconds, 'tm_min' => minutes, tm_hour => hour,
tm_mday => day of month, tm_mon => month number (0..11), tm_year => year - 1900)
And that array is not the input expected by any of the other common date or time functions, as far as I can tell. You have to pull the values out yourself and modify them in some cases and pass the result to something to get what you want. For instance:
$time_t = mktime($date_array['tm_hour'], $date_array['tm_min'],
$date_array['tm_sec'], $date_array['tm_mon']+1,
$date_array['tm_mday'], $date_array['tm_year']+1900);
And then you can return that in whatever form you need. Here I'm returning it as a string:
function getDateWithSpecifiedValues($weekDayStr,$week,$year) {
$date_array = strptime("$weekDayStr $week $year", '%A %V %y');
$time_t = mktime($date_array['tm_hour'], $date_array['tm_min'],
$date_array['tm_sec'], $date_array['tm_mon']+1,
$date_array['tm_mday'], $date_array['tm_year']+1900);
return strftime('%d %b %Y', $time_t);
}
For example,
php > print(getDateWithSpecifiedValues('Thursday',8,13)."\n");
21 Feb 2013
Try this function:
function getDateWithSpecifiedValues($weekDayStr, $week, $year) {
$dt = DateTime::createFromFormat('y, l', "$year, $weekDayStr");
return $dt->setISODate($dt->format('o'), $week, $dt->format('N'))->format('j M Y');
}
demo
I'm fairly certain neither 21st of January or the 19th of January is in week 8.
You can however use strptime to parse custom formats:
var_dump(strptime("Thursday 8 13", "%A %V %y"));
array(9) {
["tm_sec"]=>
int(0)
["tm_min"]=>
int(0)
["tm_hour"]=>
int(0)
["tm_mday"]=>
int(21)
["tm_mon"]=>
int(1)
["tm_year"]=>
int(113)
["tm_wday"]=>
int(4)
["tm_yday"]=>
int(58)
["unparsed"]=>
string(0) ""
}
See the documentation for strptime for the meaning of each value in the returned array.
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.
The DateTime class in PHP (5.3+) works just great as long as the first day of the week in your country is Sunday. In the Netherlands the first day of the week is Monday and that just makes the class useless for building a calendar with week view and calculations.
I can't seem to find an answer on Stackoverflow or the rest of the Internet on how to have DateTime act as if the first day of the week is Monday.
I found this piece on Stackoverflow, but it doesn't fix all the ways you can get into trouble and it's not an elegant solution.
$dateTime = new DateTime('2012-05-14');
$monday = clone $dateTime->modify(('Sunday' == $dateTime->format('l')) ? 'Monday last week' : 'Monday this week');
Is there a way to change this or extent DateTime? Can't imagine it's not a setting as most of Europe starts their weeks on monday.
Added:
Posting the full calendar and functions code will not make things clearer. But here is one one line for example.
I often have to check what the first day of the week is or calculate from the first day of the week to a different date and time in that week. My code is getting full of these:
$startOfWeek = $date->modify(('Sunday' == $date->format('l')) ? 'Monday last week' : 'Monday this week')->modify('+3 hours')->format(DATETIME);
I also get an unwanted result trying to get the first full week of the month or year. As my $date object doesn't always contain the same date I have to keep checking it this way, making the code difficult to read. Having a lot more programming to do on this calendar I can't forsee where it's going to bug again.
EDIT There are some inconsistencies though. For some strange reason DateTime does get this next one right:
$test = new DateTime('2012-10-29'); // Monday
echo $test->modify('Sunday this week')->format('Y-m-d'); // 2012-11-04
// But...
$test = new DateTime('2012-11-04'); // Sunday
echo $test->modify('Monday this week')->format('Y-m-d'); // 2012-11-05 instead of 2012-10-29
But I think I can make the question clearer:
Can the DateTime() class be used with monday as the first day of the week. If not, can the class be extended to use monday as the first day of the week.
UPDATE:
Ok, I think I'm getting somewhere... I'm not a pro at coding classes..but this seems to work for the weeks. But it still needs rules for first day, second day... and also for the day name Sunday itself. I don't think this is foolproof. I would appreciate any help to fix it.
class EuroDateTime extends DateTime {
// Fields
private $weekModifiers = array (
'this week',
'next week',
'previous week',
'last week'
);
// Override "modify()"
public function modify($string) {
// Search pattern
$pattern = '/'.implode('|', $this->weekModifiers).'/';
// Change the modifier string if needed
if ( $this->format('N') == 7 ) { // It's Sunday
$matches = array();
if ( preg_match( $pattern, $string, $matches )) {
$string = str_replace($matches[0], '-7 days '.$matches[0], $string);
}
}
return parent::modify($string);
}
}
// This works
$test = new EuroDateTime('2012-11-04');
echo $test->modify('Monday this week')->format('Y-m-d');
// And I can still concatenate calls like the DateTime class was intended
echo $test->modify('Monday this week')->modify('+3 days')->format('Y-m-d');
I found this to work, yet there are some inconsistencies in PHP's DateTime class.
If the departing date is a sunday the previous monday is not considered the same week (fixed by this class). But departing from a monday, the next sunday is considered as the same week. If they fix that in the future this class will need some additions.
class EuroDateTime extends DateTime {
// Override "modify()"
public function modify($string) {
// Change the modifier string if needed
if ( $this->format('N') == 7 ) { // It's Sunday and we're calculating a day using relative weeks
$matches = array();
$pattern = '/this week|next week|previous week|last week/i';
if ( preg_match( $pattern, $string, $matches )) {
$string = str_replace($matches[0], '-7 days '.$matches[0], $string);
}
}
return parent::modify($string);
}
}
There's nothing to stop you manually modifying a date to get the "first" day of the week, depending on your definition of "first". For instance:
$firstDayOfWeek = 1; // Monday
$dateTime = new DateTime('2012-05-16'); // Wednesday
// calculate how many days to remove to get back to the "first" day
$difference = ($firstDayOfWeek - $dateTime->format('N'));
if ($difference > 0) { $difference -= 7; }
$dateTime->modify("$difference days");
var_dump($dateTime->format('r')); // "Mon, 14 May 2012 00:00:00 +0000"
Notice how the output changes as you vary $firstDayOfWeek; if it was changed to 4 above (Thursday), it would then consider Thu, 10 May 2012 as the "first" day.
Edit: this is a rather basic example. The correct way to do this is by using the user/system's locale to give you the "first" day, and compute from there. See this question for more information.
You can also get the start and the end of the week with setISODate, the last parameter is the ISO-daynumber in the week, monday is 1 and sunday 7
$firstday = new \DateTime();
$lastday = clone($firstday);
$firstday->setISODate($firstday->format("Y"),$firstday->format("W"),1);
$lastday->setISODate($firstday->format("Y"),$firstday->format("W"),7);
I too am confused about what the problem is, because DateTime does have a notion of the week starting from Monday: The N format gives you the days of the week counting from Monday to Sunday, with Monday being 1 and Sunday being 7. Moreover, the W format, the only way to get a week number, also starts the week on Monday. (I seem to remember that Dutch week numbers aren't exactly like ISO week numbers, but that's a different story). So what feature are you missing exactly?
Edit So the problem is (only?) that the relative datetime formats, such as "Monday this week" give the wrong result when the reference date is a Sunday. From the docs it sounds like DateTime just defers to strtotime, which is supposed to be locale-dependent. So if you have your locale set properly and this is not working, it sounds like a bug (for what that's worth).
The proper answer:
$week_start_day; // 0 - Sunday, 1 - Monday
$date_time_from = new DateTime('now');
$date_time_to = clone $date_time_from;
$this_week_first_day = $date_time_from->setISODate($date_time_from->format("Y"), $date_time_from->format("W"), $week_start_day);
$this_week_last_day = $date_time_to->setISODate($date_time_to->format("Y"), $date_time_to->format("W"), (6 + $week_start_day));
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