Your skill will accomplishwhat the force of many cannot PerlMonks

### Web month Calander

by Ryszard (Priest)
 on Nov 22, 2001 at 14:26 UTC Need Help??
Ryszard has asked for the wisdom of the Perl Monks concerning the following question:

I'm writing a web based calander, and want to display a month (or more) in a html table, add links and pull out whatever data is associated with the link (ala the yahoo datebook).

Now i've got it printing out a nice little table with all the dates in the correct spots etc, (which is good) but i'm iterating thru' three loops. one to pull out the days, one to build a monthly matrix (much like the `cal` command), and the final loop builds the html.

I'm thinking this is pretty slow and inefficient, and was wondering if there is a better way.

I thought of using a hash for the number of days in a month (and making the appropriate exceptions for a LY, then determining what day is the 1st of the month) however i'm still stuck with two loops.

Naturally any comments on the style of the code appreciated.

```#!/usr/bin/perl -w

use strict;
use Data::Dumper;
use Date::Calc qw( Delta_Days Add_Delta_Days Date_to_Text );
use CGI;

my \$q = new CGI;

sub date_range {
my(@date) = (@_)[0,1,2];
my(@list);
my(\$i);
my \$output = '';

my \$date;
my %pos = (Su=>1,
Mo=>2,
Tu=>3,
We=>4,
Th=>5,
Fr=>6,
Sa=>7
);
my @box;

\$i = Delta_Days(@_);
while (\$i-- >= 0) {
push( @list, [ @date ] );
@date = Add_Delta_Days(@date, 1) if (\$i >= 0);
}

#build the matrix to hold the days.
my @box;              #the arrray to hold the calendar data
my \$row=0;
foreach \$date (@list) {
my \$col = \$pos{substr(Date_to_Text(@{\$date}),0,2)};
\$box[\$row][\$col]= (@{\$date}[2]);
if (\$col eq 7) {\$row++}
}

for (my \$i=0; \$i<5; \$i++){
\$output .= "<tr>";
for (my \$j=0; \$j<8;\$j++){
if (! defined \$box[\$i][\$j]) {
\$output .= \$q->td({align=>"right"},"&nbsp");
} else {
\$output .= \$q->td({align=>"right"},\$box[\$i][\$j]);
}
}
\$output .= "</tr>";

}
return \$output;
}

print \$q->table(&date_range(2001,11,1, 2001,11,30)); # in chronologica
+l order

Replies are listed 'Best First'.
Re: Web month Calander
by growlf (Pilgrim) on Nov 22, 2001 at 15:34 UTC
Hmm, is there a reason not to use HTML::CalendarMonth? Like so:

Updated (removed html-assubs, since CGI does all this anyhow)

```#!/usr/bin/perl -w
use strict;

use HTML::CalendarMonth;
use CGI;

my \$page = new CGI;
my \$calendar = HTML::CalendarMonth->new();

