diff --git a/django/db/backends/__init__.py b/django/db/backends/__init__.py
index 7674f5c..c8f010a 100644
--- a/django/db/backends/__init__.py
+++ b/django/db/backends/__init__.py
@@ -1,4 +1,7 @@
+import datetime
+
 from django.db.utils import DatabaseError
+from django.utils import timezone
 
 try:
     import thread
@@ -807,9 +810,17 @@ class BaseDatabaseOperations(object):
 
         `value` is an int, containing the looked-up year.
         """
-        first = '%s-01-01 00:00:00'
-        second = '%s-12-31 23:59:59.999999'
-        return [first % value, second % value]
+        tz = timezone.get_current_timezone() if settings.USE_TZ else None
+        first_dt = datetime.datetime(year=value, month=01, day=01, tzinfo=tz)
+        second_dt = datetime.datetime(year=value, month=12, day=31, hour=23,
+                                      minute=59, second=59, microsecond=999999,
+                                      tzinfo=tz)
+        if settings.USE_TZ:
+            first_dt = first_dt.astimezone(timezone.utc)
+            second_dt = second_dt.astimezone(timezone.utc)
+        first = first_dt.strftime('%Y-%m-%d %H:%M:%S')
+        second = second_dt.strftime('%Y-%m-%d %H:%M:%S.%f')
+        return [first, second]
 
     def year_lookup_bounds_for_date_field(self, value):
         """
diff --git a/django/db/backends/postgresql_psycopg2/operations.py b/django/db/backends/postgresql_psycopg2/operations.py
index 949a05c..861d742 100644
--- a/django/db/backends/postgresql_psycopg2/operations.py
+++ b/django/db/backends/postgresql_psycopg2/operations.py
@@ -1,4 +1,6 @@
 from django.db.backends import BaseDatabaseOperations
+from django.conf import settings
+from django.utils import timezone
 
 
 class DatabaseOperations(BaseDatabaseOperations):
@@ -7,11 +9,18 @@ class DatabaseOperations(BaseDatabaseOperations):
 
     def date_extract_sql(self, lookup_type, field_name):
         # http://www.postgresql.org/docs/8.0/static/functions-datetime.html#FUNCTIONS-DATETIME-EXTRACT
+        field_sql = field_name
+        if settings.USE_TZ:
+            # Hey, I finally managed to get the UTC offset! And in oh-so-beautiful way...
+            # Will this break at DST?
+            time_offset = timezone.now().astimezone(timezone.get_current_timezone()).utcoffset()
+            if time_offset:
+                field_sql = self.date_interval_sql(field_name, '+', time_offset)
         if lookup_type == 'week_day':
             # For consistency across backends, we return Sunday=1, Saturday=7.
-            return "EXTRACT('dow' FROM %s) + 1" % field_name
+            return "EXTRACT('dow' FROM %s) + 1" % field_sql
         else:
