Tutoriels

Guide de Traitement des Timestamps en Python

Cette page est provisoirement disponible en anglais. La traduction française est en préparation.

Introduction

Python provides two main modules for working with dates and timestamps: datetime for high-level date operations and time for lower-level timestamp operations. Understanding how to properly use timestamps in Python is essential for data processing, API integration, and time-based applications. This guide covers timestamp fundamentals, conversions, timezone handling, and best practices.

Getting Current Timestamp

Using time Module

import time

# Get current Unix timestamp (seconds since epoch)
now_seconds = time.time()
print(now_seconds)  # e.g., 1704672000.123456

# Get current timestamp as integer
now_int = int(time.time())
print(now_int)  # e.g., 1704672000

# Get current time in milliseconds
now_ms = int(time.time() * 1000)
print(now_ms)  # e.g., 1704672000123

Using datetime Module

from datetime import datetime

# Get current UTC datetime
now_utc = datetime.utcnow()
print(now_utc)  # 2024-01-08 00:00:00.123456

# Get current local datetime
now_local = datetime.now()
print(now_local)  # 2024-01-07 19:00:00.123456 (if EST)

# Get timestamp from datetime
timestamp = now_utc.timestamp()
print(timestamp)  # e.g., 1704672000.123456

Best Practice: Use datetime.utcnow() for UTC timestamps and datetime.now() for local timestamps. Always be explicit about timezone.

Creating Datetime from Timestamp

From Unix Timestamp (Seconds)

from datetime import datetime

# Create datetime from Unix timestamp (seconds)
dt = datetime.fromtimestamp(1704672000)
print(dt)  # 2024-01-07 19:00:00 (local timezone)

# Create UTC datetime from Unix timestamp
dt_utc = datetime.utcfromtimestamp(1704672000)
print(dt_utc)  # 2024-01-08 00:00:00+00:00 (UTC)

From Unix Timestamp (Milliseconds)

from datetime import datetime

# Convert milliseconds to datetime
ts_ms = 1704672000123
dt = datetime.fromtimestamp(ts_ms / 1000)
print(dt)  # 2024-01-08 00:00:00.123000

Important: datetime.fromtimestamp() uses local timezone. Use datetime.utcfromtimestamp() for UTC.

From Date Components

from datetime import datetime

# Create from year, month, day, hour, minute, second
dt = datetime(2024, 1, 8, 14, 30, 45)
print(dt)  # 2024-01-08 14:30:45

# Create date only (time defaults to midnight)
dt_date = datetime(2024, 1, 8)
print(dt_date)  # 2024-01-08 00:00:00

# Create time only (date defaults to 1900-01-01)
from datetime import time
t = time(14, 30, 45)
print(t)  # 14:30:45

Python Range: datetime objects can represent years 1 to 9999.

Converting Datetime to Timestamp

Using timestamp() Method

from datetime import datetime

# Convert datetime to Unix timestamp (seconds)
dt = datetime(2024, 1, 8, 14, 30, 45)
timestamp = dt.timestamp()
print(timestamp)  # e.g., 1704672654.0

# Convert UTC datetime to timestamp
dt_utc = datetime(2024, 1, 8, 14, 30, 45, tzinfo=timezone.utc)
timestamp_utc = dt_utc.timestamp()
print(timestamp_utc)  # e.g., 1704695045.0

Using calendar.timegm() for UTC

import calendar
from datetime import datetime

# Convert UTC datetime to timestamp (naive datetime assumed UTC)
dt = datetime(2024, 1, 8, 14, 30, 45)
timestamp_utc = calendar.timegm(dt.timetuple())
print(timestamp_utc)  # e.g., 1704695045

# More reliable than timestamp() for UTC naive datetimes

Use Case: calendar.timegm() is useful when working with UTC timestamps from naive datetimes.

Date Arithmetic

Adding and Subtracting Time

from datetime import datetime, timedelta

# Add 7 days
dt = datetime(2024, 1, 8)
future = dt + timedelta(days=7)
print(future)  # 2024-01-15 00:00:00

# Subtract 1 hour
past = dt - timedelta(hours=1)
print(past)  # 2024-01-07 23:00:00

# Add 2 hours and 30 minutes
dt = datetime(2024, 1, 8, 10, 0, 0)
dt = dt + timedelta(hours=2, minutes=30)
print(dt)  # 2024-01-08 12:30:00

