Skip to content

Datetime Accessor (dt)

The dt accessor in pandas provides vectorized datetime operations on Series containing datetime values. This allows you to extract date components, perform datetime arithmetic, and format dates without explicit loops.

Overview

import pandas as pd

dates = pd.Series(pd.date_range('2024-01-01', periods=5))

# Access datetime methods via .dt accessor
print(dates.dt.year)
0    2024
1    2024
2    2024
3    2024
4    2024
dtype: int32

Prerequisites

The dt accessor requires datetime-like data. Convert strings to datetime first:

# String column
s = pd.Series(['2024-01-01', '2024-01-02', '2024-01-03'])
print(s.dtype)  # object

# Convert to datetime
s = pd.to_datetime(s)
print(s.dtype)  # datetime64[ns]

# Now dt accessor works
print(s.dt.day)  # 1, 2, 3

Extracting Date Components

Year, Month, Day

dates = pd.Series(pd.date_range('2024-03-15', periods=3))

print(dates.dt.year)   # 2024, 2024, 2024
print(dates.dt.month)  # 3, 3, 3
print(dates.dt.day)    # 15, 16, 17

Quarter and Week

dates = pd.Series(pd.to_datetime(['2024-01-15', '2024-04-15', '2024-07-15', '2024-10-15']))

print(dates.dt.quarter)      # 1, 2, 3, 4
print(dates.dt.isocalendar().week)  # ISO week number

Day of Week

dates = pd.Series(pd.date_range('2024-01-01', periods=7))

print(dates.dt.dayofweek)    # 0=Monday, 6=Sunday
print(dates.dt.day_name())   # Monday, Tuesday, ...
print(dates.dt.weekday)      # Same as dayofweek

Day of Year

dates = pd.Series(pd.to_datetime(['2024-01-01', '2024-06-15', '2024-12-31']))
print(dates.dt.dayofyear)  # 1, 167, 366

Extracting Time Components

Hour, Minute, Second

times = pd.Series(pd.to_datetime(['2024-01-01 09:30:45', '2024-01-01 14:15:30']))

print(times.dt.hour)        # 9, 14
print(times.dt.minute)      # 30, 15
print(times.dt.second)      # 45, 30
print(times.dt.microsecond) # 0, 0
print(times.dt.nanosecond)  # 0, 0

Time Component

Extract just the time portion:

times = pd.Series(pd.to_datetime(['2024-01-01 09:30:45', '2024-01-01 14:15:30']))
print(times.dt.time)
0    09:30:45
1    14:15:30
dtype: object

Date Component

Extract just the date portion:

print(times.dt.date)
0    2024-01-01
1    2024-01-01
dtype: object

Boolean Properties

Checking Date Characteristics

dates = pd.Series(pd.to_datetime([
    '2024-01-01', '2024-01-31', '2024-02-29', '2024-12-31'
]))

print(dates.dt.is_month_start)  # True, False, False, False
print(dates.dt.is_month_end)    # False, True, False, True
print(dates.dt.is_quarter_start) # True, False, False, False
print(dates.dt.is_quarter_end)   # False, False, False, True
print(dates.dt.is_year_start)    # True, False, False, False
print(dates.dt.is_year_end)      # False, False, False, True
print(dates.dt.is_leap_year)     # True, True, True, True (2024 is leap year)

Formatting Dates

strftime()

Format datetime to string using format codes.

dates = pd.Series(pd.date_range('2024-01-15', periods=3))

# Various formats
print(dates.dt.strftime('%Y-%m-%d'))    # 2024-01-15, 2024-01-16, ...
print(dates.dt.strftime('%d/%m/%Y'))    # 15/01/2024, 16/01/2024, ...
print(dates.dt.strftime('%B %d, %Y'))   # January 15, 2024, ...
print(dates.dt.strftime('%A'))          # Monday, Tuesday, ...

Common Format Codes

Code Meaning Example
%Y Year (4-digit) 2024
%y Year (2-digit) 24
%m Month (zero-padded) 01-12
%B Month name (full) January
%b Month name (abbr) Jan
%d Day (zero-padded) 01-31
%H Hour (24-hour) 00-23
%I Hour (12-hour) 01-12
%M Minute 00-59
%S Second 00-59
%A Weekday (full) Monday
%a Weekday (abbr) Mon
%p AM/PM AM, PM

Rounding Operations

floor(), ceil(), round()

times = pd.Series(pd.to_datetime([
    '2024-01-15 09:37:45',
    '2024-01-15 14:22:30'
]))

# Round to nearest hour
print(times.dt.round('H'))
# 2024-01-15 10:00:00, 2024-01-15 14:00:00

