diff --git a/swift/obj/server.py b/swift/obj/server.py
index a5f90ef49c..b22b8221f8 100644
--- a/swift/obj/server.py
+++ b/swift/obj/server.py
@@ -21,6 +21,7 @@ import multiprocessing
 import time
 import traceback
 import socket
+import math
 from datetime import datetime
 from swift import gettext_ as _
 from hashlib import md5
@@ -492,7 +493,7 @@ class ObjectController(object):
                 except (OverflowError, ValueError):
                     # catches timestamps before the epoch
                     return HTTPPreconditionFailed(request=request)
-                if if_modified_since and file_x_ts_utc < if_modified_since:
+                if if_modified_since and file_x_ts_utc <= if_modified_since:
                     return HTTPNotModified(request=request)
                 keep_cache = (self.keep_cache_private or
                               ('X-Auth-Token' not in request.headers and
@@ -507,7 +508,7 @@ class ObjectController(object):
                             key.lower() in self.allowed_headers:
                         response.headers[key] = value
                 response.etag = metadata['ETag']
-                response.last_modified = file_x_ts_flt
+                response.last_modified = math.ceil(file_x_ts_flt)
                 response.content_length = obj_size
                 try:
                     response.content_encoding = metadata[
@@ -549,7 +550,7 @@ class ObjectController(object):
                 response.headers[key] = value
         response.etag = metadata['ETag']
         ts = metadata['X-Timestamp']
-        response.last_modified = float(ts)
+        response.last_modified = math.ceil(float(ts))
         # Needed for container sync feature
         response.headers['X-Timestamp'] = ts
         response.content_length = int(metadata['Content-Length'])
diff --git a/swift/proxy/controllers/obj.py b/swift/proxy/controllers/obj.py
index b230269e48..189e909756 100644
--- a/swift/proxy/controllers/obj.py
+++ b/swift/proxy/controllers/obj.py
@@ -28,6 +28,7 @@ import itertools
 import mimetypes
 import re
 import time
+import math
 from datetime import datetime
 from swift import gettext_ as _
 from urllib import unquote, quote
@@ -1164,7 +1165,7 @@ class ObjectController(Controller):
                 resp.headers['X-Copied-From-Last-Modified'] = \
                     source_resp.headers['last-modified']
             copy_headers_into(req, resp)
-        resp.last_modified = float(req.headers['X-Timestamp'])
+        resp.last_modified = math.ceil(float(req.headers['X-Timestamp']))
         return resp
 
     @public
diff --git a/test/functional/swift_test_client.py b/test/functional/swift_test_client.py
index 67d4472302..3ae4abdbf5 100644
--- a/test/functional/swift_test_client.py
+++ b/test/functional/swift_test_client.py
@@ -723,7 +723,8 @@ class File(Base):
         else:
             raise RuntimeError
 
-    def write(self, data='', hdrs={}, parms={}, callback=None, cfg={}):
+    def write(self, data='', hdrs={}, parms={}, callback=None, cfg={},
+              return_resp=False):
         block_size = 2 ** 20
 
         if isinstance(data, file):
@@ -767,6 +768,9 @@ class File(Base):
             pass
         self.md5 = self.compute_md5sum(data)
 
+        if return_resp:
+            return self.conn.response
+
         return True
 
     def write_random(self, size=None, hdrs={}, parms={}, cfg={}):
@@ -776,3 +780,12 @@ class File(Base):
                                 self.conn.make_path(self.path))
         self.md5 = self.compute_md5sum(StringIO.StringIO(data))
         return data
+
+    def write_random_return_resp(self, size=None, hdrs={}, parms={}, cfg={}):
+        data = self.random_data(size)
+        resp = self.write(data, hdrs=hdrs, parms=parms, cfg=cfg,
+                          return_resp=True)
+        if not resp:
+            raise ResponseError(self.conn.response)
+        self.md5 = self.compute_md5sum(StringIO.StringIO(data))
+        return resp
diff --git a/test/functional/tests.py b/test/functional/tests.py
index d1c626e12d..3a8a02f512 100644
--- a/test/functional/tests.py
+++ b/test/functional/tests.py
@@ -1732,6 +1732,28 @@ class TestFileComparison(Base):
             self.assertRaises(ResponseError, file_item.read, hdrs=hdrs)
             self.assert_status(412)
 
+    def testLastModified(self):
+        file_name = Utils.create_name()
+        content_type = Utils.create_name()
+
+        file = self.env.container.file(file_name)
+        file.content_type = content_type
+        resp = file.write_random_return_resp(self.env.file_size)
+        put_last_modified = resp.getheader('last-modified')
+
+        file = self.env.container.file(file_name)
+        info = file.info()
+        self.assert_('last_modified' in info)
+        last_modified = info['last_modified']
+        self.assertEqual(put_last_modified, info['last_modified'])
+
+        hdrs = {'If-Modified-Since': last_modified}
+        self.assertRaises(ResponseError, file.read, hdrs=hdrs)
+        self.assert_status(304)
+
+        hdrs = {'If-Unmodified-Since': last_modified}
+        self.assert_(file.read(hdrs=hdrs))
+
 
 class TestFileComparisonUTF8(Base2, TestFileComparison):
     set_up = False
diff --git a/test/unit/obj/test_server.py b/test/unit/obj/test_server.py
index fb25f12abb..fd6c11e201 100755
--- a/test/unit/obj/test_server.py
+++ b/test/unit/obj/test_server.py
@@ -21,6 +21,7 @@ import operator
 import os
 import mock
 import unittest
+import math
 from shutil import rmtree
 from StringIO import StringIO
 from time import gmtime, strftime, time
@@ -739,7 +740,8 @@ class TestObjectController(unittest.TestCase):
         self.assertEquals(resp.headers['content-type'], 'application/x-test')
         self.assertEquals(
             resp.headers['last-modified'],
-            strftime('%a, %d %b %Y %H:%M:%S GMT', gmtime(float(timestamp))))
+            strftime('%a, %d %b %Y %H:%M:%S GMT',
+                     gmtime(math.ceil(float(timestamp)))))
         self.assertEquals(resp.headers['etag'],
                           '"0b4c12d7e0a73840c1c4f148fda3b037"')
         self.assertEquals(resp.headers['x-object-meta-1'], 'One')
@@ -841,7 +843,8 @@ class TestObjectController(unittest.TestCase):
         self.assertEquals(resp.headers['content-type'], 'application/x-test')
         self.assertEquals(
             resp.headers['last-modified'],
-            strftime('%a, %d %b %Y %H:%M:%S GMT', gmtime(float(timestamp))))
+            strftime('%a, %d %b %Y %H:%M:%S GMT',
+                     gmtime(math.ceil(float(timestamp)))))
         self.assertEquals(resp.headers['etag'],
                           '"0b4c12d7e0a73840c1c4f148fda3b037"')
         self.assertEquals(resp.headers['x-object-meta-1'], 'One')
