Previous Page Next Page

Formatting Dates

This section discusses using filters to display and format date and time variables inside the template files. You probably will work with dates to either display the current date or display dates that are fields in a model.

The following sections describe the date, time, now, timesince, and timeuntil filters and how to apply them in a template.

date

The date filter can be applied to Python date variables, including date fields in a model object. The date filter accepts a string of format characters as an argument and formats the date based on those characters. For a full description of the datetime format characters, refer to Appendix C, "Formatting Dates and Times."

The following examples should help you understand how the date filter works. The entryDate variable is a date instance with a value of February 7, 2005.

The following code applies the j character to render the day of the week without the leading 0, the S character to render the English day/month suffix, the F character to render the month as textual, and the Y character to render the four-digit year:

{{ entryDate|date:"jS F Y" }}
renders
7th February 2005

The following code applies the D character to render the three-character day-of-the-week text, the F character to render the month as textual, the j character to render the day of the week without the leading 0, the S character to render the English day/month suffix, and the Y character to render the four-digit year:

{{ entryDate|date:"D, F jS, Y" }}
renders
Mon, February 7th, 2005

The following code applies the m character to add the two-digit month value, the d character to add the two-digit day value, and the Y character to add the four-digit year:

{{ entryDate|date:"m/d/Y" }}
renders
02/07/2005

Did you Know?

Did you notice that the comma and slash characters that were added to the format string for the date filter get rendered with the values specified by the format characters?


time

The time filter can be applied to Python date and datetime variables, including datetime fields in a model object, the same way that the date filter is. The time filter also accepts a string of format characters as an argument and formats the time based on those characters. For a full description of the datetime format characters, refer to Appendix C.

By the Way

You can use only the characters that format time specifically in the time filter. The date characters will not work.


The following examples should help you understand how the time filter works. The someTime variable is a time instance with a value of 10:51 p.m. MDT.

The following code applies the h character to render the two-digit hour in 12-hour format, the i character to render the two-digit minutes value, the a character to render the a.m./p.m. text string, and the T character to render the timezone string:

{{ someTime|date:"h:ia T" }}
renders
10:51p.m. Mountain Daylight Time

The following code applies the H character to render the two-digit hour in 24-hour format, the i character to render the two-digit minutes value, the s character to render the two-digit seconds value, the a character to render the AM/PM text string, and the O character to render the offset to Greenwich time:

{{ someTime|date:"H:i:sAO" }}
renders
22:51:46PM+1800

Did you Know?

Did you notice that the colon characters that were added to the format string for the time filter get rendered with the values specified by the format characters?


now

Because we are discussing the date and time filters in this section, it would be a good idea to discuss the now tag as well. The now tag works similarly to the date and time filters in that it accepts a string of format characters to format the current date and time. However, the now tag uses tag syntax instead of filter syntax and is not applied to a variable object. The following line of code shows how to render the current date and time in a template using the now filter:

{% now "M d, Y g:ma" %}

This line of code renders the date and time in the following format:

Jan 17, 2008 3:01p.m.

For a full description of the datetime format characters, refer to Appendix C.

timesince and timeuntil

The timesince filter can be applied to either a time or datetime variable. It accepts an optional time or datetime object as the only argument. The timesince filter determines the time since the time or datetime variable to the current time and renders a textual string noting the difference.

The timeuntil filter can also be applied to either a time or datetime variable. It also accepts an optional time or datetime object as the only argument. However, the timeuntil filter subtracts the current time from the time or datetime variable and renders a textual string noting the delta.

If a time or datetime argument is added, the timesince and timeuntil filters determine the time elapsed between the filter argument and the variable, and render a textual string noting the difference.

Watch Out!

Currently, the time or datetime argument should be earlier than that of the original variable in both the timeuntil and timesince filters. This was different than I expected. I'm not certain if this will change in the future.


The timesince and timeuntil filters measure the difference in units of years, months, days, minutes, and seconds. However, only the two largest units are displayed, such as years and months, months and days, days and hours, hours and minutes, and minutes and seconds.

The following code snippet shows an example of using the timeuntil and timesince filters to display textual information about the last archive date, next archive date, and current date and time:

<h1>Archive Data</h1>
<table border=1 padding=2>
<tr>
    <td>Current Time</td>
    <td>Last Archive</td>
    <td>Next Archive</td>
</tr>
<tr>
    <td>{% now "M d, Y h:m:sa" %}</td>
    <td>{{ lastArch|date:"M d, Y h:m:sa" }}</td>
    <td>{{ nextArch|date:"M d, Y h:m:sa" }}</td>
</tr>
</table>
<p>
It has been {{ lastArch|timesince }}
since the last archive.<p>
The next archive will take place in
{{ nextArch|timeuntil }}.<p>

The time between the archives will be
{{ nextArch|timeuntil:lastArch }}.