# Add negative timedelta (subtract)
dt = datetime(2024, 1, 8)
dt = dt + timedelta(days=-1)
print(dt)  # 2024-01-07 00:00:00

Calculating Duration

from datetime import datetime

# Calculate duration between two datetimes
dt1 = datetime(2024, 1, 8, 10, 0, 0)
dt2 = datetime(2024, 1, 8, 18, 0, 0)

duration = dt2 - dt1
print(duration)  # 8:00:00

# Extract duration components
print(duration.days)    # 0
print(duration.seconds)  # 28800 (8 hours)
print(duration.total_seconds())  # 28800.0

# Calculate in hours
hours = duration.total_seconds() / 3600
print(f"Duration: {hours} hours")  # Duration: 8.0 hours

Business Days Calculation

from datetime import datetime, timedelta

def add_business_days(start_date, days):
    """Add business days to a date (excludes weekends)"""
    result = start_date
    added_days = 0

    while added_days < days:
        result += timedelta(days=1)
        if result.weekday() < 5:  # Monday=0, Friday=4
            added_days += 1

    return result

# Example
start = datetime(2024, 1, 8)
result = add_business_days(start, 5)
print(result)  # 2024-01-15 (Monday)

Recommendation: Use the python-dateutil library for more advanced business day calculations including holidays.

Formatting Dates

ISO 8601 Format

from datetime import datetime

# Format as ISO 8601
dt = datetime(2024, 1, 8, 14, 30, 45)
iso_string = dt.isoformat()
print(iso_string)  # 2024-01-08T14:30:45

# With timezone (using pytz)
import pytz
tz = pytz.timezone('America/New_York')
dt = datetime(2024, 1, 8, 14, 30, 45, tzinfo=tz)
iso_with_tz = dt.isoformat()
print(iso_with_tz)  # 2024-01-08T14:30:45-05:00

Custom Formatting with strftime

from datetime import datetime

dt = datetime(2024, 1, 8, 14, 30, 45)

# Common format codes
formats = {
    'YYYY-MM-DD': dt.strftime('%Y-%m-%d'),  # 2024-01-08
    'YYYY/MM/DD HH:MM': dt.strftime('%Y/%m/%d %H:%M'),  # 2024/01/08 14:30
    'Day Month, Year': dt.strftime('%d %B, %Y'),  # 08 January, 2024
    'Weekday': dt.strftime('%A'),  # Monday
    'Short Weekday': dt.strftime('%a'),  # Mon
    'Time': dt.strftime('%H:%M:%S'),  # 14:30:45
    'AM/PM': dt.strftime('%I:%M %p'),  # 02:30 PM
}

for name, formatted in formats.items():
    print(f"{name}: {formatted}")

Format Codes:

> %Y  Year (4 digits)           %m  Month (01-12)
> %y  Year (2 digits)           %d  Day (01-31)
> %B  Month name (January)         %b  Month abbr (Jan)
> %A  Weekday name (Monday)       %a  Weekday abbr (Mon)
> %H  Hour (00-23)             %I  Hour (01-12)
> %M  Minute (00-59)            %S  Second (00-59)
> %p  AM/PM                     %f  Microseconds (000000-999999)
>

Format for Different Locales

from datetime import datetime
import locale

dt = datetime(2024, 1, 8, 14, 30, 45)

# Set locale
locale.setlocale(locale.LC_ALL, 'en_US.UTF-8')
en_format = dt.strftime('%B %d, %Y')  # January 08, 2024

locale.setlocale(locale.LC_ALL, 'fr_FR.UTF-8')
fr_format = dt.strftime('%d %B %Y')  # 08 janvier 2024

locale.setlocale(locale.LC_ALL, 'zh_CN.UTF-8')
zh_format = dt.strftime('%Y年%m月%d日')  # 2024年01月08日

Note: locale.setlocale() affects the entire process. Use locale.getlocale() to restore original locale.

Parsing Dates

Parsing ISO 8601 Strings

from datetime import datetime

# Parse ISO 8601 string
iso_string = "2024-01-08T14:30:45"
dt = datetime.fromisoformat(iso_string)
print(dt)  # 2024-01-08 14:30:45

