diff --git a/geomagio/TimeseriesUtility.py b/geomagio/TimeseriesUtility.py
index c40ba8609576b60bf0bcc68d6af85abec6192a56..418bbe9c17a04b903d83a8906b133eefb37f48ce 100644
--- a/geomagio/TimeseriesUtility.py
+++ b/geomagio/TimeseriesUtility.py
@@ -535,3 +535,28 @@ def pad_and_trim_trace(trace, starttime, endtime):
             trace.data = numpy.concatenate(
                 [trace.data, numpy.full(cnt, numpy.nan, dtype=numpy.float64)]
             )
+
+
+def round_usecs(time):
+    """Rounds residual microseconds to milliseconds.
+
+    Parameters
+    ----------
+    time: UTCDateTime
+        time containing microsecond values
+
+    Returns
+    ----------
+    time: UTCDateTime
+        time containing rounded(or non-rounded) microsecond values
+    """
+    usecs = time.microsecond
+    # round microseconds to nearest millisecond
+    rounded_usecs = int(round(usecs / 1000, 0)) * 1000
+    # reset microseconds to 0 at top of second, add second to input time
+    if rounded_usecs > 999000:
+        rounded_usecs = 0
+        time += 1
+    if rounded_usecs != usecs:
+        time = time.replace(microsecond=rounded_usecs)
+    return time
diff --git a/geomagio/edge/RawInputClient.py b/geomagio/edge/RawInputClient.py
index f50a93cd24ab445216232828e6cbacb740235c0b..e6483c7fa5859990f23cbbf84811a937b172ef76 100644
--- a/geomagio/edge/RawInputClient.py
+++ b/geomagio/edge/RawInputClient.py
@@ -6,6 +6,8 @@ import struct
 import sys
 from datetime import datetime
 from ..TimeseriesFactoryException import TimeseriesFactoryException
+from ..TimeseriesUtility import round_usecs
+import logging
 from obspy.core import UTCDateTime
 from time import sleep
 
@@ -414,7 +416,7 @@ class RawInputClient:
         """
         PARAMETERS
         ----------
-        time: UTCDateTime
+        input_time: UTCDateTime
             time of the first sample
 
         RETURNS
@@ -425,11 +427,20 @@ class RawInputClient:
             secs: int
             usecs: int
         """
+
+        # check for presence of residual microseconds
+        if (time.microsecond / 1000).is_integer() == False:
+            # create warning message when rounding is necessary
+            logging.warning(
+                "residual microsecond values encountered, rounding to nearest millisecond"
+            )
+            # round residual microsecond values
+            time = round_usecs(time)
+
         yr = time.year
         doy = time.datetime.timetuple().tm_yday
         secs = time.hour * 3600 + time.minute * 60 + time.second
         usecs = time.microsecond
-
         return (yr, doy, secs, usecs)
 
     def _open_socket(self):
diff --git a/test/TimeseriesUtility_test.py b/test/TimeseriesUtility_test.py
index 827b0afeced6bc9e7a80c0cb75f48bc3cf98ee34..a664b2e28a718e42e57553ca9c57d29aa02bae15 100644
--- a/test/TimeseriesUtility_test.py
+++ b/test/TimeseriesUtility_test.py
@@ -449,6 +449,22 @@ def test_pad_and_trim_trace_fixfloat():
     )
 
 
+def test_round_usecs():
+    """TimeseriesUtility_test.test_round_usecs()
+    This tests whether microsecond values are rounded or
+    not depending on residual microsecond values
+    """
+    # test case with no residual microseconds
+    time = TimeseriesUtility.round_usecs(UTCDateTime("2020-10-07T00:00:00Z"))
+    assert_equal(time, UTCDateTime("2020-10-07T00:00:00Z"))
+    # test case with residual microseconds
+    time = TimeseriesUtility.round_usecs(UTCDateTime("2020-10-07T00:00:00.995600Z"))
+    assert_equal(time, UTCDateTime("2020-10-07T00:00:00.996000Z"))
+    # test case with rounding to next second
+    time = TimeseriesUtility.round_usecs(UTCDateTime("2020-10-07T00:00:00.9995Z"))
+    assert_equal(time, UTCDateTime("2020-10-07T00:00:01.000Z"))
+
+
 def _create_trace(data, channel, starttime, delta=60.0):
     stats = Stats()
     stats.channel = channel