Figure 9.7 shows the output of the code in the web browser.

Figure 9.7. The archive details web page generated by the code snippet using the now tag, timeuntil filter, and timesince filter.


Try It Yourself: Format Date and Time Variables in a Template

In this section, you will add a datetime field to the Blog model in the Person application. You will use the date formatting filters to display the dates correctly in the Person details view.

Follow these steps to add the datetime field to the Blog model and update the person_details.py template:

1.
Stop the development server.

2.
Open the iFriends/People/models.py file in an editor.

3.
Add the following line of code to the Blog model to add a datetime field called Last Modified:

date = models.DateTimeField('Last Modified')

4.
Save the iFriends/People/models.py file.

Watch Out!

You need to synchronize the changes to the Blog model to the database. Django currently cannot do this. It is recommended that you sync the application to the database only once (when it is created). However, in the real world, we know that isn't possible. I've been able to update the database by removing the table(s) for the model that is changed and then synchronizing the database. To get the models in the database to update, you need to drop the people_blog table in the database, which means that all the data in that table will be lost. The following steps take you through the process of updating the database properly. Hopefully, Django will fix this in the future. If Django changes things and these steps do not work, you may need to drop the entire database (lose all your data) and then synchronize.

5.
Open a MySQL command-line client.

6.
From the MySQL command prompt, enter the following commands to drop the people_blog table:

use ifriendsdb;
drop table people_blog;

7.
Use the following command from the iFriends root directory to synchronize the updated Blog model to the database:

python manage.py syncdb

8.
Use the following command from the iFriends root directory to start the development server:

python manage.py runserver

9.
Access the admin interface using the following URL. Verify that the Blog objects have the new Last Modified field, and create some new blog entries.

http://127.0.0.1:8000/admin

By the Way

Django doesn't display the Last Modified datetime field because we used the auto_now option, which overrides any value you might add in the admin interface.

10.
Open the iFriends/templates/Person/person_details.py file in a web browser.

11.
Modify the following line to format the birthday date field correctly, as shown in Listing 9.5:

<li>Birthday: {{ p.birthday|date:"m/d/Y" }}</li>

12.
Add the following lines of code to the blog list to display the blog's Last Modified date, as shown in Listing 9.5:

<li>
    {{ b.title }} -
    <font size="2"> {{ b.date|date:"M d, Y g:ma" }}</font>
</li>

13.
Save the iFriends/templates/Person/person_details.py file.

14.
Access one of the Person details pages from the following address in a web browser, as shown in Figure 9.8, and view the new dates you added.

Figure 9.8. Person details view that has formatted dates for the birthday and blog list items.


http://127.0.0.1:8000/People/Info/1/

Listing 9.5 shows the complete person_details.py file.

Listing 9.5. Full Contents of iFriends/templates/Person/person_details.py

{% extends "iFriends_base.html" %}

{% block title %}Details{% endblock %}
{% block content %}
<table width=100%>
<tr bgcolor="aabbcc"><td colspan="3">
<font size="5" color="white">Personal Information</font>
</td></tr>
<tr valign="top"><td width=30% bgcolor="aaaaaa"><font color="white" size="5">
    <li>Name: {{p.name}}</li>
    <li>Birthday: {{ p.birthday|date:"m/d/Y" }}</li>
    <li>Gender:
        {% ifequal p.gender "M" %}            Bloke
        {% else %}
            Sheila
        {% endifequal %}
    </li>
    <li>Desc: {{ p.desc }} </li>
</font></td>
<td width=40% bgcolor="aa99aa"><font color="white" size="4">
    {% include "quote.html" %}
</font></td>
<td width=30%>
    <h3>Contact Info</h3>
    <li>Email: {{ p.email }}</li>
    <li>Website: {{ p.favoriteURL }}</li>
</td></tr>
<tr>
<td width="30%" bgcolor="556677" valign="top">
    <font color="white" size="4">
    {% with p.friends.all as fl %}
    <h3>
        {{ fl|length|yesno:"iFriend,No Friend"}}{{fl|length|pluralize}}
    </h3>
    {% for f in fl %}
    <li>{{ f.name }}</li>
    {% endfor %}
    {% endwith %}
    </font>
</td>
<td width="70%" bgcolor="555555" colspan="2" valign="top">
    <font color="white" size="4">
    {% with p.blogs.all as bl %}
    <h3>
        {{ bl|length|yesno:"Blog,No Blog"}}
        Entr{{ bl|length|pluralize:"y,ies"}}
    </h3>
    {% for b in bl %}
    <li>{{ b.title }} -
        <font size="2"> {{ b.date|date:"M d, Y g:ma" }}</font>
    </li>
    {% endfor %}
    {% endwith %}
    </font>
</td>
</tr>
</table>
{% endblock %}


					  


Previous Page Next Page