-            return "EXTRACT('%s' FROM %s)" % (lookup_type, field_name)
+            return "EXTRACT('%s' FROM %s)" % (lookup_type, field_sql)
 
     def date_interval_sql(self, sql, connector, timedelta):
         """
@@ -32,7 +41,23 @@ class DatabaseOperations(BaseDatabaseOperations):
 
     def date_trunc_sql(self, lookup_type, field_name):
         # http://www.postgresql.org/docs/8.0/static/functions-datetime.html#FUNCTIONS-DATETIME-TRUNC
-        return "DATE_TRUNC('%s', %s)" % (lookup_type, field_name)
+        field_sql = field_name
+        if settings.USE_TZ:
+            # Hey, I finally managed to get the UTC offset! And in oh-so-beautiful way...
+            # Will this break at DST?
+            time_offset = timezone.now().astimezone(timezone.get_current_timezone()).utcoffset()
+            if time_offset:
+                field_sql = self.date_interval_sql(field_name, '+', time_offset)
+            # Alternate way: better except we don't know if PostgreSQL happens to support this
+            # timezone... For example the testing returns +0300 for me, which really isn't a
+            # timezone name :( The above way is a hack at its core, we really don't know if the
+            # offset is correct for the date in the DB. It is likely not going to matter, the
+            # DST offset is usually just one hour. But for example some country can change
+            # their time zone for 23 hours, and that would break date lookups. Maybe a bit
+            # non-realistic problem, but to be totally correct we should use PostgreSQL's at
+            # time zone, not adding the current UTC offset.
+            # field_sql = field_name + " AT TIME ZONE '%s'" % timezone.get_current_timezone_name()
+        return "DATE_TRUNC('%s', %s)" % (lookup_type, field_sql)
 
     def deferrable_sql(self):
         return " DEFERRABLE INITIALLY DEFERRED"
diff --git a/django/db/backends/sqlite3/base.py b/django/db/backends/sqlite3/base.py
index 0b19442..421d883 100644
--- a/django/db/backends/sqlite3/base.py
+++ b/django/db/backends/sqlite3/base.py
@@ -127,6 +127,25 @@ class DatabaseOperations(BaseDatabaseOperations):
         # single quotes are used because this is a string (and could otherwise
         # cause a collision with a field name).
         return "django_date_trunc('%s', %s)" % (lookup_type.lower(), field_name)
+ 
+    def year_lookup_bounds(self, value):
+        """
+        Returns a two-elements list with the lower and upper bound to be used
+        with a BETWEEN operator to query a field value using a year lookup
+
+        `value` is an int, containing the looked-up year.
+        """
+        tz = timezone.get_current_timezone() if settings.USE_TZ else None
+        first_dt = datetime.datetime(year=value, month=01, day=01, tzinfo=tz)
+        second_dt = datetime.datetime(year=value, month=12, day=31, hour=23,
+                                      minute=59, second=59, microsecond=999999,
+                                      tzinfo=tz)
+        if settings.USE_TZ:
+            first_dt = first_dt.astimezone(timezone.utc)
+            second_dt = second_dt.astimezone(timezone.utc)
+        first = first_dt.strftime('%Y-%m-%d')
+        second = second_dt.strftime('%Y-%m-%d %H:%M:%S.%f')
+        return [first, second]
 
     def drop_foreignkey_sql(self):
         return ""
@@ -178,11 +197,6 @@ class DatabaseOperations(BaseDatabaseOperations):
 
         return unicode(value)
 
-    def year_lookup_bounds(self, value):
-        first = '%s-01-01'
-        second = '%s-12-31 23:59:59.999999'
-        return [first % value, second % value]
-
     def convert_values(self, value, field):
         """SQLite returns floats when it should be returning decimals,
         and gets dates and datetimes wrong.
@@ -359,6 +373,9 @@ def _sqlite_extract(lookup_type, dt):
         dt = util.typecast_timestamp(dt)
     except (ValueError, TypeError):
         return None
+    if settings.USE_TZ:
+        tz = timezone.get_current_timezone()
+        dt = dt.astimezone(tz)
     if lookup_type == 'week_day':
         return (dt.isoweekday() % 7) + 1
     else:
@@ -369,6 +386,9 @@ def _sqlite_date_trunc(lookup_type, dt):
         dt = util.typecast_timestamp(dt)
     except (ValueError, TypeError):
         return None
+    if settings.USE_TZ:
+        tz = timezone.get_current_timezone()
+        dt = dt.astimezone(tz)
     if lookup_type == 'year':
         return "%i-01-01 00:00:00" % dt.year
     elif lookup_type == 'month':
diff --git a/tests/modeltests/timezones/tests.py b/tests/modeltests/timezones/tests.py
index a8d2c0c..81642df 100644
--- a/tests/modeltests/timezones/tests.py
+++ b/tests/modeltests/timezones/tests.py
@@ -277,6 +277,15 @@ LegacyDatabaseTests = override_settings(USE_TZ=False)(LegacyDatabaseTests)
 
 #@override_settings(USE_TZ=True)
 class NewDatabaseTests(BaseDateTimeTests):
+    @requires_tz_support
+    def test_day_in_current_tz(self):
+        dt = datetime.datetime(2012, 03, 05, 01, 00, 00)
+        dt = dt.replace(tzinfo=EAT)
+        Event.objects.create(dt=dt)
+        with timezone.override(UTC):
+            self.assertEqual(Event.objects.dates('dt', 'day')[0].day, 4)
+        with timezone.override(EAT):
+            self.assertEqual(Event.objects.dates('dt', 'day')[0].day, 5)
 
     @requires_tz_support
     @skipIf(sys.version_info < (2, 6), "this test requires Python >= 2.6")
