diff --git a/swh/model/identifiers.py b/swh/model/identifiers.py
index d542178f340385403da75e4510d71994b69ebb72..04bd407807e1dfa1c171c485fee94349d9113780 100644
--- a/swh/model/identifiers.py
+++ b/swh/model/identifiers.py
@@ -360,8 +360,10 @@ def normalize_timestamp(time_representation):
         if negative_utc is None:
             negative_utc = False
     elif isinstance(time_representation, datetime.datetime):
-        seconds = int(time_representation.timestamp())
         microseconds = time_representation.microsecond
+        if microseconds:
+            time_representation = time_representation.replace(microsecond=0)
+        seconds = int(time_representation.timestamp())
         utcoffset = time_representation.utcoffset()
         if utcoffset is None:
             raise ValueError(
diff --git a/swh/model/tests/test_identifiers.py b/swh/model/tests/test_identifiers.py
index 682a3ef2a6fc654247304c98e7dcae8b4694c135..7a236ac9036f47a27deb79411d630983bf1b48af 100644
--- a/swh/model/tests/test_identifiers.py
+++ b/swh/model/tests/test_identifiers.py
@@ -1172,6 +1172,35 @@ def test_normalize_timestamp_dict_invalid_timestamp(dict_input):
         normalize_timestamp(dict_input)
 
 
+UTC = datetime.timezone.utc
+TS_TIMEZONES = [
+    datetime.timezone.min,
+    datetime.timezone(datetime.timedelta(hours=-1)),
+    UTC,
+    datetime.timezone(datetime.timedelta(minutes=+60)),
+    datetime.timezone.max,
+]
+TS_TZ_EXPECTED = [-1439, -60, 0, 60, 1439]
+TS_DATETIMES = [
+    datetime.datetime(2020, 2, 27, 14, 39, 19, tzinfo=UTC),
+    datetime.datetime(2120, 12, 31, 23, 59, 59, tzinfo=UTC),
+    datetime.datetime(1610, 5, 14, 15, 43, 0, tzinfo=UTC),
+]
+TS_DT_EXPECTED = [1582814359, 4765132799, -11348929020]
+
+
+@pytest.mark.parametrize("date, seconds", zip(TS_DATETIMES, TS_DT_EXPECTED))
+@pytest.mark.parametrize("tz, offset", zip(TS_TIMEZONES, TS_TZ_EXPECTED))
+@pytest.mark.parametrize("microsecond", [0, 1, 10, 100, 1000, 999999])
+def test_normalize_timestamp_datetime(date, seconds, tz, offset, microsecond):
+    date = date.astimezone(tz).replace(microsecond=microsecond)
+    assert normalize_timestamp(date) == {
+        "timestamp": {"seconds": seconds, "microseconds": microsecond},
+        "offset": offset,
+        "negative_utc": False,
+    }
+
+
 # SWHIDs that are outright invalid, no matter the context
 INVALID_SWHIDS = [
     "swh:1:cnt",