Index: tests/regressiontests/admin_filters/tests.py
===================================================================
--- tests/regressiontests/admin_filters/tests.py	(revision 17667)
+++ tests/regressiontests/admin_filters/tests.py	(working copy)
@@ -10,6 +10,7 @@
 from django.contrib.auth.models import User
 from django.core.exceptions import ImproperlyConfigured
 from django.test import TestCase, RequestFactory
+from django.test.utils import override_settings
 from django.utils.encoding import force_unicode
 
 from .models import Book
@@ -115,6 +116,7 @@
 
     def setUp(self):
         self.today = datetime.date.today()
+        self.tomorrow = self.today + datetime.timedelta(days=1)
         self.one_week_ago = self.today - datetime.timedelta(days=7)
 
         self.request_factory = RequestFactory()
@@ -143,9 +145,8 @@
         request = self.request_factory.get('/')
         changelist = self.get_changelist(request, Book, modeladmin)
 
-        request = self.request_factory.get('/', {'date_registered__year': self.today.year,
-                                                 'date_registered__month': self.today.month,
-                                                 'date_registered__day': self.today.day})
+        request = self.request_factory.get('/', {'date_registered__gte': self.today,
+                                                 'date_registered__lt': self.tomorrow})
         changelist = self.get_changelist(request, Book, modeladmin)
 
         # Make sure the correct queryset is returned
@@ -157,13 +158,12 @@
         self.assertEqual(force_unicode(filterspec.title), u'date registered')
         choice = select_by(filterspec.choices(changelist), "display", "Today")
         self.assertEqual(choice['selected'], True)
-        self.assertEqual(choice['query_string'], '?date_registered__day=%s'
-                                                 '&date_registered__month=%s'
-                                                 '&date_registered__year=%s'
-                                                % (self.today.day, self.today.month, self.today.year))
+        self.assertEqual(choice['query_string'], '?date_registered__gte=%s'
+                                                 '&date_registered__lt=%s'
+                                                % (self.today, self.tomorrow))
 
-        request = self.request_factory.get('/', {'date_registered__year': self.today.year,
-                                                 'date_registered__month': self.today.month})
+        request = self.request_factory.get('/', {'date_registered__gte': self.today.replace(day=1),
+                                                 'date_registered__lt': self.tomorrow})
         changelist = self.get_changelist(request, Book, modeladmin)
 
         # Make sure the correct queryset is returned
@@ -179,11 +179,12 @@
         self.assertEqual(force_unicode(filterspec.title), u'date registered')
         choice = select_by(filterspec.choices(changelist), "display", "This month")
         self.assertEqual(choice['selected'], True)
-        self.assertEqual(choice['query_string'], '?date_registered__month=%s'
-                                                 '&date_registered__year=%s'
-                                                % (self.today.month, self.today.year))
+        self.assertEqual(choice['query_string'], '?date_registered__gte=%s'
+                                                 '&date_registered__lt=%s'
+                                                % (self.today.replace(day=1), self.tomorrow))
 
-        request = self.request_factory.get('/', {'date_registered__year': self.today.year})
+        request = self.request_factory.get('/', {'date_registered__gte': self.today.replace(month=1, day=1),
+                                                 'date_registered__lt': self.tomorrow})
         changelist = self.get_changelist(request, Book, modeladmin)
 
         # Make sure the correct queryset is returned
@@ -199,11 +200,12 @@
         self.assertEqual(force_unicode(filterspec.title), u'date registered')
         choice = select_by(filterspec.choices(changelist), "display", "This year")
         self.assertEqual(choice['selected'], True)
-        self.assertEqual(choice['query_string'], '?date_registered__year=%s'
-                                                % (self.today.year))
+        self.assertEqual(choice['query_string'], '?date_registered__gte=%s'
+                                                 '&date_registered__lt=%s'
+                                                % (self.today.replace(month=1, day=1), self.tomorrow))
 
         request = self.request_factory.get('/', {'date_registered__gte': str(self.one_week_ago),
-                                                 'date_registered__lte': str(self.today)})
+                                                 'date_registered__lt': str(self.tomorrow)})
         changelist = self.get_changelist(request, Book, modeladmin)
 
         # Make sure the correct queryset is returned
