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

x
?
SolvedPrivate

List of Fridays

Posted on 2013-07-12
6
Medium Priority
?
257 Views
Last Modified: 2013-08-11
Hi there,

I hack and slashed this code together a long time ago - I didn't understand it 100% then, and I still don't understand it 100% now.  All I know is that it will make a list of all the current Fridays in a year.  Can you help me understand & comment (so I will remember) whats going on in these loops to grab all the Friday dates?  How do I grab all the Sundays instead?  What is the "list($n,$d)..." line all about?  

Thank you!

function fridays($month, $year, $newsletter_list)
{ 
  // $newsletter_list is an array of exsisting newsletter dates from the database.  IE. 2012-11-04, 2012-11-25..
  $days = array();
  
  for ($month = 1; $month <= 12; $month++) {
	  list($n,$d) = explode('-', date('t-d', strtotime("Friday, $year-$month")));
	  while ($d <= $n)
	  {
		$selectedDay = sprintf("%04d-%02d-%02d", $year, $month, $d);
		$ontheList = false;
		
		for ($q = 0; $q < count($newsletter_list); $q++) {
			if ($selectedDay == $newsletter_list[$q]) {
				$ontheList = true;
			}																		
		}
		
		if ($ontheList == false) {
			$days[] = $selectedDay;
		}
		
		$d += 7;
	  }
  }
  return $days;
}

Open in new window

0
Comment
Question by:maeve100
  • 4
  • 2
6 Comments
 
LVL 111

Expert Comment

by:Ray Paseur
ID: 39322418
0
 
LVL 111

Expert Comment

by:Ray Paseur
ID: 39322419
Also, please see this article.  It has useful learning resources for those who are new to PHP and want to learn more.
http://www.experts-exchange.com/Web_Development/Web_Languages-Standards/PHP/A_11769-And-by-the-way-I-am-new-to-PHP.html
0
 
LVL 111

Assisted Solution

by:Ray Paseur
Ray Paseur earned 1000 total points
ID: 39322457
I have not tested this exhaustively, but it seems correct.

<?php // RAY_temp_maeve100.php
error_reporting(E_ALL);
echo '<pre>';

// ESTABLISH A FUNCTION DEFINITION FOR A GIVEN YEAR AND A GIVEN DAY OF THE WEEK
function days($year='Today', $day='Friday')
{
    // NORMALIZE THE YEAR TO 4-DIGIT
    $year = date('Y', strtotime("$year"));

    // FIND THE FIRST DAY
    $first = date('c', strtotime("$year-01 FIRST $day"));

    // THE RETURN VALUES HERE
    $arr = array();

    // COLLECT THE WEEKDAYS IN THIS YEAR
    while ($first < "$year-12-32")
    {
        $arr[] = $first;

        // INCREMENT BY ONE WEEK
        $first = date('c', strtotime($first . ' PLUS 1 WEEK'));
    }

    // RETURN THE VALUES
    return $arr;
}

// TEST THE FUNCTION
$x = days("2002-03-15", 'Monday');
var_dump($x);
$x = days();
var_dump($x);

Open in new window

HTH, ~Ray
0
Independent Software Vendors: 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!

 
LVL 60

Accepted Solution