@@ -427,10 +436,16 @@ class NewDatabaseTests(BaseDateTimeTests):
         # implementation is changed to perform the aggregation is local time.
         Event.objects.create(dt=datetime.datetime(2011, 1, 1, 1, 30, 0, tzinfo=EAT))
         Event.objects.create(dt=datetime.datetime(2011, 1, 1, 4, 30, 0, tzinfo=EAT))
-        self.assertEqual(Event.objects.filter(dt__year=2011).count(), 1)
-        self.assertEqual(Event.objects.filter(dt__month=1).count(), 1)
-        self.assertEqual(Event.objects.filter(dt__day=1).count(), 1)
-        self.assertEqual(Event.objects.filter(dt__week_day=7).count(), 1)
+        with timezone.override(EAT):
+            self.assertEqual(Event.objects.filter(dt__year=2011).count(), 2)
+            self.assertEqual(Event.objects.filter(dt__month=1).count(), 2)
+            self.assertEqual(Event.objects.filter(dt__day=1).count(), 2)
+            self.assertEqual(Event.objects.filter(dt__week_day=7).count(), 2)
+        with timezone.override(UTC):
+            self.assertEqual(Event.objects.filter(dt__year=2011).count(), 1)
+            self.assertEqual(Event.objects.filter(dt__month=1).count(), 1)
+            self.assertEqual(Event.objects.filter(dt__day=1).count(), 1)
+            self.assertEqual(Event.objects.filter(dt__week_day=7).count(), 1)
 
     def test_query_aggregation(self):
         # Only min and max make sense for datetimes.
@@ -469,18 +484,29 @@ class NewDatabaseTests(BaseDateTimeTests):
         # Same comment as in test_query_date_related_filters.
         Event.objects.create(dt=datetime.datetime(2011, 1, 1, 1, 30, 0, tzinfo=EAT))
         Event.objects.create(dt=datetime.datetime(2011, 1, 1, 4, 30, 0, tzinfo=EAT))
-        self.assertQuerysetEqual(Event.objects.dates('dt', 'year'),
-                [datetime.datetime(2010, 1, 1, tzinfo=UTC),
-                 datetime.datetime(2011, 1, 1, tzinfo=UTC)],
-                transform=lambda d: d)
-        self.assertQuerysetEqual(Event.objects.dates('dt', 'month'),
-                [datetime.datetime(2010, 12, 1, tzinfo=UTC),
-                 datetime.datetime(2011, 1, 1, tzinfo=UTC)],
-                transform=lambda d: d)
-        self.assertQuerysetEqual(Event.objects.dates('dt', 'day'),
-                [datetime.datetime(2010, 12, 31, tzinfo=UTC),
-                 datetime.datetime(2011, 1, 1, tzinfo=UTC)],
-                transform=lambda d: d)
+        with timezone.override(EAT):
+            self.assertQuerysetEqual(Event.objects.dates('dt', 'year'),
+                    [datetime.datetime(2011, 1, 1, tzinfo=UTC)],
+                    transform=lambda d: d)
+            self.assertQuerysetEqual(Event.objects.dates('dt', 'month'),
+                    [datetime.datetime(2011, 1, 1, tzinfo=UTC)],
+                    transform=lambda d: d)
+            self.assertQuerysetEqual(Event.objects.dates('dt', 'day'),
+                    [datetime.datetime(2011, 1, 1, tzinfo=UTC)],
+                    transform=lambda d: d)
+        with timezone.override(UTC):
+            self.assertQuerysetEqual(Event.objects.dates('dt', 'year'),
+                    [datetime.datetime(2010, 1, 1, tzinfo=UTC),
+                    datetime.datetime(2011, 1, 1, tzinfo=UTC)],
+                    transform=lambda d: d)
+            self.assertQuerysetEqual(Event.objects.dates('dt', 'month'),
+                    [datetime.datetime(2010, 12, 1, tzinfo=UTC),
+                    datetime.datetime(2011, 1, 1, tzinfo=UTC)],
+                    transform=lambda d: d)
+            self.assertQuerysetEqual(Event.objects.dates('dt', 'day'),
+                    [datetime.datetime(2010, 12, 31, tzinfo=UTC),
+                    datetime.datetime(2011, 1, 1, tzinfo=UTC)],
+                    transform=lambda d: d)
 
     def test_raw_sql(self):
         # Regression test for #17755
