Skip to content

Python Pandas: How to Create Datetime Column from Year, Month, Day (and Time) Columns

Learn how to combine separate year, month, day, and time columns into a single datetime column in Pandas using pd.to_datetime() with dictionary mapping or DataFrame subsets.

Often, date and time components are stored in separate columns in a dataset (e.g., 'Year', 'Month', 'Day', 'Hour', 'Minute', 'Second'). To perform time series analysis or other date-based operations in Pandas, you need to combine these components into a single datetime column. This guide explains how to effectively use pandas.to_datetime() to create a datetime column from separate year, month, day, and optional time component columns in a DataFrame.

The Goal: Assembling Datetime Objects

Given a Pandas DataFrame with separate integer columns for year, month, day (and optionally hour, minute, second), we want to create a new column where each entry is a Pandas datetime64[ns] object representing the combined date and time.

Example DataFrame

import pandas as pd

data = {
    'year_col': [2022, 2023, 2023, 2024, 2022],
    'month_col': [12, 1, 8, 3, 11],
    'day_col': [15, 31, 20, 5, 10],
    'hour_val': [10, 14, 9, 23, 17],
    'minute_val': [30, 0, 15, 59, 45],
    'second_val': [0, 5, 50, 30, 10],
    'Event_Type': ['A', 'B', 'A', 'C', 'B']
}
df_original = pd.DataFrame(data)
print("Original DataFrame:")
print(df_original)

Output:

Original DataFrame:
   year_col  month_col  day_col  hour_val  minute_val  second_val Event_Type
0      2022         12       15        10          30           0          A
1      2023          1       31        14           0           5          B
2      2023          8       20         9          15          50          A
3      2024          3        5        23          59          30          C
4      2022         11       10        17          45          10          B

The pandas.to_datetime(arg, ...) function is versatile. When arg is a dictionary, it expects specific keys like 'year', 'month', 'day', 'hour', 'minute', 'second'. The values for these keys should be Series (or list-like) of the corresponding components.

From Year, Month, Day

import pandas as pd

df = pd.DataFrame({
    'year_col': [2022, 2023, 2023, 2024], 'month_col': [12, 1, 8, 3],
    'day_col': [15, 31, 20, 5], 'Event_Type': ['A', 'B', 'A', 'C']
})

date_components_dict = {
    'year': df['year_col'],
    'month': df['month_col'],
    'day': df['day_col']
}

df['Combined_Date'] = pd.to_datetime(date_components_dict)

print("DataFrame with 'Combined_Date' column (from Y, M, D):")
print(df[['year_col', 'month_col', 'day_col', 'Combined_Date']])

Output:

DataFrame with 'Combined_Date' column (from Y, M, D):
   year_col  month_col  day_col Combined_Date
0      2022         12       15    2022-12-15
1      2023          1       31    2023-01-31
2      2023          8       20    2023-08-20
3      2024          3        5    2024-03-05

From Year, Month, Day, Hour, Minute, Second

Include the time components in the dictionary passed to pd.to_datetime().

import pandas as pd

df = pd.DataFrame({
    'year_col': [2022, 2023], 'month_col': [12, 1], 'day_col': [15, 31],
    'hour_val': [10, 14], 'minute_val': [30, 0], 'second_val': [0, 5],
    'Event_Type': ['A', 'B']
})

datetime_components_dict = {
    'year': df['year_col'],
    'month': df['month_col'],
    'day': df['day_col'],
    'hour': df['hour_val'],
    'minute': df['minute_val'],
    'second': df['second_val']
}

df['Combined_Datetime'] = pd.to_datetime(datetime_components_dict)

print("DataFrame with 'Combined_Datetime' column (from Y, M, D, H, M, S):")
print(df[['Combined_Datetime', 'Event_Type']])

Output:

DataFrame with 'Combined_Datetime' column (from Y, M, D, H, M, S):
    Combined_Datetime Event_Type
0 2022-12-15 10:30:00          A
1 2023-01-31 14:00:05          B

Important Note on Column Names

When passing a dictionary to pd.to_datetime(), the keys of the dictionary must be the standard names: 'year', 'month', 'day', 'hour', 'minute', 'second'. The values associated with these keys are your DataFrame columns (Series).

If your DataFrame columns are already named 'year', 'month', 'day', etc., the dictionary creation is simpler:

df['Combined_Date'] = pd.to_datetime(
    {'year': df.year, 'month': df.month, 'day': df.day}
)

