Working with Dates and Times
Real-world datasets are full of dates and times — order timestamps, log entries, sensor readings — and pandas has first-class support for them built on NumPy's datetime64 dtype and its own Timestamp and Timedelta objects. Getting date columns into the right dtype unlocks a large toolkit: component extraction (year, month, weekday), date arithmetic, filtering by date range, and resampling. Treating dates as plain strings instead of a proper datetime dtype disables nearly all of this functionality and is one of the most common early mistakes when working with temporal data in pandas.
Cricket analogy: Match timestamps, toss times, and rain-delay logs need proper datetime handling in pandas, since treating 'March 15 2026' as plain text disables date-range filtering for questions like 'all matches played in the IPL playoffs window'.
Parsing strings into datetime64
pd.to_datetime() converts strings, lists, or entire columns into pandas Timestamp objects backed by the datetime64[ns] dtype. It can infer common formats automatically, or you can supply an explicit format string (e.g. '%Y-%m-%d') for speed and to avoid ambiguity between formats like day-first and month-first dates. When reading data with pd.read_csv, passing parse_dates=['column_name'] parses date columns at load time rather than requiring a separate conversion step afterward.
Cricket analogy: pd.to_datetime() converts match date strings like '15-03-2026' into proper Timestamp objects, and supplying an explicit format avoids the day-first versus month-first ambiguity that plagues international fixture lists.
import pandas as pd
logs = pd.DataFrame({
'event': ['login', 'purchase', 'logout'],
'ts': ['2026-03-01 08:15:00', '2026-03-01 08:42:10', '2026-03-01 09:03:55']
})
logs['ts'] = pd.to_datetime(logs['ts'])
print(logs.dtypes['ts']) # datetime64[ns]
print(logs['ts'].iloc[0]) # Timestamp('2026-03-01 08:15:00')The .dt accessor: extracting components
Once a Series has a datetime64 dtype, the .dt accessor exposes attributes and methods analogous to Python's datetime module: .dt.year, .dt.month, .dt.day, .dt.hour, .dt.dayofweek, .dt.day_name(), .dt.is_month_end, and more. These are vectorized, so extracting a weekday name from a million-row column is fast. .dt.floor, .dt.ceil, and .dt.round let you snap timestamps to a coarser granularity (e.g. rounding down to the nearest hour), which is often a preprocessing step before grouping or resampling.
Cricket analogy: Once a match-date column is datetime64, .dt.day_name() instantly extracts whether a Test was played on a Saturday, and .dt.floor can round toss times down to the nearest hour before grouping by session.
import pandas as pd
logs['ts'] = pd.to_datetime(logs['ts'])
logs['hour'] = logs['ts'].dt.hour
logs['weekday'] = logs['ts'].dt.day_name()
print(logs[['event', 'hour', 'weekday']])
# event hour weekday
# 0 login 8 Sunday
# 1 purchase 8 Sunday
# 2 logout 9 SundayTimedelta arithmetic and date offsets
Subtracting two Timestamp columns produces a Timedelta, representing an elapsed duration, which itself supports .dt accessor attributes like .dt.days and .dt.seconds. Adding a Timedelta (or a pandas DateOffset, like pd.DateOffset(months=1) or pd.offsets.BusinessDay(5)) to a Timestamp shifts it forward or backward in time. DateOffset objects are calendar-aware — adding one month correctly lands on the same day next month (or the closest valid day), unlike naively adding a fixed number of days.
Cricket analogy: Subtracting a match's start Timestamp from its end Timestamp yields a Timedelta of elapsed play, and adding pd.offsets.BusinessDay(5) to a series finale date correctly schedules the next fixture on a valid playing day.
pandas Timestamps carry nanosecond precision by default and can be timezone-aware. tz_localize assigns a timezone to naive timestamps, while tz_convert converts an already timezone-aware Series to a different timezone — mixing naive and aware timestamps in the same operation raises an error, which is a deliberate safeguard against silent timezone bugs.
Adding a fixed number of days (e.g. Timedelta(days=30)) to approximate 'one month later' is inaccurate because months vary in length; use pd.DateOffset(months=1) when calendar-correct month or year arithmetic is required.
- pd.to_datetime() converts strings or columns into the datetime64[ns] dtype backing pandas Timestamp objects.
- parse_dates in read_csv parses date columns automatically at load time.
- The .dt accessor exposes vectorized date/time component extraction (.dt.year, .dt.day_name(), .dt.hour, etc.).
- Subtracting two Timestamps yields a Timedelta representing elapsed duration.
- pd.DateOffset provides calendar-aware arithmetic (e.g., adding a month), unlike fixed-length Timedelta addition.
- tz_localize and tz_convert manage timezone assignment and conversion, and pandas prevents mixing naive with timezone-aware timestamps.
Practice what you learned
1. What is the effect of calling pd.to_datetime() on a column of date strings?
2. What does subtracting one datetime64 Series from another produce?
3. Why is pd.DateOffset(months=1) generally preferred over pd.Timedelta(days=30) for 'one month later' calculations?
4. Which parameter of pd.read_csv parses specified columns as datetime64 directly during file loading?
5. What happens if you try to compare or combine a timezone-naive Timestamp with a timezone-aware Timestamp in pandas?
Was this page helpful?
You May Also Like
Time Series Basics
Learn pandas' Timestamp, DatetimeIndex, and date_range tools that form the foundation for working with time-indexed data.
Resampling and Rolling Windows
Master resample() for changing time-series frequency and rolling()/expanding() for moving-window calculations like moving averages.
Data Type Conversion
Master how to inspect and convert pandas column dtypes with astype, to_numeric, to_datetime, and category types to fix incorrect or inefficient typing.
Reading and Writing Data
Learn pandas' file I/O functions — read_csv, read_excel, read_json, to_csv, and to_parquet — plus the key parameters that control parsing, dtypes, and output format.