As I explained in Chapter 14, MySQL has several column types that store dates and times, the most important of which are DATE,DATETIME, and TIMESTAMP. As the name suggests, DATEstores only the year, month, and date; the other two store both the date and the time. Since it’s easy to extract just the date part, this might narrow down your choices to just DATETIMEand TIMESTAMP. In MySQL 4.1 and above, both store the date and time in the same format. For example, 10:08 a.m. on September 2, 2008, is stored like this:
2008-09-02 10:08:00
17
Versions prior to MySQL 4.1 use the same format for a DATETIMEcolumn but store the same date and time in a TIMESTAMPcolumn without any punctuation—in other words, like this:
20080902100800
Although this is less human-readable than the current format, it makes no difference, because the functions used for formatting dates and times work identically with either format.
So, what’s the difference between DATETIME and TIMESTAMP? It can be summarized as follows:
DATETIME: This stores any combination of date and time between New Year’s Day in the year 1000 to New Year’s Eve in the year 9999. The date must be inserted explic- itly. If no time is specified, MySQL automatically sets the time element to 00:00:00.
If an invalid date is specified, MySQL silently changes it to 0000-00-00 00:00:00.
TIMESTAMP: The main purpose of this column type is to store the current date and time automatically. However, only one TIMESTAMPcolumn in a table can have this automatic behavior. By default, the first TIMESTAMPcolumn in a table records the current date and time when a record is inserted and updates the date and time whenever the value of at least one other column is changed.
To simplify it even further: use DATETIMEwhen you want to record a specific date, and use TIMESTAMPwhen you want to record the current date and time.
The problem with simple rules is that life is rarely simple. Sometimes, you might want to store specific dates but have the ability to use the current date and time. The answer is to use the MySQL function NOW(). Unfortunately, Dreamweaver doesn’t have the ability to incorporate MySQL functions as values for Insert Record and Update Record server behav- iors. You need to adjust the code manually.
Another scenario is where you want to keep track of when a record is updated without losing the time of its original creation. In this case, the answer is to use two TIMESTAMP columns. Since only one TIMESTAMPcolumn can have automatic properties, use the first one to keep track of when the record is updated, and prime the second column with NOW(). If nothing is entered in either column when a record is updated, the first TIMESTAMP column automatically updates to the new date and time, and the second one retains the time of original creation.
Both scenarios involve using NOW()to insert the value in a MySQL column, so let’s see how it’s done.
Since the second TIMESTAMPcolumn is being used to store a static date and time, you might wonder why not use a DATETIMEcolumn instead. It’s simply a question of efficiency. A TIMESTAMP column requires only half the storage space of a DATETIMEone.
The following exercise shows you how to adapt the code generated by a Dreamweaver Insert Record server behavior to pass a MySQL function, such as NOW(), as the value to be inserted in a column. It takes advantage of an undocumented aspect of Dreamweaver’s GetSQLValueString()function.
1.Open phpMyAdmin, and select the dwcs4database.
2.Create a new table called date_testwith five columns (fields). Use the settings in Table 17-1 to define the table.
Table 17-1.Settings for the date_test table
Field Type Length/Values Attributes Index A_I
pk INT UNSIGNED PRIMARY Yes
updated TIMESTAMP created TIMESTAMP fixed_date DATETIME
message VARCHAR 100
When you save the table definition, the structure should look like this in phpMyAdmin:
Using NOW() with the Insert Record server behavior
17
Note that MySQL 5.0 and higher displays the automatic properties of the updated column, because it’s the first TIMESTAMPcolumn in the table. The same automatic properties apply even if you’re using an older version of MySQL, but they’re not displayed in phpMyAdmin.
3.Copy current_date_start.phpfrom examples/ch17toworkfiles/ch17, and save it as current_date.php. The page contains a form with two text fields, one for a message and the other to enter a date, as shown in the following screenshot:
4.Click anywhere inside the form, and insert a hidden field. In the Property inspector, name the hidden field created, and give it the value NOW(), as shown here:
5.Apply an Insert Record server behavior. When you select the date_testtable, the settings should look like this:
Let’s examine these values. Unused Primary Keyis fine, because the pkcolumn was set to increment automatically. Does Not Get a Valueis also fine for the updatedcol- umn, because the first TIMESTAMPcolumn is initialized automatically with the cur- rent date and time.
The createdand fixed_datecolumns are listed as getting dates. This looks quite promising, but don’t be lulled into a false sense of security. Dreamweaver handles a date in the same way as text, surrounding it with quotes, but NOW()is a function
and must not be enclosed in quotes. So, these two columns will need to be fixed manually once the server behavior has been applied.
Finally, the messagecolumn looks OK, because it’s getting its value from the form as text.
6.Click OK to apply the Insert Record server behavior, and then switch to Code view to locate the code generated by Dreamweaver. The section that builds the INSERT
query is shown in Figure 17-15. 17
Figure 17-15.You need to edit the Insert Record server behavior code to use NOW() as the value for a date column.
7.The createdcolumn gets its value from the hidden field that you created in step 4.
However, passing that value to the GetSQLValueString()function as a datedata type results in MySQL attempting to insert NOW()as a string. This is invalid for a date column, so you end up with 0000-00-00 00:00:00instead of the current date and time.
Fortunately, the GetSQLValueString() function accepts two optional arguments for you to incorporate user-defined values in a SQL query. Amend the code shown on line 41 of Figure 17-15 like this:
GetSQLValueString($_POST['created'], "defined", 'NOW()'),
This tells GetSQLValueString()to incorporate NOW()into the query without any quotes, so it is used correctly as a function. Don’t be confused by the quotes around NOW()when you pass it as an argument to GetSQLValueString(). It’s what happens inside the function that matters. GetSQLValueString() prepares values for incorporation into a SQL query by removing magic quotes, escaping characters that cause problems with database queries, and adding quotes where required.
Using "defined"as the second argument lets you pass a MySQL function safely as the third argument.
8.The code created by Dreamweaver for the fixed_datecolumn is OK as long as the user inserts a date. However, the form in current_date.php instructs the user to leave the field blank to insert the current date. This suggests that you need a conditional statement. Indeed, you do, but that’s taken care of inside GetSQLValueString().
As I said earlier, the function accepts two optional arguments. The first optional argument sets the value if the submitted variable contains a value. The second optional argument is used if the submitted variable is empty. So, this is how you edit the code shown on line 42 of Figure 17-15:
GetSQLValueString($_POST['fixed_date'], "defined", ➥ GetSQLValueString($_POST['fixed_date'], "date"), 'NOW()'),
At first glance, this looks bizarre, but let’s analyze what’s happening here. The first argument to GetSQLValueString() is $_POST['fixed_date']. This is the value
submitted from the form field. The second argument is "defined". This tells GetSQLValueString()to use the third argument if the form field contains a value or to use the fourth argument if the form field is empty. Let’s deal with the fourth argument first, because it’s straightforward. The fourth argument is 'NOW()', so the SQL query will use NOW()as a function if the form field is left blank.
Now, let’s return to the third argument, which is used if the form field isn’t blank.
If you look at it on its own, it’s exactly the same as the original code on line 42 of Figure 17-15. In other words, if the form field contains a value, it’s passed to GetSQLValueString()and treated as a date.
9.Save current_date.php, and load it into a browser.
10.The only purpose of the messagefield is to give you something to update and iden- tify each record. Enter some text, and leave the fixed_datefield empty. Click the Insertbutton. If nothing is wrong with your code, the form should submit the val- ues and remain onscreen with empty fields.
11.Submit the form twice more, once with a date in MySQL format (YYYY-MM-DD) and the other time with a date in American (MM/DD/YYYY) or European (DD/MM/YYYY) format.
12.Click the Browse tab in phpMyAdmin to view the contents of the date_testtable.
You should see something similar to Figure 17-16.
Figure 17-16.The fields are correctly populated with the date and time, except when an invalid format is used.
As Figure 17-16 shows, the date and time are the same in all three columns in the first record. The first two columns are the same in the second record, but the fixed_datecolumn has recorded the date (2008-08-08) I entered in MySQL for- mat. However, when I entered 12/25/2008in the final record, fixed_datewas set to 0000-00-00 00:00:00. By the way, this has nothing to do with using forward slashes—MySQL accepts a wide range of separators, which it converts silently to dashes. The problem lies with year, month, and date being in the wrong order. The only solution is to format dates correctly before attempting to store them in MySQL. We’ll look at that next.
You can check your code, if necessary, against current_date.phpin examples/ch17.