@@ -216,9 +218,14 @@
         choice = select_by(filterspec.choices(changelist), "display", "Past 7 days")
         self.assertEqual(choice['selected'], True)
         self.assertEqual(choice['query_string'], '?date_registered__gte=%s'
-                                                 '&date_registered__lte=%s'
-                                                % (str(self.one_week_ago), str(self.today)))
+                                                 '&date_registered__lt=%s'
+                                                % (str(self.one_week_ago), str(self.tomorrow)))
 
+    @override_settings(USE_TZ=True)
+    def test_datefieldlistfilter_with_time_zone_support(self):
+        # Regression for #17830
+        self.test_datefieldlistfilter()
+
     def test_allvaluesfieldlistfilter(self):
         modeladmin = BookAdmin(Book, site)
 
Index: django/contrib/admin/filters.py
===================================================================
--- django/contrib/admin/filters.py	(revision 17667)
+++ django/contrib/admin/filters.py	(working copy)
@@ -11,6 +11,7 @@
 from django.core.exceptions import ImproperlyConfigured
 from django.utils.encoding import smart_unicode
 from django.utils.translation import ugettext_lazy as _
+from django.utils import timezone
 
 from django.contrib.admin.util import (get_model_from_relation,
     reverse_field_path, get_limit_choices_to_from_path, prepare_lookup_value)
@@ -282,44 +283,49 @@
         self.field_generic = '%s__' % field_path
         self.date_params = dict([(k, v) for k, v in params.items()
                                  if k.startswith(self.field_generic)])
-        today = datetime.date.today()
-        one_week_ago = today - datetime.timedelta(days=7)
-        today_str = str(today)
+
+        now = timezone.now()
+        # When time zone support is enabled, convert "now" to the user's time
+        # zone so that the definition of "Today" matches what the user expect.
+        if now.tzinfo is not None:
+            current_tz = timezone.get_current_timezone()
+            now = now.astimezone(current_tz)
+            if hasattr(current_tz, 'normalize'):
+                # available for pytz time zones
+                now = current_tz.normalize(now)
+
         if isinstance(field, models.DateTimeField):
-            today_str += ' 23:59:59'
-        self.lookup_kwarg_year = '%s__year' % field_path
-        self.lookup_kwarg_month = '%s__month' % field_path
-        self.lookup_kwarg_day = '%s__day' % field_path
-        self.lookup_kwarg_past_7_days_gte = '%s__gte' % field_path
-        self.lookup_kwarg_past_7_days_lte = '%s__lte' % field_path
+            today = now.replace(hour=0, minute=0, second=0, microsecond=0)
+        else:       # field is a models.DateField
+            today = now.date()
+        tomorrow = today + datetime.timedelta(days=1)
+    
+        self.lookup_kwarg_since = '%s__gte' % field_path
+        self.lookup_kwarg_until = '%s__lt' % field_path
         self.links = (
             (_('Any date'), {}),
             (_('Today'), {
-                self.lookup_kwarg_year: str(today.year),
-                self.lookup_kwarg_month: str(today.month),
-                self.lookup_kwarg_day: str(today.day),
+                self.lookup_kwarg_since: str(today),
+                self.lookup_kwarg_until: str(tomorrow),
             }),
             (_('Past 7 days'), {
-                self.lookup_kwarg_past_7_days_gte: str(one_week_ago),
-                self.lookup_kwarg_past_7_days_lte: today_str,
+                self.lookup_kwarg_since: str(today - datetime.timedelta(days=7)),
+                self.lookup_kwarg_until: str(tomorrow),
             }),
             (_('This month'), {
-                self.lookup_kwarg_year: str(today.year),
-                self.lookup_kwarg_month: str(today.month),
+                self.lookup_kwarg_since: str(today.replace(day=1)),
+                self.lookup_kwarg_until: str(tomorrow),
             }),
             (_('This year'), {
-                self.lookup_kwarg_year: str(today.year),
+                self.lookup_kwarg_since: str(today.replace(month=1, day=1)),
+                self.lookup_kwarg_until: str(tomorrow),
             }),
         )
         super(DateFieldListFilter, self).__init__(
             field, request, params, model, model_admin, field_path)
 
     def expected_parameters(self):
-        return [
-            self.lookup_kwarg_year, self.lookup_kwarg_month,
-            self.lookup_kwarg_day, self.lookup_kwarg_past_7_days_gte,
-            self.lookup_kwarg_past_7_days_lte
-        ]
+        return [self.lookup_kwarg_since, self.lookup_kwarg_until]
 
     def choices(self, cl):
         for title, param_dict in self.links:
