diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 140557426a3..885d2ce5829 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -6,6 +6,9 @@ * `SACTrace.lpspol` and `lcalda` are `True` and `False` by default, when created via `SACTrace.from_obspy_trace` with a `Trace` that has no SAC inheritance. (see #1507) + - obspy.io.stationxml: + * Datetime fields are written with microseconds to StationXML if + microseconds are present. (see #1511) 1.0.2: (doi: 10.5281/zenodo.49636) - obspy.core: diff --git a/obspy/io/stationxml/core.py b/obspy/io/stationxml/core.py index 393bf08b167..135dff1a754 100644 --- a/obspy/io/stationxml/core.py +++ b/obspy/io/stationxml/core.py @@ -1328,7 +1328,10 @@ def _obj2tag(parent, tag_name, tag_value): def _format_time(value): - return value.strftime("%Y-%m-%dT%H:%M:%S+00:00") + if value.microsecond == 0: + return value.strftime("%Y-%m-%dT%H:%M:%S+00:00") + else: + return value.strftime("%Y-%m-%dT%H:%M:%S.%f+00:00") # Remove once 0.11 has been released. diff --git a/obspy/io/stationxml/tests/data/minimal_station_with_microseconds.xml b/obspy/io/stationxml/tests/data/minimal_station_with_microseconds.xml new file mode 100644 index 00000000000..ab0e23f5496 --- /dev/null +++ b/obspy/io/stationxml/tests/data/minimal_station_with_microseconds.xml @@ -0,0 +1,8 @@ + + + OBS + + + 2013-01-01T00:00:00.123456+00:00 + + diff --git a/obspy/io/stationxml/tests/test_stationxml.py b/obspy/io/stationxml/tests/test_stationxml.py index 291805e8f32..3223bb77277 100644 --- a/obspy/io/stationxml/tests/test_stationxml.py +++ b/obspy/io/stationxml/tests/test_stationxml.py @@ -22,6 +22,7 @@ import obspy from obspy.core.inventory import Inventory, Network +import obspy.io.stationxml.core class StationXMLTestCase(unittest.TestCase): @@ -114,6 +115,31 @@ def test_read_and_write_minimal_file(self): self._assert_station_xml_equality(file_buffer, expected_xml_file_buffer) + def test_subsecond_read_and_write_minimal_file(self): + """ + Test reading and writing of sub-second time in datetime field, + using creation time + + """ + filename = os.path.join(self.data_dir, + "minimal_station_with_microseconds.xml") + inv = obspy.read_inventory(filename) + + # Write it again. Also validate it to get more confidence. Suppress the + # writing of the ObsPy related tags to ease testing. + file_buffer = io.BytesIO() + + inv.write(file_buffer, format="StationXML", + _suppress_module_tags=True) + file_buffer.seek(0, 0) + + with open(filename, "rb") as open_file: + expected_xml_file_buffer = io.BytesIO(open_file.read()) + expected_xml_file_buffer.seek(0, 0) + + self._assert_station_xml_equality(file_buffer, + expected_xml_file_buffer) + def test_read_and_write_full_file(self): """ Test that reading and writing of a full StationXML document with all @@ -126,20 +152,10 @@ def test_read_and_write_full_file(self): # writing of the ObsPy related tags to ease testing. file_buffer = io.BytesIO() - # XXX helper variable to debug writing the full random file, set True - # XXX for debug output - write_debug_output = False - inv.write(file_buffer, format="StationXML", - validate=(not write_debug_output), _suppress_module_tags=True) file_buffer.seek(0, 0) - if write_debug_output: - with open("/tmp/debugout.xml", "wb") as open_file: - open_file.write(file_buffer.read()) - file_buffer.seek(0, 0) - with open(filename, "rb") as open_file: expected_xml_file_buffer = io.BytesIO(open_file.read()) expected_xml_file_buffer.seek(0, 0)