# Parse with timezone
iso_tz_string = "2024-01-08T14:30:45-05:00"
dt_tz = datetime.fromisoformat(iso_tz_string)
print(dt_tz)  # 2024-01-08 14:30:45-05:00

Parsing Custom Formats with strptime

from datetime import datetime

# Parse custom format
date_string = "08 January, 2024 14:30:45"
dt = datetime.strptime(date_string, '%d %B, %Y %H:%M:%S')
print(dt)  # 2024-01-08 14:30:45

# Parse US format
us_string = "01/08/2024 2:30 PM"
dt_us = datetime.strptime(us_string, '%m/%d/%Y %I:%M %p')
print(dt_us)  # 2024-01-08 14:30:00

# Parse 24-hour format
eu_string = "08.01.2024 14:30"
dt_eu = datetime.strptime(eu_string, '%d.%m.%Y %H:%M')
print(dt_eu)  # 2024-01-08 14:30:00

Format Codes for strptime:

> Same as strftime() format codes:
>   %Y (year), %m (month), %d (day)
>   %H (hour 24), %I (hour 12), %M (minute), %S (second)
>   %p (AM/PM), %f (microseconds)
>   %B (month name), %A (weekday name)
>

Handling Parse Errors

from datetime import datetime

def safe_parse_date(date_string, format_string):
    """Parse date string with error handling"""
    try:
        return datetime.strptime(date_string, format_string)
    except ValueError as e:
        print(f"Failed to parse date: {date_string}")
        print(f"Error: {e}")
        return None

# Examples
valid = safe_parse_date("2024-01-08", "%Y-%m-%d")
invalid = safe_parse_date("invalid date", "%Y-%m-%d")

print(valid)   # 2024-01-08 00:00:00
print(invalid)  # Failed to parse date: invalid date

Timezone Handling

Using pytz Library

from datetime import datetime
import pytz

# Create datetime with timezone
tz = pytz.timezone('America/New_York')
dt_aware = datetime(2024, 1, 8, 14, 30, 45, tzinfo=tz)
print(dt_aware)  # 2024-01-08 14:30:45-05:00

# Convert between timezones
tokyo_tz = pytz.timezone('Asia/Tokyo')
dt_tokyo = dt_aware.astimezone(tokyo_tz)
print(dt_tokyo)  # 2024-01-09 04:30:45+09:00

# Get current time in specific timezone
tz = pytz.timezone('Europe/London')
now_london = datetime.now(tz)
print(now_london)  # 2024-01-08 00:00:00+00:00

Best Practice: Install pytz with pip install pytz for comprehensive timezone support.

Using zoneinfo (Python 3.9+)

from datetime import datetime, timezone
from zoneinfo import ZoneInfo

# Python 3.9+ built-in timezone support
tz = ZoneInfo('America/New_York')
dt_aware = datetime(2024, 1, 8, 14, 30, 45, tzinfo=tz)
print(dt_aware)  # 2024-01-08 14:30:45-05:00

# Convert to UTC
dt_utc = dt_aware.astimezone(timezone.utc)
print(dt_utc)  # 2024-01-08 19:30:45+00:00

Advantage: zoneinfo is built into Python 3.9+, no external dependencies needed.

UTC vs Local Time

from datetime import datetime

# Get local time (system timezone)
dt_local = datetime.now()
print(f"Local: {dt_local}")

# Get UTC time
dt_utc = datetime.utcnow()
print(f"UTC: {dt_utc}")

# Convert local to UTC (requires timezone-aware datetime)
import pytz
tz = pytz.timezone('America/New_York')
dt_aware = datetime.now(tz)
dt_utc = dt_aware.astimezone(pytz.utc)
print(f"Converted to UTC: {dt_utc}")

Common Operations

Start/End of Period

from datetime import datetime, timedelta

def start_of_day(dt):
    """Return start of day (midnight)"""
    return dt.replace(hour=0, minute=0, second=0, microsecond=0)

def end_of_day(dt):
    """Return end of day (23:59:59.999999)"""
    return dt.replace(hour=23, minute=59, second=59, microsecond=999999)

def start_of_month(dt):
    """Return start of month"""
    return dt.replace(day=1, hour=0, minute=0, second=0, microsecond=0)