@@ -1043,6 +1046,37 @@ class TestObjectController(unittest.TestCase):
         resp = req.get_response(self.object_controller)
         self.assertEquals(resp.status_int, 304)
 
+        req = Request.blank('/sda1/p/a/c/o',
+                            environ={'REQUEST_METHOD': 'HEAD'})
+        resp = req.get_response(self.object_controller)
+        since = resp.headers['Last-Modified']
+        self.assertEquals(since, strftime('%a, %d %b %Y %H:%M:%S GMT',
+                                          gmtime(math.ceil(float(timestamp)))))
+
+        req = Request.blank('/sda1/p/a/c/o', environ={'REQUEST_METHOD': 'GET'},
+                            headers={'If-Modified-Since': since})
+        resp = self.object_controller.GET(req)
+        self.assertEquals(resp.status_int, 304)
+
+        timestamp = normalize_timestamp(int(time()))
+        req = Request.blank('/sda1/p/a/c/o2',
+                            environ={'REQUEST_METHOD': 'PUT'},
+                            headers={
+                                'X-Timestamp': timestamp,
+                                'Content-Type': 'application/octet-stream',
+                                'Content-Length': '4'})
+        req.body = 'test'
+        resp = req.get_response(self.object_controller)
+        self.assertEquals(resp.status_int, 201)
+
+        since = strftime('%a, %d %b %Y %H:%M:%S GMT',
+                         gmtime(float(timestamp)))
+        req = Request.blank('/sda1/p/a/c/o2',
+                            environ={'REQUEST_METHOD': 'GET'},
+                            headers={'If-Modified-Since': since})
+        resp = req.get_response(self.object_controller)
+        self.assertEquals(resp.status_int, 304)
+
     def test_GET_if_unmodified_since(self):
         timestamp = normalize_timestamp(time())
         req = Request.blank('/sda1/p/a/c/o', environ={'REQUEST_METHOD': 'PUT'},
@@ -1079,6 +1113,18 @@ class TestObjectController(unittest.TestCase):
         resp = req.get_response(self.object_controller)
         self.assertEquals(resp.status_int, 200)
 
+        req = Request.blank('/sda1/p/a/c/o',
+                            environ={'REQUEST_METHOD': 'HEAD'})
+        resp = req.get_response(self.object_controller)
+        since = resp.headers['Last-Modified']
+        self.assertEquals(since, strftime('%a, %d %b %Y %H:%M:%S GMT',
+                                          gmtime(math.ceil(float(timestamp)))))
+
+        req = Request.blank('/sda1/p/a/c/o', environ={'REQUEST_METHOD': 'GET'},
+                            headers={'If-Unmodified-Since': since})
+        resp = self.object_controller.GET(req)
+        self.assertEquals(resp.status_int, 200)
+
     def test_GET_quarantine(self):
         # Test swift.obj.server.ObjectController.GET
         timestamp = normalize_timestamp(time())
diff --git a/test/unit/proxy/test_server.py b/test/unit/proxy/test_server.py
index 7b00c56a60..8803e4a797 100644
--- a/test/unit/proxy/test_server.py
+++ b/test/unit/proxy/test_server.py
@@ -1036,6 +1036,56 @@ class TestObjectController(unittest.TestCase):
         finally:
             swift.proxy.controllers.obj.MAX_FILE_SIZE = MAX_FILE_SIZE
 
+    def test_PUT_last_modified(self):
+        prolis = _test_sockets[0]
+        sock = connect_tcp(('localhost', prolis.getsockname()[1]))
+        fd = sock.makefile()
+        fd.write('PUT /v1/a/c/o.last_modified HTTP/1.1\r\n'
+                 'Host: localhost\r\nConnection: close\r\n'
+                 'X-Storage-Token: t\r\nContent-Length: 0\r\n\r\n')
+        fd.flush()
+        headers = readuntil2crlfs(fd)
+        exp = 'HTTP/1.1 201'
+        lm_hdr = 'Last-Modified: '
+        self.assertEqual(headers[:len(exp)], exp)
+
+        last_modified_put = [line for line in headers.split('\r\n')
+                             if lm_hdr in line][0][len(lm_hdr):]
+        sock = connect_tcp(('localhost', prolis.getsockname()[1]))
+        fd = sock.makefile()
+        fd.write('HEAD /v1/a/c/o.last_modified HTTP/1.1\r\n'
+                 'Host: localhost\r\nConnection: close\r\n'
+                 'X-Storage-Token: t\r\n\r\n')
+        fd.flush()
+        headers = readuntil2crlfs(fd)
+        exp = 'HTTP/1.1 200'
+        self.assertEqual(headers[:len(exp)], exp)
+        last_modified_head = [line for line in headers.split('\r\n')
+                              if lm_hdr in line][0][len(lm_hdr):]
+        self.assertEqual(last_modified_put, last_modified_head)
+
+        sock = connect_tcp(('localhost', prolis.getsockname()[1]))
+        fd = sock.makefile()
+        fd.write('GET /v1/a/c/o.last_modified HTTP/1.1\r\n'
+                 'Host: localhost\r\nConnection: close\r\n'
+                 'If-Modified-Since: %s\r\n'
+                 'X-Storage-Token: t\r\n\r\n' % last_modified_put)
+        fd.flush()
+        headers = readuntil2crlfs(fd)
+        exp = 'HTTP/1.1 304'
+        self.assertEqual(headers[:len(exp)], exp)
+
+        sock = connect_tcp(('localhost', prolis.getsockname()[1]))
+        fd = sock.makefile()
+        fd.write('GET /v1/a/c/o.last_modified HTTP/1.1\r\n'
+                 'Host: localhost\r\nConnection: close\r\n'
+                 'If-Unmodified-Since: %s\r\n'
+                 'X-Storage-Token: t\r\n\r\n' % last_modified_put)
+        fd.flush()
+        headers = readuntil2crlfs(fd)
+        exp = 'HTTP/1.1 200'
+        self.assertEqual(headers[:len(exp)], exp)
+
     def test_expirer_DELETE_on_versioned_object(self):
         test_errors = []