Epoch Time to Datetime Conversion in Python

While working on a project where I had to process server logs with timestamps stored as epoch time. The challenge was converting these Unix timestamps to human-readable datetime formats for analysis.

If you’ve ever dealt with APIs, databases, or log files, you’ve probably encountered epoch time. It’s everywhere in the tech world, but it’s not exactly user-friendly when you’re trying to understand when something happened.

In this article, I’ll show you five different methods to convert epoch time to datetime in Python. Each method has its use case, and I’ll explain when to use which approach based on my experience.

Epoch Time

Epoch time (also called Unix timestamp) represents the number of seconds that have elapsed since January 1, 1970, 00:00:00 UTC. This date is known as the Unix epoch.

For example, the epoch time 1672531200 represents January 1, 2023, 00:00:00 UTC. It’s a standardized way to represent time across different systems and programming languages.

Methods to Convert Epoch Time to Datetime in Python

Let me explain to you the efficient methods to convert epoch time to datetime in Python.

1 – Use datetime.fromtimestamp()

The easy way to convert epoch time to a datetime is using Python’s built-in datetime.fromtimestamp() method.

Here’s a practical example using a timestamp from a typical web server log:

from datetime import datetime

# Example: Converting a server log timestamp
epoch_time = 1672531200  # January 1, 2023, 00:00:00 UTC
datetime_obj = datetime.fromtimestamp(epoch_time)

print(f"Epoch time: {epoch_time}")
print(f"Datetime: {datetime_obj}")
print(f"Formatted: {datetime_obj.strftime('%Y-%m-%d %H:%M:%S')}")

Output:

Epoch time: 1672531200
Datetime: 2023-01-01 00:00:00
Formatted: 2023-01-01 00:00:00

You can refer to the screenshot below to see the output.

convert epoch to datetime python

This method automatically converts to your local timezone. If you’re in EST, the result will show EST time, not UTC.

2 – Use datetime.utcfromtimestamp() for UTC Time

When working with international applications or when you need precise UTC, use datetime.utcfromtimestamp() method in Python.

from datetime import datetime

# Example: Processing timestamps from a global API
api_timestamps = [1672531200, 1672534800, 1672538400]  # New Year's Day 2023 hourly data

print("API Response Timestamps (UTC):")
for i, timestamp in enumerate(api_timestamps):
    utc_datetime = datetime.utcfromtimestamp(timestamp)
    print(f"Entry {i+1}: {utc_datetime} UTC")
    print(f"  Formatted: {utc_datetime.strftime('%B %d, %Y at %I:%M %p')} UTC")
    print()

Output:

API Response Timestamps (UTC):
Entry 1: 2023-01-01 00:00:00 UTC
  Formatted: January 01, 2023 at 12:00 AM UTC

Entry 2: 2023-01-01 01:00:00 UTC
  Formatted: January 01, 2023 at 01:00 AM UTC

Entry 3: 2023-01-01 02:00:00 UTC
  Formatted: January 01, 2023 at 02:00 AM UTC

You can refer to the screenshot below to see the output.

python datetime to epoch

This method is crucial when you’re dealing with data from multiple time zones or when storing data in databases.

3 – Use timezone-aware datetime with pytz

For production applications, I always recommend using timezone-aware datetime objects. This requires the pytz library for better timezone handling.

First, install pytz if you haven’t already:

pip install pytz

Here’s how to convert epoch time to different US time zones:

from datetime import datetime
import pytz

def convert_epoch_to_timezone(epoch_time, timezone_str):
    """Convert epoch time to specified timezone"""
    utc_datetime = datetime.utcfromtimestamp(epoch_time)
    utc_datetime = pytz.utc.localize(utc_datetime)
    target_timezone = pytz.timezone(timezone_str)
    return utc_datetime.astimezone(target_timezone)

# Example: Converting trading session timestamps
trading_start_epoch = 1672934400  # January 5, 2023 (typical trading day)

# Convert to different US time zones
timezones = [
    'US/Eastern',    # New York Stock Exchange
    'US/Central',    # Chicago
    'US/Mountain',   # Denver
    'US/Pacific'     # NASDAQ (California)
]

print(f"Trading Session Start (Epoch: {trading_start_epoch}):")
for tz in timezones:
    tz_datetime = convert_epoch_to_timezone(trading_start_epoch, tz)
    print(f"  {tz}: {tz_datetime.strftime('%Y-%m-%d %I:%M:%S %p %Z')}")

Output:

Trading Session Start (Epoch: 1672934400):
  US/Eastern: 2023-01-05 02:00:00 PM EST
  US/Central: 2023-01-05 01:00:00 PM CST
  US/Mountain: 2023-01-05 12:00:00 PM MST
  US/Pacific: 2023-01-05 11:00:00 AM PST

