In this hour, you will learn How to acquire the current date and time How to get information about a date How to format date information How to test dates for validity How to set dates H
Trang 1When the loop reaches the file named "0", the string returned by readdir() resolves to false,which causes the loop to end The approach in Listing 10.14 uses === to check that the return valuereturned by readdir() is not exactly equivalent to false 0 only resolves to false in the test, so we
circumvent the problem
If you find the ordering of items in a directory listing to be arbitrary,it's because the order is determined by the file system If you wantthe items ordered in a specific fashion, you must read the contentsinto an array, which can then be sorted to your liking and
subsequently displayed
[ Team LiB ]
Trang 2[ Team LiB ]
Summary
In this hour, you learned how to use include() to incorporate files into your documents and toexecute any PHP code contained in include files You learned how to use some of PHP's file testfunctions You explored functions for reading files by the line, by the character, and in arbitrarychunks You learned how to write to files, either replacing or appending to existing content Finally,you learned how to create, remove, and read directories
Now that we can work with files, we can save and access substantial amounts of data If we need tolook up data from large files, however, our scripts begin to slow down quite considerably What weneed is some kind of database
[ Team LiB ]
Trang 3[ Team LiB ]
Q&A
Q1: Does the include() statement slow down my scripts?
A1: Because an included file must be opened and parsed by the engine, it adds some
overhead However, the benefits of reusable code libraries often outweigh the relativelylow performance overhead
Q2: Should I always end script execution if a file cannot be opened for writing or reading?
A2: You should always allow for this possibility If your script absolutely depends on the fileyou want to work with, you might want to use the die() function, writing an informativeerror message to the browser In less critical situations, you still need to allow for thefailure, perhaps by adding it to a log file
[ Team LiB ]
Trang 41: What functions do you use to add library code to the currently running script?
A1: You can use the require() or include() statement to incorporate PHP files into thecurrent document You could also use include_once() or require_once()
2: What function do you use to find out whether a file is present on your file system?
A2: You can test for the existence of a file with the file_exists() function
3: How do you determine the size of a file?
A3: The filesize() function returns a file's size in bytes
4: What function do you use to open a file for reading or writing?
A4: The fopen() function opens a file It accepts the path to a file and a character
representing the mode It returns a file resource
5: What function do you use to read a line of data from a file?
A5: The fgets() function reads data up to the buffer size you pass it, the end of the line, orthe end of the document, whichever comes first
6: How can you tell when you've reached the end of a file?
A6: The feof() function returns true when the file resource it's passed reaches the end ofthe file
7: What function do you use to write a line of data to a file?
A7: You can write data to a file with the fputs() function
8: How do you open a directory for reading?
A8: The opendir() function enables you to open a directory for reading
Trang 59: What function do you use to read the name of a directory item after you've opened adirectory for reading?
A9: The readdir() function returns the name of a directory item from an opened directory
2.
[ Team LiB ]
Trang 6[ Team LiB ]
Hour 11 Working with Dates and Times
Dates are so much a part of everyday life that it becomes easy to work with them without thinking.However, the quirks of the Gregorian calendar can be difficult to work with in programs Fortunately,PHP provides powerful tools for date arithmetic that make date manipulation an easy task Similarly,MySQL comes with its own set of date-related functions You learn about these in this hour as well,and find that MySQL can take a lot of the programming burden off your hands
In this hour, you will learn
How to acquire the current date and time
How to get information about a date
How to format date information
How to test dates for validity
How to set dates
How to use MySQL's date and time-related functions
How to format date and time results in MySQL
How to find and express intervals between dates and times using MySQL
[ Team LiB ]
Trang 7[ Team LiB ]
Using Date and Time Functions in PHP
The several sections that follow introduce you to the date- and time-related functions specifically inPHP You learn about the MySQL functions later in this hour Try each listing yourself, as you marchalong through this hour
Getting the Date with time()
PHP's time() function gives you all the information that you need about the current date and time
It requires no arguments and returns an integer For us humans, the returned number is a little hard
on the eyes, but it's extremely useful nonetheless
print time();
// sample output: 1127732399
The integer returned by time() represents the number of seconds elapsed since midnight GMT on
January 1, 1970 This moment is known as the Unix epoch , and the number of seconds that have elapsed since then is referred to as a timestamp PHP offers excellent tools to convert a timestamp
into a form that humans are comfortable with Even so, isn't a timestamp a needlessly convolutedway of storing a date? In fact, the opposite is true From just one number, you can extract enormousamounts of information Even better, a timestamp can make date arithmetic much easier than youmight imagine
Think of a homegrown date system in which you record days of the month as well as months andyears Now imagine a script that must add one day to a given date If this date happened to be 31December 1999, rather than adding 1 to the date, you'd have to write code to set the day of themonth to 1, the month to January, and the year to 2000 Using a timestamp, you need only add aday's worth of seconds to your current figure and you're done You can convert this new figure intosomething more friendly at your leisure
Converting a Timestamp with getdate()
Now that you have a timestamp to work with, you must convert it before you present it to the user
getdate() optionally accepts a timestamp and returns an associative array containing informationabout the date If you omit the timestamp, getdate() works with the current timestamp as
returned by time() Table 11.1 lists the elements contained in the array returned by getdate()
seconds
Trang 8Seconds past the minute (0–59)
Trang 9Table 11.1 The Associative Array Returned by getdate()
Listing 11.1 uses getdate() (line 7) to extract information from a timestamp, employing a
foreach statement to print each element (line 8) You can see typical output in Figure 11.1
getdate() returns the date according to the local time zone
Figure 11.1 Using getdate()
Listing 11.1 Acquiring Date Information with getdate()
Trang 10Converting a Timestamp with date()
You can use getdate() when you want to work with the elements that it outputs Sometimes,
though, you want to display the date as a string The date() function returns a formatted string
that represents a date You can exercise an enormous amount of control over the format that
date() returns with a string argument that you must pass to it In addition to the format string,
date() optionally accepts a timestamp Table 11.2 lists the codes that a format string can contain
Any other data you include in the format string passed to date() is included in the return value
Trang 13Year (two digits)
Table 11.2 Format Codes for Use with date()
Listing 11.2 puts a few of these format codes to the test
Listing 11.2 Formatting a Date with date()
Trang 14Listing 11.2 calls date() twice: the first time on line 8 to output an abbreviated date format, andthe second time on line 11 for a longer format Save the text of this listing in a file called
listing11.2.php and open it in your Web browser Your date will differ from the following,obviously, but here's some sample output:
09/16/02 8.52:06
Today is 16 of September 2002, at 8.52 am
Although the format string looks arcane, it's easy to build If you want to add a string that containsletters that are also format codes to the format, you can escape them by placing a backslash (\ ) infront of them For characters that become control characters when escaped, you must escape thebackslash that precedes them For example, \t is a format code for a tab, so to ensure that the tabprints, use \\t as in the previous example
Also note that the date() function returns information according to your local time zone If youwant to format a date in GMT, you use the gmdate() function, which works in exactly the sameway
Creating Timestamps with mktime()
You can already get information about the current time, but you cannot yet work with arbitrarydates mktime() returns a timestamp that you can then use with date() or getdate()
mktime() accepts up to six integer arguments in the following order:
Listing 11.3 uses mktime() to get a timestamp that we then use with the date() function
Listing 11.3 Creating a Timestamp with mktime()
1: <html>
2: <head>
3: <title>Listing 11.3 Creating a timestamp with mktime()</title> 4: </head>
Trang 1511: print "The date is ";
12: print date("j of F Y, \a\\t g.i a", $ts);
13: ?>
14: </body>
15: </html>
We call mktime() on line 8 and assign the returned timestamp to the $ts variable We then use
date() on lines 9 and 12 to output formatted versions of the date using $ts You can choose toomit some or all the arguments to mktime() , and the value appropriate to the current time is usedinstead mktime() also adjusts for values that go beyond the relevant range, so an hour argument
of 25 translates to 1:00 a.m on the day after that specified in the month, day, and year arguments.Save the text of this listing in a file called listing11.2.php and open it in your Web browser.You should see:
08/23/02 4.15:00
The date is 23 of August 2002, at 4.15 am
Testing a Date with checkdate()
You might need to accept date information from user input Before you work with a user-entered date
or store it in a database, you should check that the date is valid checkdate() accepts threeintegers: month, day, and year checkdate() returns true if the month is between 1 and 12, theday is acceptable for the given month and year (accounting for leap years), and the year is between
0 and 32767 Be careful, though: A date might be valid but not acceptable to other date functions.For example, the following line returns true:
Trang 17[ Team LiB ]
Using Date and Time Functions in MySQL
MySQL's built-in date-related functions can be used in SELECT statements, with or without
specifying a table, to retrieve a result of the function Or you can use the functions with any type ofdate field: date, datetime, timestamp , and year Depending on the type of field in use,the results of the date-related functions are more or less useful
Working with Days
The DAYOFWEEK() and WEEKDAY() functions do similar things with slightly different results Bothfunctions are used to find the weekday index of a date, but the difference lies in the starting day andposition
If you use DAYOFWEEK() , the first day of the week is Sunday, at position 1, and the last day of theweek is Saturday, at position 7 For example:
mysql> select dayofweek('2001-11-13');
1 row in set (0.00 sec)
The result shows that November 13, 2001 was weekday index 3, or Tuesday Using the same datewith WEEKDAY() gives you a different result with the same meaning:
mysql> select weekday('2001-11-13');
1 row in set (0.00 sec)
The result shows that November 13, 2001 was weekday index 1 Because WEEKDAY() uses Monday
as the first day of the week at position 0 and Sunday as the last day at position 6, 1 is accurate:Tuesday
Trang 18The DAYOFMONTH() and DAYOFYEAR() functions are more straightforward, with only one resultand a range that starts at 1 and ends at 31 for DAYOFMONTH() and 366 for DAYOFYEAR()
Some examples follow:
mysql> select dayofmonth('2001-11-13');
1 row in set (0.00 sec)
mysql> select dayofyear('2001-11-13');
1 row in set (0.00 sec)
It might seem odd to have a function that returns the day of the month on a particular date becausethe day is right there in the string But think about using these types of functions in WHERE clauses
to perform comparisons on records If you have a table that holds online orders with a field
containing the date the order was placed, you can quickly get a count of the orders placed on anygiven day of the week, or see how many orders were placed during the first half of the month versusthe second half
The following two queries show how many orders were placed during the first three days of the week(throughout all months) and then the remaining days of the week:
mysql> select count(id) from orders where dayofweek(date_ordered) < 4;
1 row in set (0.00 sec)
mysql> select count(id) from orders where dayofweek(date_ordered) > 3;
Trang 19Using DAYOFMONTH() , the following examples show the number of orders placed during the first
half of any month versus the second half:
mysql> select count(id) from orders where dayofmonth(date_ordered) < 16;
+ -+
| COUNT(id) | + -+
| 6 |
+ -+
1 row in set (0.00 sec) mysql> select count(id) from orders where dayofmonth(date_ordered) > 15; + -+
| COUNT(id) | + -+
| 2 |
+ -+
1 row in set (0.00 sec) You can use the DAYNAME() function to add more life to your results because it returns the name of the weekday for any given date: mysql> select dayname(date_ordered) from orders; + -+
| DAYNAME(date_ordered) | + -+
| Thursday |
| Monday |
| Thursday |
| Thursday |
| Wednesday |
| Thursday |
| Sunday |
| Sunday |
+ -+
8 rows in set (0.00 sec)
Functions aren't limited to WHERE clauses—you can use them in ORDER BY clauses as well:
mysql> select dayname(date_ordered) from orders
-> order by dayofweek(date_ordered);
Trang 20| DAYNAME(date_ordered) | + -+
| Sunday |
| Sunday |
| Monday |
| Wednesday |
| Thursday |
| Thursday |
| Thursday |
| Thursday |
+ -+
8 rows in set (0.00 sec) Working with Months and Years Days of the week aren't the only parts of the calendar, and MySQL has functions specifically for months and years as well Just like the DAYOFWEEK() and DAYNAME() functions, MONTH() and MONTHNAME() return the number of the month in a year and the name of the month for a given date For example: mysql> select month('2001-11-13'), monthname('2001-11-13'); + -+ -+
| MONTH('2001-11-13') | MONTHNAME('2001-11-13') | + -+ -+
| 11 | November |
+ -+ -+
1 row in set (0.00 sec) Using MONTHNAME() on the sample orders table shows the proper results but a lot of repeated data: mysql> select monthname(date_ordered) from orders; + -+
| MONTHNAME(date_ordered) | + -+
| November |
| November |
| November |
| November |
| November |
| November |
| November |
Trang 21| October |
+ -+
8 rows in set (0.00 sec) You can use DISTINCT to get nonrepetitive results: mysql> select distinct monthname(date_ordered) from orders; + -+
| MONTHNAME(date_ordered) | + -+
| November |
| October |
+ -+
2 rows in set (0.00 sec) For work with years, the YEAR() function will return the year of a given date: mysql> select distinct year(date_ordered) from orders; + -+
| YEAR(date_ordered) | + -+
| 2001 |
+ -+
1 row in set (0.00 sec) Working with Weeks Weeks can be tricky things—there can be 53 weeks in a year if Sunday is the first day of the week and December hasn't ended For example, December 30th of 2001 was a Sunday: mysql> select dayname('2001-12-30'); + -+
| DAYNAME('2001-12-30') | + -+
| Sunday |
+ -+
1 row in set (0.00 sec)
That fact made December 30th of 2001 part of the 53rd week of the year:
Trang 22mysql> select week('2001-12-30');
1 row in set (0.00 sec)
The 53rd week contains December 30th and 31st, and is only two days long; the first week of 2002
begins with January 1st
If you want your weeks to start on Mondays but still want to find the week of the year, the optional
second argument enables you to change the start day A 1 indicates a week that starts on Monday
In the following examples, a Monday start day makes December 30th part of the 52nd week of 2001,
but December 31 is still part of the 53rd week of 2001
mysql> select week('2001-12-30',1);
1 row in set (0.00 sec)
mysql> select week('2001-12-31',1);
1 row in set (0.00 sec)
Working with Hours, Minutes, and Seconds
If you're using a date that includes the exact time, such as datetime or timestamp , or even
just a time field, there are functions to find the hours, minutes, and seconds from that string Not
surprisingly, these functions are called HOUR() , MINUTE() , and SECOND() HOUR() returns
the hour in a given time, which is between 0 and 23 The range for MINUTE() and SECOND() is 0
to 59
Here are some examples:
mysql> select hour('2001-11-13 07:27:49') as hour,minute('2001-11-13 07:27:49') -> as minute,second('2001-11-13 07:27:49') as second;
Trang 231 row in set (0.00 sec)
That's a lot of queries to get at one time from a datetime field—you can put the hour and minutetogether and even use CONCAT_WS() to put the : between the results and get a representation ofthe time:
mysql> select concat_ws(':',hour('2001-11-13 07:27:49'),
1 row in set (0.00 sec)
If you use field names instead of strings, remember not to use quotation marks Here's an examplethat uses the dateadded field from the sometable table:
mysql> select concat_ws(':',hour(dateadded), minute(dateadded))
-> as sample_time from sometable;
9 rows in set (0.00 sec)
This is cheating because it's not the actual time—it's just two numbers stuck together to look like atime If you used the concatenation trick on a time such as 02:02 , the result would be 2:2 , asshown here:
Trang 24mysql> select concat_ws(':',hour('02:02'), minute('02:02')) as sample_time;
1 row in set (0.00 sec)
This result is obviously not the intended result In the next section, you learn how to use the
DATE_FORMAT() function to properly format dates and times
Formatting Dates and Times with MySQL
The DATE_FORMAT() function formats a date , datetime , or timestamp field into a string by
using options that tell it exactly how to display the results The syntax of DATE_FORMAT() is
DATE_FORMAT(date,format)
There are many formatting options, as shown in Table 11.3 , which should look somewhat similar to
Table 11.2 It's the same concept as the PHP date() function
Trang 27To display the 02:02 result that we rigged in the previous section, you'd use the %h and %i options
to return the hour and minute from the date with a : between the two options For example:
mysql> select date_format('2001-11-13 02:02:00', '%h:%i') as sample_time;
1 row in set (0.00 sec)
The following are just a few more examples of the DATE_FORMAT() function in use, but this
function is best understood by practicing it yourself
mysql> select date_format('2001-11-13', '%W, %M %D, %Y') as sample_time;
Trang 28mysql> select date_format(now(),'%W the %D of %M, %Y around %l o\'clock %p') -> as sample_time;
1 row in set (0.00 sec)
If you're working specifically with time fields, the TIME_FORMAT() function works just like the
DATE_FORMAT() function Only the format options for hours, minutes, and seconds are allowed:
mysql> select time_format('02:02:00', '%h:%i') as sample_time;
1 row in set (0.00 sec)
Performing Date Arithmetic with MySQL
MySQL has several functions to help perform date arithmetic, and this is one of the areas where it
might be quicker to allow MySQL to do the math than your PHP script The DATE_ADD() and
DATE_SUB() functions return a result given a starting date and an interval The syntax for both
functions is
DATE_ADD(date,INTERVAL value type)
DATE_SUB(date,INTERVAL value type)
Table 11.4 shows the possible types and their expected value format
Number of seconds
SECOND
Number of minutes
MINUTE
Trang 30mysql> select date_add(now(), interval 21 day);
1 row in set (0.00 sec)
To subtract 21 days, use
mysql> select date_sub(now(), interval 21 day);
1 row in set (0.00 sec)
Use the expression as it's shown in Table 11.4 , despite what might be a natural tendency to use
DAYS instead of DAY Using DAYS results in an error:
mysql> select date_add(now(), interval 21 days);
ERROR 1064: You have an error in your SQL syntax near 'days)' at line 1
If you're using DATE_ADD() or DATE_SUB() with a date value instead of a datetime value,the result will be shown as a date value unless you use expressions related to hours, minutes, andseconds In that case, your result will be a datetime result
For example, the result of the first query remains a date field, whereas the second becomes a
1 row in set (0.00 sec)
mysql> select date_add("2001-12-31", interval 12 hour);
+ -+
Trang 31| DATE_ADD("2001-12-31", INTERVAL 12 HOUR) |
+ -+
| 2001-12-31 12:00:00 |
+ -+
1 row in set (0.00 sec)
Starting with MySQL version 3.23, you can also perform date arithmetic using the + and - operatorsinstead of DATE_ADD() and DATE_SUB() functions:
mysql> select "2001-12-31" + interval 1 day;
1 row in set (0.00 sec)
mysql> select "2001-12-31" - interval 14 hour;
1 row in set (0.00 sec)
Special Functions and Conversion Features
The MySQL NOW() function returns a current datetime result, and is useful for timestamping login
or access times, as well as numerous other tasks MySQL has a few other functions that performsimilarly
The CURDATE() and CURRENT_DATE() functions are synonymous, and each returns the currentdate in YYYY-MM-DD format:
mysql> select curdate(), current_date();
Trang 32Similarly, the CURTIME() and CURRENT_TIME() functions return the current time in HH:MM:SS
1 row in set (0.00 sec)
The NOW() , SYSDATE() , and CURRENT_TIMESTAMP() functions return values in full
datetime format (YYYY-MM-DD HH:MM:SS ):
mysql> select now(), sysdate(), current_timestamp();
+ -+ -+ -+
| now() | sysdate() | current_timestamp() | + -+ -+ -+
| 2002-09-16 09:14:50 | 2002-09-16 09:14:50 | 2002-09-16 09:14:50 | + -+ -+ -+
1 row in set (0.00 sec)
The UNIX_TIMESTAMP() function returns the current date in—or converts a given date to—Unixtimestamp format Unix timestamp format is in seconds since the epoch, or seconds since midnight,January 1, 1970 For example:
mysql> select unix_timestamp();
1 row in set (0.00 sec)
mysql> select unix_timestamp('1973-12-30');
Trang 33The FROM_UNIXTIME() function performs a conversion of a Unix timestamp to a full datetime
format when used without any options:
mysql> select from_unixtime('1032192914');
1 row in set (0.00 sec)
You can use the format options from the DATE_FORMAT() functions to display a timestamp in amore appealing manner:
mysql> select from_unixtime(unix_timestamp(), '%D %M %Y at %h:%i:%s');
1 row in set (0.00 sec)
If you're working with a number of seconds and want to convert the seconds to a time-formattedresult, you can use SEC_TO_TIME() and TIME_TO_SEC() to convert values back and forth.For example, 1440 seconds is equal to 24 minutes and vice versa:
mysql> select sec_to_time('1440'), time_to_sec('00:24:00');
Trang 34Additionally, you discovered that MySQL's built-in date and time functions can definitely take some ofthe load off your application by internally formatting dates and times and performing the date andtime arithmetic The formatting options used for the DATE_FORMAT() function provide a simplemethod to produce a custom display string from any sort of date field The DATE_ADD() and
DATE_SUB() functions and their numerous available interval types help you determine dates andtimes in the past or future Additionally, functions such as DAY(), WEEK(), MONTH(), and
YEAR() are useful for extracting parts of dates for use in WHERE or ORDER BY clauses
[ Team LiB ]
Trang 35A1: In PHP, use time() In MySQL, use UNIX_TIMESTAMP().
2: Which PHP function accepts a timestamp and returns an associative array that representsthe given date?
A2: The getdate() function returns an associative array whose elements contain aspects ofthe given date
3: Which PHP function do you use to format date information? What about using MySQL?
A3: In PHP, use date() In MySQL, use DATE_FORMAT()
4: Which PHP function could you use to check the validity of a date?
A4: You can check a date with the checkdate() function
Activity
Create a birthday countdown script Given form input of month, day, and year, output a messagethat tells the user how many days, hours, minutes, and seconds until the big day Use whatevercombination of PHP and MySQL functions you want
[ Team LiB ]
Trang 36[ Team LiB ]
Hour 12 Creating a Simple Calendar
This hour continues the date and time lesson from the previous hour, this time in the context ofcreating a small calendar
In this hour, you will learn
How to build a simple calendar script
How to build a class library to generate date pull-downs in HTML forms
[ Team LiB ]