Method 2: Passing a Subset DataFrame to pd.to_datetime()

If your DataFrame columns are already named 'year', 'month', 'day' (and optionally 'hour', 'minute', 'second'), you can pass a subset of your DataFrame containing just these columns directly to pd.to_datetime().

import pandas as pd

df_std_names = pd.DataFrame({
    'year': [2022, 2023],
    'month': [12, 1],
    'day': [15, 31],
    'hour': [10, 14], # Optional time components
    'minute': [30, 0],
    'second': [0, 5],
    'Category': ['X', 'Y']
})
print("DataFrame with standard date component names:")
print(df_std_names)
print()

columns_for_datetime = ['year', 'month', 'day', 'hour', 'minute', 'second']
existing_datetime_cols = [col for col in columns_for_datetime if col in df_std_names.columns]

df_std_names['Assembled_Datetime'] = pd.to_datetime(df_std_names[existing_datetime_cols])

print("DataFrame with assembled datetime from subset:")
print(df_std_names[['Assembled_Datetime', 'Category']])

Output:

DataFrame with standard date component names:
   year  month  day  hour  minute  second Category
0  2022     12   15    10      30       0        X
1  2023      1   31    14       0       5        Y

DataFrame with assembled datetime from subset:
   Assembled_Datetime Category
0 2022-12-15 10:30:00        X
1 2023-01-31 14:00:05        Y

Method 3: Constructing a String and Using format (Less Common for This)

While pd.to_datetime() can parse strings, manually constructing a date string from columns and then parsing it is generally less efficient and more error-prone than the direct dictionary or DataFrame subset methods if your components are already numeric. However, if your components are strings and need to be combined into a parseable date string first:

import pandas as pd

df_str_cols = pd.DataFrame({
    'Y': ['2022', '2023'],
    'M': ['12', '01'], # Month as string
    'D': ['15', '31'], # Day as string
    'Event': ['Q4', 'Q1']
})



df_str_cols_numeric = df_str_cols.copy()
df_str_cols_numeric['Y'] = df_str_cols_numeric['Y'].astype(int)
df_str_cols_numeric['M'] = df_str_cols_numeric['M'].astype(int)
df_str_cols_numeric['D'] = df_str_cols_numeric['D'].astype(int)

df_str_cols_numeric['Combined_Date'] = pd.to_datetime(
    {'year': df_str_cols_numeric.Y, 'month': df_str_cols_numeric.M, 'day': df_str_cols_numeric.D}
)

print("DataFrame from string columns, combined via dictionary method:")
print(df_str_cols_numeric)

The arithmetic approach (df.year*10000+...) only works if the columns are numeric and requires a matching format string. For combining existing numeric year, month, day columns, Method 1 or 2 are superior.

Handling Invalid Dates (errors parameter)

If your year, month, day combinations might result in invalid dates (e.g., February 30th), pd.to_datetime() will raise an error by default. You can use the errors parameter:

  • errors='raise' (default): Raise an exception for invalid dates.
  • errors='coerce': Convert invalid dates to NaT (Not a Time).
  • errors='ignore': Return the input if it cannot be parsed (resulting in mixed types).
import pandas as pd

df_invalid = pd.DataFrame({'year': [2023], 'month': [2], 'day': [30]}) # Feb 30 is invalid

df_invalid['Date_Coerced'] = pd.to_datetime(df_invalid[['year', 'month', 'day']], errors='coerce')
print("Handling invalid date with errors='coerce':")
print(df_invalid)

Output:

Handling invalid date with errors='coerce':
   year  month  day Date_Coerced
0  2023      2   30          NaT

Conclusion

To create a single datetime column in a Pandas DataFrame from separate year, month, day (and optional time) columns:

  1. The recommended method is to pass a dictionary to pd.to_datetime(), where keys are standard names like 'year', 'month', 'day', 'hour', etc., and values are your DataFrame's corresponding columns (Series):

    df['NewDateTime'] = pd.to_datetime({
        'year': df['your_year_col'],
        'month': df['your_month_col'],
        'day': df['your_day_col']
    })
  2. Alternatively, if your DataFrame columns are already named 'year', 'month', 'day', etc., you can pass a subset of your DataFrame directly: pd.to_datetime(df[['year', 'month', 'day']]).

These methods are efficient and leverage Pandas' robust date parsing capabilities. Remember to handle potential errors for invalid date combinations using the errors='coerce' parameter if necessary.

Navigation