You can refer to the screenshot below to see the output.

python epoch to datetime

This approach handles daylight saving time automatically, which is essential for financial or business applications.

4 – Use pandas for Large Datasets

When working with large datasets containing multiple epoch timestamps, pandas provides an efficient solution.

import pandas as pd
from datetime import datetime

# Example: Processing e-commerce transaction data
transaction_data = {
    'transaction_id': ['TXN001', 'TXN002', 'TXN003', 'TXN004', 'TXN005'],
    'epoch_timestamp': [1672531200, 1672534800, 1672538400, 1672542000, 1672545600],
    'amount': [149.99, 79.50, 299.00, 45.25, 199.99],
    'customer_id': ['CUST001', 'CUST002', 'CUST003', 'CUST004', 'CUST005']
}

# Create DataFrame
df = pd.DataFrame(transaction_data)

# Convert epoch timestamps to datetime
df['transaction_datetime'] = pd.to_datetime(df['epoch_timestamp'], unit='s')

# Format for better readability
df['formatted_date'] = df['transaction_datetime'].dt.strftime('%B %d, %Y at %I:%M %p')

# Display results
print("E-commerce Transaction Analysis:")
print(df[['transaction_id', 'formatted_date', 'amount']].to_string(index=False))

# Additional analysis
print(f"\nTotal transactions: {len(df)}")
print(f"Date range: {df['transaction_datetime'].min().date()} to {df['transaction_datetime'].max().date()}")
print(f"Total revenue: ${df['amount'].sum():.2f}")

Output:

E-commerce Transaction Analysis:
transaction_id       formatted_date  amount
        TXN001  January 01, 2023 at 12:00 AM  149.99
        TXN002  January 01, 2023 at 01:00 AM   79.50
        TXN003  January 01, 2023 at 02:00 AM  299.00
        TXN004  January 01, 2023 at 03:00 AM   45.25
        TXN005  January 01, 2023 at 04:00 AM  199.99

Total transactions: 5
Date range: 2023-01-01 to 2023-01-01
Total revenue: $773.73

You can refer to the screenshot below to see the output.

python datetime epoch

This method is particularly useful when you’re analyzing time-series data or working with CSV files containing epoch timestamps.

5 – Handle Millisecond Epoch Time

Sometimes you’ll encounter epoch timestamps in milliseconds instead of seconds. This is common with JavaScript APIs or certain databases.

from datetime import datetime
import pandas as pd

def convert_millisecond_epoch(ms_epoch):
    """Convert millisecond epoch to datetime"""
    return datetime.fromtimestamp(ms_epoch / 1000)

# Example: Processing mobile app analytics data
app_events = [
    {'event': 'app_open', 'timestamp_ms': 1672531200000},
    {'event': 'user_login', 'timestamp_ms': 1672531260000},
    {'event': 'purchase_view', 'timestamp_ms': 1672531320000},
    {'event': 'purchase_complete', 'timestamp_ms': 1672531380000},
    {'event': 'app_close', 'timestamp_ms': 1672531440000}
]

print("Mobile App User Journey:")
for event in app_events:
    dt = convert_millisecond_epoch(event['timestamp_ms'])
    formatted_time = dt.strftime('%I:%M:%S %p')
    print(f"  {formatted_time} - {event['event'].replace('_', ' ').title()}")

# Using pandas for millisecond conversion
df = pd.DataFrame(app_events)
df['datetime'] = pd.to_datetime(df['timestamp_ms'], unit='ms')
df['time_spent'] = df['datetime'].diff().dt.total_seconds().fillna(0)

print(f"\nSession Analysis:")
print(f"Total session time: {df['time_spent'].sum()} seconds")
print(f"Time to purchase: {df[df['event'] == 'purchase_complete']['time_spent'].sum()} seconds from login")

Output:

Mobile App User Journey:
  12:00:00 AM - App Open
  12:01:00 AM - User Login
  12:02:00 AM - Purchase View
  12:03:00 AM - Purchase Complete
  12:04:00 AM - App Close

Session Analysis:
Total session time: 240.0 seconds
Time to purchase: 60.0 seconds from login

This example demonstrates converting millisecond-based epoch timestamps into human-readable datetimes and analyzing event durations.

Real-World Application Example

Here’s a complete example that demonstrates how I recently used epoch time conversion in a financial trading application:

import pandas as pd
from datetime import datetime
import pytz
import json