def end_of_month(dt):
    """Return end of month"""
    if dt.month == 12:
        return dt.replace(year=dt.year + 1, month=1, day=1) - timedelta(days=1)
    return dt.replace(month=dt.month + 1, day=1) - timedelta(days=1)

# Examples
dt = datetime(2024, 1, 15, 14, 30, 45)
print(start_of_day(dt))    # 2024-01-15 00:00:00
print(end_of_month(dt))    # 2024-01-31 23:59:59.999999

Age Calculation

from datetime import datetime

def calculate_age(birth_date):
    """Calculate age in years, months, and days"""
    today = datetime.now()
    birth = datetime.fromisoformat(birth_date)

    years = today.year - birth.year
    months = today.month - birth.month
    days = today.day - birth.day

    # Adjust if birthday hasn't happened yet this year
    if (months < 0 or (months == 0 and days < 0)):
        years -= 1
        months += 12

    return {
        'years': years,
        'months': months,
        'days': days
    }

# Example
age = calculate_age('1990-06-15')
print(f"Age: {age['years']} years, {age['months']} months, {age['days']} days")
# Age: 33 years, 6 months, -7 days

Countdown Timer

from datetime import datetime

def countdown(target_date_str):
    """Calculate countdown to target date"""
    target = datetime.fromisoformat(target_date_str)
    now = datetime.now()
    diff = target - now

    if diff.total_seconds() <= 0:
        return {'expired': True, 'text': 'Target date passed'}

    days = diff.days
    hours = diff.seconds // 3600
    minutes = (diff.seconds % 3600) // 60
    seconds = diff.seconds % 60

    return {
        'expired': False,
        'text': f"{days} days, {hours} hours, {minutes} minutes, {seconds} seconds",
        'total_seconds': diff.total_seconds()
    }

# Example
result = countdown('2024-12-31T00:00:00')
print(result['text'])
# "357 days, 11 hours, 29 minutes, 12 seconds"

Best Practices

Timezone Best Practices

✅ Always store UTC timestamps in databases
✅ Convert to local timezone only for display
✅ Use timezone-aware datetime objects for user-facing times
✅ Document timezone assumptions in code comments
✅ Use IANA timezone names (America/New_York, not UTC-5)
❌ Don't store local timestamps without timezone metadata
❌ Don't mix UTC and naive datetimes in calculations
❌ Don't assume server timezone matches user timezone
❌ Don't use pytz for Python 3.9+ (use zoneinfo instead)

Performance Tips

✅ Use datetime.timestamp() instead of time.time() for datetime objects
✅ Cache timezone objects when used repeatedly
✅ Use datetime.utcnow() for UTC (faster than aware datetimes)
✅ Use timedelta arithmetic for time calculations (more readable)
❌ Don't create timezone objects in loops (reuse them)
❌ Don't call datetime.now() in tight loops (call once and reuse)

Data Integrity

from datetime import datetime

def validate_datetime(dt):
    """Validate datetime object is within reasonable range"""
    if not isinstance(dt, datetime):
        return False, "Not a datetime object"

    if dt.year < 1900 or dt.year > 2100:
        return False, "Year out of reasonable range"

    if dt.month < 1 or dt.month > 12:
        return False, "Invalid month"

    if dt.day < 1 or dt.day > 31:
        return False, "Invalid day"

    return True, "Valid"

# Example
valid = validate_datetime(datetime(2024, 1, 8, 14, 30, 45))
print(valid)  # (True, "Valid")

invalid = validate_datetime(datetime(2024, 13, 1))
print(invalid)  # (False, "Invalid month")

Related Tools

Additional Resources

For production applications with complex timezone or business day requirements, consider using:

  • pytz: Legacy but widely supported timezone library
  • zoneinfo: Built-in Python 3.9+ (preferred for new code)
  • python-dateutil: Advanced date parsing and business day calculations
  • pendulum: Pythonic datetime library with better timezone handling

Python's datetime module is sufficient for basic operations, but libraries provide better timezone support and parsing for complex use cases.

Mise a jour

En Python, utilisez datetime avec timezone.utc. Un datetime naif depend du fuseau local du processus et peut donner des resultats differents selon la machine.

Essayez

Testez votre conversion de timestamp

Résultat de date

Besoin de plus d'options ? Convertisseur Epoch