# Floor to hour
print(times.dt.floor('H'))
# 2024-01-15 09:00:00, 2024-01-15 14:00:00

# Ceil to hour
print(times.dt.ceil('H'))
# 2024-01-15 10:00:00, 2024-01-15 15:00:00

Common Frequency Strings

String Meaning
'D' Day
'H' Hour
'T' or 'min' Minute
'S' Second
'W' Week
'M' Month end
'MS' Month start
'Q' Quarter end

Timezone Operations

tz_localize()

Assign timezone to naive datetime.

dates = pd.Series(pd.date_range('2024-01-15', periods=3))

# Localize to UTC
dates_utc = dates.dt.tz_localize('UTC')
print(dates_utc)

tz_convert()

Convert between timezones.

dates_utc = pd.Series(pd.date_range('2024-01-15', periods=3, tz='UTC'))

# Convert to US Eastern
dates_eastern = dates_utc.dt.tz_convert('US/Eastern')
print(dates_eastern)

tz

Access timezone information.

dates = pd.Series(pd.date_range('2024-01-15', periods=3, tz='US/Eastern'))
print(dates.dt.tz)  # US/Eastern

Normalization

normalize()

Set time component to midnight.

times = pd.Series(pd.to_datetime([
    '2024-01-15 09:30:00',
    '2024-01-15 14:45:00'
]))

print(times.dt.normalize())
# 2024-01-15, 2024-01-15 (at midnight)

Practical Examples

Filtering by Date Components

# Create sample data
df = pd.DataFrame({
    'date': pd.date_range('2024-01-01', periods=100, freq='D'),
    'sales': range(100)
})

# Filter weekends
weekends = df[df['date'].dt.dayofweek >= 5]
print(f"Weekend days: {len(weekends)}")

# Filter specific month
january = df[df['date'].dt.month == 1]

# Filter Q1
q1 = df[df['date'].dt.quarter == 1]

Grouping by Time Period

# Daily sales data
df = pd.DataFrame({
    'date': pd.date_range('2024-01-01', periods=365, freq='D'),
    'sales': range(365)
})

# Monthly totals
monthly = df.groupby(df['date'].dt.month)['sales'].sum()

# Day of week analysis
dow_avg = df.groupby(df['date'].dt.dayofweek)['sales'].mean()
dow_avg.index = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
print(dow_avg)

Financial Example: Trading Days

import pandas as pd
import numpy as np

# Stock price data
dates = pd.bdate_range('2024-01-01', '2024-03-31')  # Business days only
prices = pd.DataFrame({
    'date': dates,
    'close': 100 + np.cumsum(np.random.randn(len(dates)))
})

# Extract date features
prices['year'] = prices['date'].dt.year
prices['month'] = prices['date'].dt.month
prices['day_name'] = prices['date'].dt.day_name()
prices['is_month_end'] = prices['date'].dt.is_month_end

# Month-end prices
month_end_prices = prices[prices['is_month_end']]
print(month_end_prices[['date', 'close']])

Creating Date Features for Analysis

df = pd.DataFrame({
    'transaction_date': pd.date_range('2023-01-01', periods=1000, freq='H')
})

# Extract multiple features at once
df['year'] = df['transaction_date'].dt.year
df['month'] = df['transaction_date'].dt.month
df['day'] = df['transaction_date'].dt.day
df['hour'] = df['transaction_date'].dt.hour
df['dayofweek'] = df['transaction_date'].dt.dayofweek
df['is_weekend'] = df['transaction_date'].dt.dayofweek >= 5
df['quarter'] = df['transaction_date'].dt.quarter

print(df.head(10))

Timedelta Operations

For TimedeltaIndex or timedelta64 dtype, similar accessor methods are available:

# Calculate time differences
df = pd.DataFrame({
    'start': pd.to_datetime(['2024-01-01 09:00', '2024-01-02 10:30']),
    'end': pd.to_datetime(['2024-01-01 17:30', '2024-01-02 18:00'])
})

df['duration'] = df['end'] - df['start']

# Access timedelta components
print(df['duration'].dt.total_seconds())  # Total seconds
print(df['duration'].dt.components)       # Days, hours, minutes, etc.

Summary of Key Properties

Property Returns Example
dt.year Year 2024
dt.month Month (1-12) 1
dt.day Day (1-31) 15
dt.hour Hour (0-23) 14
dt.minute Minute (0-59) 30
dt.second Second (0-59) 45
dt.dayofweek Day of week (0=Mon) 0
dt.dayofyear Day of year (1-366) 15
dt.quarter Quarter (1-4) 1
dt.is_month_end Boolean True/False
dt.date Date only 2024-01-15
dt.time Time only 14:30:45