class TradingDataProcessor:
    """Process trading data with epoch timestamp conversion"""
    
    def __init__(self, timezone='US/Eastern'):
        self.timezone = pytz.timezone(timezone)
    
    def process_trade_data(self, raw_data):
        """Process raw trading data from API"""
        # Convert to DataFrame
        df = pd.DataFrame(raw_data)
        
        # Convert epoch timestamps
        df['trade_datetime'] = pd.to_datetime(df['timestamp'], unit='s')
        df['trade_datetime'] = df['trade_datetime'].dt.tz_localize('UTC').dt.tz_convert(self.timezone)
        
        # Add market session info
        df['market_session'] = df['trade_datetime'].apply(self._get_market_session)
        df['trading_day'] = df['trade_datetime'].dt.date
        
        # Format for display
        df['formatted_time'] = df['trade_datetime'].dt.strftime('%Y-%m-%d %I:%M:%S %p %Z')
        
        return df
    
    def _get_market_session(self, dt):
        """Determine market session based on time"""
        hour = dt.hour
        if 4 <= hour < 9:
            return "Pre-Market"
        elif 9 <= hour < 16:
            return "Regular Hours"
        elif 16 <= hour < 20:
            return "After Hours"
        else:
            return "Closed"
    
    def generate_summary(self, df):
        """Generate trading summary"""
        summary = {
            'total_trades': len(df),
            'trading_days': df['trading_day'].nunique(),
            'sessions': df['market_session'].value_counts().to_dict(),
            'volume': df['quantity'].sum(),
            'value': (df['price'] * df['quantity']).sum(),
            'time_range': {
                'start': df['trade_datetime'].min().strftime('%Y-%m-%d %I:%M:%S %p %Z'),
                'end': df['trade_datetime'].max().strftime('%Y-%m-%d %I:%M:%S %p %Z')
            }
        }
        return summary

# Example usage with sample trading data
sample_trades = [
    {'timestamp': 1672934400, 'symbol': 'AAPL', 'price': 130.15, 'quantity': 100, 'side': 'BUY'},
    {'timestamp': 1672938000, 'symbol': 'GOOGL', 'price': 89.25, 'quantity': 50, 'side': 'BUY'},
    {'timestamp': 1672941600, 'symbol': 'MSFT', 'price': 239.50, 'quantity': 75, 'side': 'SELL'},
    {'timestamp': 1672945200, 'symbol': 'AAPL', 'price': 131.20, 'quantity': 200, 'side': 'BUY'},
    {'timestamp': 1672948800, 'symbol': 'TSLA', 'price': 157.90, 'quantity': 25, 'side': 'BUY'},
]

# Process the data
processor = TradingDataProcessor()
trades_df = processor.process_trade_data(sample_trades)

print("Trading Data Analysis")
print("=" * 50)
print(trades_df[['symbol', 'formatted_time', 'market_session', 'price', 'quantity', 'side']].to_string(index=False))

# Generate summary
summary = processor.generate_summary(trades_df)
print(f"\nTrading Summary:")
print(f"Total Trades: {summary['total_trades']}")
print(f"Trading Days: {summary['trading_days']}")
print(f"Total Volume: {summary['volume']:,} shares")
print(f"Total Value: ${summary['value']:,.2f}")
print(f"Time Range: {summary['time_range']['start']} to {summary['time_range']['end']}")

print(f"\nSession Breakdown:")
for session, count in summary['sessions'].items():
    print(f"  {session}: {count} trades")

Output:

Trading Data Analysis
==================================================
symbol      formatted_time market_session   price  quantity side
  AAPL  2023-01-05 02:00:00 PM EST   Regular Hours  130.15       100  BUY
 GOOGL  2023-01-05 03:00:00 PM EST   Regular Hours   89.25        50  BUY
  MSFT  2023-01-05 04:00:00 PM EST    After Hours  239.50        75 SELL
  AAPL  2023-01-05 05:00:00 PM EST    After Hours  131.20       200  BUY
  TSLA  2023-01-05 06:00:00 PM EST    After Hours  157.90        25  BUY

Trading Summary:
Total Trades: 5
Trading Days: 1
Total Volume: 450 shares
Total Value: $67,650.00
Time Range: 2023-01-05 02:00:00 PM EST to 2023-01-05 06:00:00 PM EST

Session Breakdown:
  Regular Hours: 2 trades
  After Hours: 3 trades

This example showcases how epoch timestamps can be transformed into readable trading insights with detailed session-based summaries.

Conclusion

The key is understanding your data source and choosing the right method for your specific use case. Whether you’re processing server logs, analyzing trading data, or building APIs, these techniques will help you handle epoch timestamps confidently and efficiently.

Remember to always validate your timestamps, handle errors gracefully, and be explicit about time zones. Your future self (and your users) will thank you for taking the time to implement robust timestamp conversion from the start.

You may also read:

51 Python Programs

51 PYTHON PROGRAMS PDF FREE

Download a FREE PDF (112 Pages) Containing 51 Useful Python Programs.

pyython developer roadmap

Aspiring to be a Python developer?

Download a FREE PDF on how to become a Python developer.

Let’s be friends

Be the first to know about sales and special discounts.