# Lets do some customization here, since today IS thanksgiving after a
+ll
\$calendar->item(\$calendar->year, \$calendar->month)->attr(bgcolor => '#
+FF8000');
\$calendar->item(22)->attr(bgcolor => '#FFD080');
\$calendar->item(22)->wrap_content(
new HTML::Element 'a',
href => 'http://www.openresources.com/cgi-bin/
+dict?Form=dict2&Database=*&Query=Thanksgiving+Day',
target=> '_blank');

print \$calendar->as_HTML;
This results in a nice little calendar with alot of options already built for you like so:
 November 2001 Su M Tu W Th F Sa 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30

Please forgive the blatent and almost unhidden plagerism from PerlDoc.com

*G*

the only reason was ignorance! i had no idea it existed. sometimes i just launch head-long into things, without doing decent research beforehand.

thanks for the tip

In the interest's of efficiency, i'm still interested in how the above code could by modified.
(crazyinsomniac) Re: Web month Calander
by crazyinsomniac (Prior) on Nov 22, 2001 at 19:39 UTC
Well here's one way to modify it (take advantage of CGI.pm's table generating capabilities, and use map -- don't wanna look at Date::Calc at the moment, maybe tomorrow ;D)
```#!/usr/bin/perl -w

use strict;
use Data::Dumper;
use Date::Calc qw( Delta_Days Add_Delta_Days Date_to_Text );
use CGI;

my \$q = new CGI;

sub date_range
{
my(@date) = (@_)[0,1,2];
my(@list);
my(\$i);
my \$output = '';

my \$date;
my %POS = (Su=>1, Mo=>2, Tu=>3, We=>4, Th=>5, Fr=>6, Sa=>7 );

\$i = Delta_Days(@_);
while (\$i-- >= 0)
{
push( @list, [ @date ] );
@date = Add_Delta_Days(@date, 1) if (\$i >= 0);
}

#build the matrix to hold the days.
my @box;              #the arrray to hold the calendar data
my \$row=0;
foreach \$date (@list)
{
my \$col = \$POS{substr(Date_to_Text(@{\$date}),0,2)};
\$box[\$row][\$col]= (@{\$date}[2]);
\$row++ if (\$col == 7);
}

## for the header
## &nbsp; is in here because array indices start at 0, not one
## and I didn't feel like modifying your code above (-1)
\$output.= \$q->Tr( [
\$q->th( [
qw( &nbsp; Su Mo Tu We Th Fr Sa)
]
)
] );

## gets warnings, since you don't init the array
#\$output.= join '', map { \$q->Tr( [  \$q->td( [ @{\$_} ]) ] ) } @box
+;
## no warnings, cause i test for definedness

\$output.= join '',
map
{
\$q->Tr( [ \$q->td( [ map
{
defined \$_ ? \$_ :" "
} @{\$_}
,]
,)
,]
,)
} @box;
}

## since => is just a fancy comma,
print \$q->table( &date_range(2001,11,1  =>  2001,11,30) );

## or for even "better" readability
print \$q->table( &date_range(qw/2001 11 1/  =>  qw/2001 11 30/) );

__END__
Yielding the following:
Content-Type: text/html; charset=ISO-8859-1
Su Mo Tu We Th Fr Sa
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30

___crazyinsomniac_______________________________________
Disclaimer: Don't blame. It came from inside the void

perl -e "\$q=\$_;map({chr unpack qq;H*;,\$_}split(q;;,q*H*));print;\$q/\$q;"

Re: Web month Calender
by jlongino (Parson) on Nov 22, 2001 at 22:38 UTC
Ryszard, it looks to me that you are well on your way. I've modified/written something similar for our University calendar that you might want to look at for some ideas on layout. It provides several different views (6-month calendar, plain-text monthly, weekly and daily views). The link is USA Campus Calendar. I borrowed the core 6-month view code from an Ill. University (Urbana, I think, with their permission of course). It reads directly from the xnix cal command.

I don't really see that the speed to create the calendar table itself will present much of a bottleneck. It is more likely that fetching your data will take much more time (depending on your method), particularly if you have to retrieve data dynamically from Yahoo. You might want to consider a batch process that periodically updates a database or series of files (one file per event). The series of files method is the one I used since our events are generated manually at our site (through a Web interface). Unfortunately, we don't have a hit counter in place, so I can't say exactly how much it is used.

If you are interested in seeing some of my code, I can post it to my scratch pad. Particularly how the 6-month view is generated.

As far as your code goes, the only thing that some people might recommend is changing your  for (;;){} loops to  for (..){} loops. But I don't think in this case that it is objectionable (besides, the code that I modified/wrote uses them and doesn't utilize CGI table building methods as you have, so I'm not worthy to complain).

Good luck finishing your project!

--Jim

hey jlongino thanks for the comments.

You're right. IRT (In Real Time) the routine prolly wouldnt pose much of a performance threat, however it looks messy and i'm sure there are ways to optimise it. The back end is actually a Postgresql database, so that's where i'm thinking there will be some performance hit.

crazyinsomniac posted some cool CGI.pm stuff i really didnt have a good handle on before.

The project is fun, (as well as practical). I'm basically writing a personal web portal, with addrbk, datebk, ToDo, and notes interfacing with my palm pilot.

I'm also thinking of writing a 'file-manager' type interface (using the pilot-xfer tools), as well as some kind of avantgo syncing (with a malsync backend).

I've pretty much done all the session management, and addressbook thus far and am about 20% into the datebk.

As you can see I suffer from feature creep. I should concentrate on the datebk before things get out of hand.. :-)

Create A New User
Node Status?
node history
Node Type: perlquestion [id://126950]
Approved by root
help
Chatterbox?
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others romping around the Monastery: (8)
As of 2017-08-21 18:51 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
Who is your favorite scientist and why?

Results (324 votes). Check out past polls.

Notices?