473,396 Members | 1,758 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

Creating an Archive from Date

Hi

I have a series of news articles that get published by a user into a database, one of the fields is the date (2007/09/20). Is it possible to filter out the results and create links to articles for the months of the current year? and then also have year links to articles in 2007, 2006 etc.

Can anyone point me in the right direction please?

Thank you

Regards

Tom
Sep 20 '07 #1
15 1608
pbmods
5,821 Expert 4TB
Heya, Tom.

Probably the easiest way would be to use strtotime() and date():

Expand|Select|Wrap|Line Numbers
  1. $archives = array();
  2.  
  3. while( $_row = mysql_fetch_assoc($_res) )
  4. {
  5.     $archives[ date( 'Y', strtotime($_row['publish_date']) ) ] = $_row;
  6. }
  7.  
Sep 20 '07 #2
Thank You for your help I was completetly stuck and never knew which way to approach the task, I cannot test the script at the minute but will do ASAP.

An presumingly I can then use this line to obtain the months for the year.

[PHP]

$archives[ date( 'F', strtotime($_row['publish_date']) ) ] = $_row;

[/PHP]

But would this not result in a long list of repeated months and years?

As if I use disctinct in the SQL query it will recieve 2007/09/20 and 2007/09/21 and will turn both into either 2007 or September as they are both distinct?

Kind Regards

Tom
Sep 21 '07 #3
pbmods
5,821 Expert 4TB
Heya, Tom.

You might want to do something like this:
Expand|Select|Wrap|Line Numbers
  1. while( $_row = mysql_fetch_assoc($_res) )
  2. {
  3.     $_year = date( 'Y', strtotime($_row['publish_date']) );
  4.     $_mon = date( 'F', strtotime($_row['publish_date']) );
  5.  
  6.     $archives[$_year][$_mon][] = $_row;
  7. }
  8.  
The [] part will cause PHP to create a new sub-array that stores the new $_row rather than overwriting whatever is already there (oops).
Sep 21 '07 #4
I now have the following code:

[PHP]

$result = mysql_query("SELECT date FROM news")
or die(mysql_error());

$archives = array();

while( $_row = mysql_fetch_assoc($result) )
{
$_year = date( 'Y', strtotime($_row['date']) );
$_mon = date( 'F', strtotime($_row['date']) );

$archives[$_year][$_mon][] = $_row;

}

mysql_close();

[/PHP]

thank you so much for your help, if echo $_year and $_mon then I see what I was expecting too, now how can I go about only displaying unique years & Mon?

Also when filtering the news atricles by the year once I have the links setup and passing a variable through to another page to retrieve the articles for that year say 2005, would it be recommended to do a query along the lines of:

[PHP]

$_targetYear = $_POST['targetYear'}

while($row = mysql_fetch_array( $result ))
{
$_year = date( 'Y', strtotime($_row['date']) );
foreach($row as $_year = $_targetYear)
{
// Print out here what information i need such as title etc.
}
}
[/PHP]

Sorry to keep asking questions, i'm still learning PHP and getting there slowly but surely.

Thank you one again for your help.

Kind Regards

Tom
Sep 21 '07 #5
pbmods
5,821 Expert 4TB
Heya, Tom.

thank you so much for your help, if echo $_year and $_mon then I see what I was expecting too, now how can I go about only displaying unique years & Mon?
Ah. *that's* what you were talking about. Fortunately, it's no too difficult.

I'm going to make one suggestion:
Expand|Select|Wrap|Line Numbers
  1. while( $_row = mysql_fetch_assoc($_res) )
  2. {
  3.         $_year = date( 'Y', strtotime($_row['publish_date']) );
  4. /**/    $_mon = date( 'm', strtotime($_row['publish_date']) );/**/
  5.  
  6.         $archives[$_year][$_mon][] = $_row;
  7. }
  8.  
  9. $months =
  10.     array
  11.     (
  12.         1 => 'January',
  13.         2 => 'February',
  14.         .
  15.         .
  16.         .
  17.         12 => 'December',
  18.         13 => 'Oops'
  19.     );
  20.  
