Skip to content
 

In Response To Comments About A Simple PHP Calendar

In response to my article titled “A Simple Calendar Page To Display Date-Specific Data In PHP,” f1ava_f1av asks a series of questions. Since it would be a bit involved to answer in a follow-up comment, he gets yet another blog entry devoted to his questions.

Greetings-

Neat website you have, i like the functionality of it. I just wanted to ty again for your assistance with this. My txt thing that i had did work just for writing the calendar, but required external outputs., but it was def inefficient and didnt take advantage of all the php tools/sql tools out there.

btw, ive been reading this script your wrote for hours now just trying to hammer in all the points.

Yeah, I kick much geek ass. :-) Thanks for the props; sometimes, in Yahoo! Answers, no good deed goes unpunished, so it’s nice to get positive feedback.

The modulus was a very neat way for inserting the s. I also like how you broke apart the whole tr td a /a /td /tr component.

Since I’m self-taught as a computer programmer, I came to the concept of elegance late and largely by accident, but I am very glad I did.

In the geek sense, elegance doesn’t mean “sophisticated,” which most people take the word to mean. It means “simple and effective.” A key part of the idea behind elegance is restraint; in the scientific / geek sense, restraint means, “keep things as simple as you can, use as little code as possible.” It makes a huge difference, believe me.

It takes a while to develop enough skills to start being elegant, but nearly 10 years in to the game, I can tell you, elegance is what it’s about. It makes things far easier to repair and far easier to improve when you’re not wading through code like cobwebs.

mktime(0, 0, 0, $month, 1, $year, 0); === 1162357200 when you wrote this, is this in epoch format? I take it this is a date in the rawest form. For example, when you type a date in MS Excel, and then click format cells and set it to General, it shows something that doesnt make sense at all. Then when you formate it, or set it to date, it puts it in a format that makes sense.

mktime() returns a timestamp, which isn’t the “rawest” form of time available [there's microtime(), which counts off thousandths of seconds], but for most intents and purposes, yes, it’s “raw time.”

As I’ve noted before, both PHP and Unix timestamps are integers representing the number of seconds that have passed since midnight, January 1, 1970 — the Unix epoch. So in that sense, I suppose it’s “in epoch format.” I’ve never heard it referred to that way before, but I’ll go with it.

In re: how Excel (and, for that matter, most Microsoft data programs, including Access and SQL Server) handles time, people love to give Microsoft crap and more often than not, Microsoft deserves worse than it gets.

But when it comes to developer support, Microsoft can’t be beat, especially if you want to know relatively straightforward things, such as, “What the Hell is this thing Excel calls a date?”

If we check the Microsoft Knowledge Base, we encounter Article 214094, which explains everything:

Excel stores all dates as integers and all times as decimal fractions. With this system, Excel can add, subtract, or compare dates and times just like any other numbers, and all dates are manipulated by using this system.

In this system, the serial number 1 represents 1/1/1900 12:00:00 a.m. Times are stored as decimal numbers between .0 and .99999, where .0 is 00:00:00 and .99999 is 23:59:59. The date integers and time decimal fractions can be combined to create numbers that have a decimal and an integer portion. For example, the number 32331.06 represents the date and time 7/7/1988 1:26:24 a.m.

Well, there you go, then: Time in Excel (and Access, and SQL Server) is a float (most programmers call decimals a “float”, short for “floating-point number,” which means the precision [decimal places] of the number isn’t fixed). The integer portion is the date and the fractional portion, the time.

Back to f1ava_f1av:

I put a question in yahoo question/answers regarding setting the calendar to go to the current month/year when the page loads. Could one just modifty your code to read, if ‘m’ ‘y’ are set, then set the get variables equal to $month & &year assuming they are in proper format } else { $month = date(‘m’) $year = date(‘y’).

I answered that question already, but I’ll re-answer it here.

There are a couple of ways to proceed. The easiest — that which probably means the least re-coding — is to check for the presence of the required $_GET variables in the proper format and range.

If they are present and in range, we’ll proceed with the rest of the page. But if they aren’t present, or aren’t in range, we’ll send the page back to itself — providing default variables.

For example, suppose your page absolutely, positively must have month and year $_GET variables that are in range, meaning both must be integers, the month has to be between 1 and 12 and the year has to be between 2006 and 2007.

We’ll check those variables using ereg(). Although I’ve previously used isset() to check for the presence of $_GET variables, it’s not really needed if we’re going to compare variables against a regular expression; if the variables aren’t set, they won’t validate. (Since I just got done talking about how important it is to keep things simple, I suppose I should practice what I’m preaching.)

The code below will go at the very top of your page, before you send any data out to the Web browser. That’s because we’ll be using header() to redirect the page to itself if we don’t have good $_GET variables, and we can’t call header() if the script has already sent data to the Web browser.

Unfortunately, regular expressions don’t easily allow us to check if a given integer is between, say, 1 and 12 (we could write one that works, but it would be complex, and again, we want to keep it simple). So, we’ll use a good, old-fashioned less-than and greater-than evaluation.

//get the current timestamp, then get individual
//date part values from the current timestamp
$now = time();
$now_vars = getdate($now);
 
//set booleans for good month and year
//always assume things are bad
$goodyear = false;
$goodmonth = false;
 
//do we have properly formatted month?
if(ereg('^[0-9]{1,2}$', $_GET['month']) {
	//is it in range?
	if($_GET['month'] > 0 && $_GET['month'] < 13) {
		$goodmonth = true;
	}
}
 
//do we have a properly formatted year?
if(ereg('^[0-9]{4}$', $_GET['year'])) {
	//do we have a year that is in range?
	if($_GET['year'] > 2005 && $_GET['year'] < 2008) {
		$goodyear = true;
	}
}
 
//if we have a bad month OR a bad year, send the default values
if(!$goodmonth || !$goodyear) {
	$url = "Location: index.php?month=$now_vars[mon]&year=$now_vars[year]";
	eader($url);
}

I noticed on your page, that when the user clicks the > previous or next month button, the folder structure changes to that month. I wrote this code below, works pretty neat.

$pmonth = $month – 1;
$nmonth = $month + 1;
if ($pmonth == 0) {
$pyear = $year – 1;
$pmonth = 12;
} else {
$pyear = $year;
}

if ($nmonth == 13) {
$nyear = $year + 1;
$nmonth = 1;
} else {
$nyear = $year;
}

I actually haven’t written any of the code for this blog. It’s all WordPress, including the theme. I’ve tinkered a very little bit with the layout and the syntax highlighting plug-in, but other than that, it’s as it comes out of the box.

I know that hurts my geek cred — not tinkering with things that work perfectly fine — but I’m not out to reinvent the wheel, I’m out to explain to people who are fascinated by the fact the wheel rolls how, exactly, it manages to roll.

That said, you’ve got a pretty good algorithm for moving between months.

well, im going back to do some more php reading, lol but there is one thing for sure that i agree with you about. I cant stand theisman, the man just doesnt shut up, while he is on the air.

anywho, drop me a line, let me know what your looking for these days, i might have it, or know someone that does.

peace

It does seem a shame to saddle Mike Tirico, who could someday be one of the great play-by-play men, with a buffoon (Tony Kornheiser) and a quack (Joe Theismann).

Anyway, thanks for the offer, I’ll take you up on it at some point, I’m sure. Keep posting the questions; they’re fun to answer.

Leave a Reply

Spam Protection by WP-SpamFree