by:
Julian Hansen earned 1000 total points
ID: 39322969
To answer your question - here is your code commented
function fridays($month, $year, $newsletter_list)
{ 
  // $newsletter_list is an array of exsisting newsletter dates from the database.  IE. 2012-11-04, 2012-11-25..
  $days = array();
  
  // We are going to repeat this for all months from Jan to Dec
  for ($month = 1; $month <= 12; $month++) {
  
  // This is a complex bit of code - lets break it down
  //   1. strtotime("Friday, $year-$month")
  //      This returns the full date of the first friday in the month specified by Year-Month. The value returned is a millisecond value for the date
  //   2.  date('t-d', strtotime("Friday, $year-$month")))
  //      This takes the return value from the strtotime and extracts the Number of days for the month and the day of the month as a hyphen separated pair
  //   3. explode('-', date('t-d', strtotime("Friday, $year-$month")));
  //      This splits the returned string from date() into an array of items broken on the '-' the result will be an array with index[0] being
  //      the number of days in the specified month and index[1] being the day of the first friday in the month.
  //   4. list($n,$d) 
  //      This assigns the values of the array returned by the explode to the the $n and $d variables
    list($n,$d) = explode('-', date('t-d', strtotime("Friday, $year-$month")));
  
  // Ok so now we have the number of days in the month in $n and the day of the first Friday in $d
  // Time to loop around to process all fridays
    while ($d <= $n)
    {
  // Create a full date for the friday we are working on
    $selectedDay = sprintf("%04d-%02d-%02d", $year, $month, $d);
  
  // initialise the flag that tells us if this friday is in the newsletter list - we are assuming it
  // is not - but if we find it in th enext list we will set it to true
    $ontheList = false;

  // Loop through all the dates in the newsletter list (NB: we could have used a foreach for this as well)
    for ($q = 0; $q < count($newsletter_list); $q++) {
    // Check if the current newsletter list item matches our selected friday
      if ($selectedDay == $newsletter_list[$q]) {
      // and if so set the flag to true
    // NB: At this point we would want to exit the list because we have found the selected date
    // no use spinning the CPU's wheels checking the rest of the values in the list
    // we could either put a break statment here or modify the for loop to put a condition in the condition expression to 
    // check of $onthelist is still false
        $ontheList = true;
      }                                    
    }
    // If we get here and the flag is still false then the selected day is not on the list - so we add the selected day to our days array
    if ($ontheList == false) {
      $days[] = $selectedDay;
    }
    
  // Jump to the next Friday
    $d += 7;
    }
  }
  // And finally return the array containing all the fridays that don't appear on the newsletter list
  return $days;
}

Open in new window

0
 
LVL 60

Expert Comment

by:Julian Hansen
ID: 39322970
Some other anomolies I noticed

You are passing $month to the function - but you never use this value because you immediately overwrite it in the for loop.
0
 
LVL 111

Expert Comment

by:Ray Paseur
ID: 39323382
list($n,$d) = explode('-', date('t-d', strtotime("Friday, $year-$month")));

Open in new window

Any time you have code that looks like this, you have something that can lead to confusion.  The accumulation of closing parentheses is indicative of multiple function calls in a single line of code.  And in beginner programming that is almost always indicative of code that was copied from an external reference, usually without a good understanding of what the code was intended to do.

To deconstruct that line, first go to the innermost function call, which is strtotime(), and work your way out from there.  Its output is expected to be a unix timestamp (but could also be FALSE, which PHP will evaluate as if it were zero).  This value will be part of the arguments passed to date().  

The output of date() will be determined by the pattern 't-d' which will give you the number of days in the given month, followed by a dash, followed by the day of the month with a leading zero, if needed, to pad the day to 2 digits.  This will be returned in the form of a string, either 4 or 5 characters.  

This string will be passed to explode(), which will use the literal string dash '-' as a delimiter to create an array.  The zero position of the array will be the output from date('t') and the one position of the array will be the output from date('d').  

This array will be assigned to the PHP variables $n and $d by the list() statement.

That's a lot of moving parts for a single line of code.  For some reason, inexperienced programmers look at stuff like this and think, "cool."  More experienced programmers tend to avoid that kind of "cool" choosing instead to write programming that easy to read and debug, well-documented with comments, nicely formatted control structures, etc.  The computer doesn't care what you write as long as it functions properly.  But the people who read the code care, and they need to be able to understand your intent at a glance.  Those people include you, if you put the programming aside and come back to it a day, or even a few hours, later.

I have had enough bad experiences looking at incomprehensible code that I have come to believe that my own code should be easy to read and understand.  So while I tolerate a few compound statements like stacking date() and strtotime(), I generally require my code to do only one thing per line.  It's easier to test and it's easier to keep my thought processes in order when the code is laid out that way.
0

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Since pre-biblical times, humans have sought ways to keep secrets, and share the secrets selectively.  This article explores the ways PHP can be used to hide and encrypt information.
Many old projects have bad code, but the budget doesn't exist to rewrite the codebase. You can update this code to be safer by introducing contemporary input validation, sanitation, and safer database queries.
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…
The viewer will learn how to dynamically set the form action using jQuery.
Suggested Courses

876 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