Expand|Select|Wrap|Line Numbers
  1. foreach( $archives as $_year => $_yearData )
  2. {
  3.     echo "
  4.         <a href=\"/path/to/archives.php?year={$_year}\">{$_year}</a>
  5.         <ul>";
  6.  
  7.     foreach( $_yearData as $_month => $_monthData )
  8.     {
  9.         echo "
  10.             <li>
  11.                 <a href=\"/path/to/archives.php?year={$_year}&month={$_month}\">{$months[$_month]}</a>
  12.                 <ul>";
  13.  
  14.             foreach( $_monthData as $_article )
  15.             {
  16.                 echo "
  17.                     <li>
  18.                         <a href=\"/path/to/archives.php?articleid={$_article['articleid']}\">{$_article['title']}</a>
  19.                     </li>";
  20.             }
  21.  
  22.             echo "
  23.                 </ul>
  24.             </li>";
  25.     }
  26.  
  27.     echo "
  28.         </ul>";
  29. }
  30.  
Also when filtering the news atricles by the year once I have the links setup and passing a variable through to another page to retrieve the articles for that year say 2005, would it be recommended to do a query along the lines of:

[PHP]

$_targetYear = $_POST['targetYear'}

while($row = mysql_fetch_array( $result ))
{
$_year = date( 'Y', strtotime($_row['date']) );
foreach($row as $_year = $_targetYear)
{
// Print out here what information i need such as title etc.
}
}
[/PHP]
That won't quite work; aside from the syntax error, it's not really efficient to load your entire table and then process it in PHP, especially when MySQL will do all the hard work for you.

The trick is to use date() and strtotime() to format your query, and then only load articles whose `publish_date` falls within a given range.

For example, if you went to articles.php?year=2000&month=6:
Expand|Select|Wrap|Line Numbers
  1. // Validate $_GET['year'] and $_GET['month'] and create date strings.
  2. // The end result will look something like this:
  3. $_startDate = '2000-06-01 00:00:00';
  4. $_endDate = '2000-06-30 11:59:59';  // Hint:  Use strtotime on 2000-07-01 11:59:59 and then subtract the number of seconds in one day.  Then use date().
  5.  
  6. $_sql = "
  7. SELECT
  8.         *
  9.     FROM
  10.         `articles`
  11.     WHERE
  12.         `publish_date`
  13.             BETWEEN
  14.                     '{$_startDate}'
  15.                 AND
  16.                     '{$_endDate}'
  17.     ORDER BY
  18.         `publish_date` DESC";
  19.  
You'd do something very similar if no month were specified (e.g., fetch all articles between 2000-01-01 00:00:00 and 2000-12-31 11:59:59).

Sorry to keep asking questions, i'm still learning PHP and getting there slowly but surely.
That's OK; I'm supposed to be working right now :P

Keep on it, and post back if you get stuck.
Sep 21 '07 #6
pbmods


Thank you for your help I have created the archive links, I have added a couple of if statements to show only the blog titles for the current month.

But your script has also provided me with a great way of creating a site map for all the archives, which I think will only improve usability and accessibility.

Thank you. I'm in the process of implementing your second suggestion to retrieve the articles from the database.

Thank you for your help.

If you don't mind could I post back if I have any problems? I owe big time thank you.

Tom
Sep 23 '07 #7
pbmods
5,821 Expert 4TB
Heya, Tom.

Go right ahead; that's what we're here for :)

Good luck with your project, and if you ever need anything, post back anytime.
Sep 23 '07 #8
Hey pdmod its me again unfortunatly for you i'm trying to pick your brain :)

I have a problem were I am up to the part of running through the string date and time as you suggested using the strtotime.

I have created an if statement to catch if there is a variable for the month passed through if not then the start month gets set to January and the end month December.

If a month is passed through then I am setting the amounts of days within the month.

at the end of the statements and before the strtotime begins. Everything works fine when I echo $_startDate & $_endDate.

What am I doing wrong with the strtotime? as when I attempt to echo the results nothing is displayed.

Thanks you in advance

Kind Regards

Tom

[PHP]

$year = $_GET['year'];
$mon = $_GET['month'];

if ($mon == 'January' || $mon == 'March' || $mon == 'May' || $mon == 'July' || $mon == 'August' || $mon == 'October' || $mon == 'December')
}
$day = '31';
}
else if ($mon == 'April' || $mon == 'June' || $mon == 'September' || $mon == 'November' )
{
$day = '30';
}
else if ($mon == 'February')
{
$day = '28';
}