diff --git a/test/edge_test/RawInputClient_test.py b/test/edge_test/RawInputClient_test.py
index 850f1a7dfff04cc18d0dc45ffc860d334ba36bd8..ef21290aca7b15bb3784628999673fe8a30431bb 100644
--- a/test/edge_test/RawInputClient_test.py
+++ b/test/edge_test/RawInputClient_test.py
@@ -1,6 +1,8 @@
 """Tests for RawInputClient.py"""
 
 import numpy
+from datetime import datetime
+import logging
 from obspy.core import Stats, Trace, UTCDateTime
 from geomagio.edge import EdgeFactory, RawInputClient
 from numpy.testing import assert_equal
@@ -56,7 +58,7 @@ def test_raw_input_client():
 
 
 def test__get_tag():
-    """edge_test.RawInputClient_test.test_raw_input_client()"""
+    """edge_test.RawInputClient_test.test__get_tag()"""
     network = "NT"
     station = "BOU"
     channel = "MVH"
@@ -72,3 +74,63 @@ def test__get_tag():
     )
     tag_send = client._get_tag()
     assert_equal(tag_send is not None, True)
+
+
+def test__get_time_values(caplog):
+    """edge_test.RawInputClient_test.test__get_time_values()"""
+    network = "NT"
+    station = "BOU"
+    channel = "MVH"
+    location = "R0"
+    client = MockRawInputClient(
+        tag="tag",
+        host="host",
+        port="port",
+        station=station,
+        channel=channel,
+        location=location,
+        network=network,
+    )
+
+    # test rounding up of microsecond value
+    time = UTCDateTime("2020-10-07T00:00:15.196855Z")
+    yr, doy, secs, usecs = client._get_time_values(time)
+    assert_equal(yr, 2020)
+    assert_equal(doy, 281)
+    assert_equal(secs, 15)
+    assert_equal(usecs, 197000)
+    # test rounding down of microsecond value
+    time = UTCDateTime("2020-10-07T00:00:15.196455Z")
+    yr, doy, secs, usecs = client._get_time_values(time)
+    assert_equal(yr, 2020)
+    assert_equal(doy, 281)
+    assert_equal(secs, 15)
+    assert_equal(usecs, 196000)
+    # test top of second adjustment
+    time = UTCDateTime("2020-10-07T00:00:00.999999Z")
+    yr, doy, secs, usecs = client._get_time_values(time)
+    assert_equal(yr, 2020)
+    assert_equal(doy, 281)
+    assert_equal(secs, 1)
+    assert_equal(usecs, 0)
+    # test top of day adjustment
+    time = UTCDateTime("2020-10-07T23:59:59.999999Z")
+    yr, doy, secs, usecs = client._get_time_values(time)
+    assert_equal(yr, 2020)
+    assert_equal(doy, 282)
+    assert_equal(secs, 0)
+    assert_equal(usecs, 0)
+    # assert if previous 4 tests generate 4 warning messages
+    assert_equal(len(caplog.messages), 4)
+
+    # clear warnings from log
+    caplog.clear()
+    # test ideal case
+    time = UTCDateTime("2020-10-07T00:00:00.232000Z")
+    yr, doy, secs, usecs = client._get_time_values(time)
+    assert_equal(yr, 2020)
+    assert_equal(doy, 281)
+    assert_equal(secs, 0)
+    assert_equal(usecs, 232000)
+    # assert if previous test does not generate a warning message
+    assert_equal(len(caplog.messages), 0)