Skip to content
15 changes: 15 additions & 0 deletions pygmt/alias.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,21 @@ def _to_string(

>>> _to_string([[1, 2], [3, 4]], sep="/", ndim=2)
['1/2', '3/4']

>>> import datetime
>>> import numpy as np
>>> import pandas as pd
>>> import xarray as xr
>>> _to_string(
... [
... datetime.date(2010, 1, 1),
... datetime.datetime(2010, 3, 1),
... pd.Timestamp("2015-01-01T12:00:00.123456789"),
... xr.DataArray(data=np.datetime64("2005-01-01T08:00:00", "ns")),
... ],
... sep="/",
... )
'2010-01-01/2010-03-01T00:00:00.000000/2015-01-01T12:00:00.123456/2005-01-01T08:00:00.000000000'
"""
# None and False are converted to None.
if value is None or value is False:
Expand Down
34 changes: 34 additions & 0 deletions pygmt/helpers/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from pathlib import Path
from typing import Any, Literal

import numpy as np
import xarray as xr
from pygmt._typing import PathLike
from pygmt.encodings import charset
Expand Down Expand Up @@ -816,6 +817,30 @@ def sequence_join(
['1/2', '3/4']
>>> sequence_join([1, 2, 3, 4], separator=",")
'1,2,3,4'

>>> # Join a sequence of datetime-like objects into a string.
>>> import datetime
>>> import numpy as np
>>> import pandas as pd
>>> import xarray as xr
>>> sequence_join(
... [
... datetime.date(2010, 1, 1),
... np.datetime64("2010-01-01T16:00:00"),
... np.array("2010-03-01T00:00:00", dtype=np.datetime64),
... ],
... sep="/",
... )
'2010-01-01/2010-01-01T16:00:00/2010-03-01T00:00:00'
>>> sequence_join(
... [
... datetime.datetime(2010, 3, 1),
... pd.Timestamp("2015-01-01T12:00:00.123456789"),
... xr.DataArray(data=np.datetime64("2005-01-01T08:00:00", "ns")),
... ],
... sep="/",
... )
'2010-03-01T00:00:00.000000/2015-01-01T12:00:00.123456/2005-01-01T08:00:00.000000000'
"""
# Return the original value if it is not a sequence (e.g., None, bool, or str).
if not is_nonstr_iter(value):
Expand Down Expand Up @@ -848,6 +873,15 @@ def sequence_join(
f"but got {len(value)} values."
)
raise GMTInvalidInput(msg)
# 'str(v)' produces a string like '2024-01-01 00:00:00' for some datetime-like
# objects (e.g., datetime.datetime, pandas.Timestamp), which contains a space.
# If so, use np.datetime_as_string to convert it to ISO 8601 string format
# YYYY-MM-DDThh:mm:ss.ffffff.
for idx, item in enumerate(value):
if " " in str(item):
Copy link

Copilot AI Sep 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using ' ' in str(item) as a heuristic to detect datetime objects is fragile and could produce false positives for non-datetime objects that happen to contain spaces in their string representation. Consider using isinstance checks or hasattr to detect datetime-like objects more reliably.

Copilot uses AI. Check for mistakes.
value[idx] = np.datetime_as_string(
np.asarray(item, dtype=np.datetime64)
)
return sep.join(str(v) for v in value)

# Now it must be a 2-D sequence.
Expand Down
Loading