if ($mon == '')
{
$_startDate = "".$year."-January-01 00:00:00";
$_endDate = "".$year."-December-31 11:59:59";
}
else
{
$_startDate = "".$year."-".$mon."-".$day." 00:00:00";
$_endDate = "".$year."-".$mon."-".$day." 11:59:59";
}

$_start_period = date('Y-m-d H:i:s', strtotime($_startDate));
$_end_period = date('Y-m-d H:i:s', strtotime($_endDate));

echo $_start_period;
echo $_end_period;
[/PHP]
Sep 23 '07 #9
pbmods
5,821 Expert 4TB
Heya, Tom.

Rather than try to determine what the last day of the month is (don't forget about leap years and February!), let PHP handle that and focus on what you do know:
  • strtotime() returns a value in seconds.
  • The last day of the month plus one day is the first day of the next month.
  • There are 86,400 seconds in a day.

To test the theory, try this:
Expand|Select|Wrap|Line Numbers
  1. echo date( 'F j, Y g:i a', time() - 86400 );
  2.  
The output should be exactly 1 day ago.

What if the current date was, say, July 1?
Expand|Select|Wrap|Line Numbers
  1. echo date( 'F j, Y g:i a', strtotime('2007-07-01 11:59:59') - 86400 );
  2.  
The result is June 30, 2007 11:59 PM. Hm....
Sep 23 '07 #10
pbmod

Thank you i understand how to use strtotime now but i'm completely stuck on how to get the year and month into the equation? How can I get it to go one month ahead to then minus 86400 seconds off?

I have looked around an I saw you can put plus one month but that will only add on 30 days so that no good for this situation.

Thank you so much for your help.

Tom
Sep 23 '07 #11
pbmods
5,821 Expert 4TB
Heya, Tom.

If you [should] calculate the first of the month like this:
Expand|Select|Wrap|Line Numbers
  1. $_startDate = $year."-".$mon."-1 00:00:00";
  2.  
Then you can calculate the last day of the month like this:
Expand|Select|Wrap|Line Numbers
  1. $_nextMonth = $mon + 1;
  2. $_endDate = date( 'Y-m-d H:i:s', strtotime("{$year}-{$_nextMonth}-1 11:59:59") - 86400 );
  3.  
Sep 23 '07 #12
pbmods

Thank you for your help I have it all working correctly thanks to your expertise, one problem I did have is converting the string 'September' or any other month to is numerical value '09' is this somthing which can be done?

I got round the problem with if and else statements but was wondering if strtotime should have worked in this situation.

Kind Regards

Tom
Sep 24 '07 #13
pbmods
5,821 Expert 4TB
Heya, Tom.

You can use an associative array for that:
Expand|Select|Wrap|Line Numbers
  1. $_months =
  2.     array
  3.     (
  4.         'january' => '01',
  5.         .
  6.         .
  7.         .
  8.     );
  9. $_month = $_months[strtolower($mon)];
  10.  
Making everything lowercase is not strictly necessary, but it does make your code a bit more robust.
Sep 24 '07 #14
pbmods

Thank you for all your help i owe you big time.

Tom
Sep 25 '07 #15
pbmods
5,821 Expert 4TB
Heya, Tom.

We aim to please.
Sep 25 '07 #16

Sign in to post your reply or Sign up for a free account.

Similar topics

9
by: Harry | last post by:
I am accumulating over 80 pages per day into an archive that I will need to be able to present sequentially to viewers. Using html to viewing a page, then click on back to return to my archive...
5
by: Comcast Newsgroups | last post by:
I'm trying to put together a macro that queries my cell phone call expense DB the selects records as of a specific Date that are not marked "Archive", prints a report, then marks the records...
3
by: gregory_may | last post by:
Below is a routine I use for creating log files. It works great on most VB Applications. However, for web services, it needs some help. The problem is I cant reflect properly into a web service...
5
by: Sam777 | last post by:
I was under the impression that creating the app_offline.htm file at the root of the webapp would cause all handles to be closed so that the app could be removed. Unfortunately, this isn't the...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.