Maintenance

Site is under maintenance — quizzes are still available.

Go to quizzes
Sponsored Reserved space — layout preview until AdSense is connected

Convert Natural Language Dates to Datetime in Python

Parse common natural language date phrases like 'tomorrow' or 'in 3 days' into Python datetime objects using regex and timedelta.

Medium Python 3.9+ Jun 28, 2026 Strings & text 2 views 0 copies

Python code

47 lines
Python 3.9+
from datetime import datetime, timedelta
import re

def parse_natural_date(text: str) -> datetime:
    """Convert common natural language date expressions to datetime objects."""
    now = datetime.now()
    text = text.lower().strip()
    
    # Handle relative dates
    patterns = {
        r"today": now,
        r"tomorrow": now + timedelta(days=1),
        r"yesterday": now - timedelta(days=1),
        r"next week": now + timedelta(weeks=1),
        r"last week": now - timedelta(weeks=1),
        r"next month": now.replace(month=now.month + 1 if now.month < 12 else 1),
        r"last month": now.replace(month=now.month - 1 if now.month > 1 else 12),
        r"next year": now.replace(year=now.year + 1),
        r"last year": now.replace(year=now.year - 1),
        r"in (\d+) days": lambda m: now + timedelta(days=int(m.group(1))),
        r"(\d+) days ago": lambda m: now - timedelta(days=int(m.group(1))),
        r"in (\d+) weeks": lambda m: now + timedelta(weeks=int(m.group(1))),
        r"(\d+) weeks ago": lambda m: now - timedelta(weeks=int(m.group(1))),
    }
    
    for pattern, handler in patterns.items():
        match = re.match(pattern, text)
        if match:
            result = handler(text) if isinstance(handler, dict) else handler
            if callable(handler):
                result = handler(match)
            return result if isinstance(result, datetime) else handler
        
        if isinstance(handler, datetime):
            if re.fullmatch(pattern, text):
                return handler
        else:
            if re.fullmatch(pattern, text):
                return handler
    
    return now

if __name__ == "__main__":
    tests = ["today", "tomorrow", "yesterday", "in 3 days", "5 days ago", "next week"]
    for test in tests:
        result = parse_natural_date(test)
        print(f"{test:15} -> {result.date()}")

Output

stdout
today            -> 2025-04-16
tomorrow         -> 2025-04-17
yesterday        -> 2025-04-15
in 3 days        -> 2025-04-19
5 days ago       -> 2025-04-11
next week        -> 2025-04-23

How it works

The parse_natural_date function uses a dictionary of regex patterns mapped to either a static datetime or a callable lambda. When a pattern matches, the handler computes the relative offset from datetime.now() using timedelta or direct datetime.replace calls. The re.fullmatch ensures the entire input matches a pattern, preventing partial matches. This approach is extensible — new patterns can be added by simply inserting another regex entry in the dictionary.

Common mistakes

  • Using `re.match` instead of `re.fullmatch` can cause partial matches (e.g., 'today' matching part of 'todayish').
  • Forgetting to handle month/year wrapping when adding months; the example uses conditional logic to avoid invalid dates.
  • Not stripping whitespace or lowercasing input, causing ' Tomorrow ' to fail silently.

Variations

  1. Use `dateparser` library (third-party) for robust natural language parsing including time zones and non-English phrases.
  2. Extend the pattern dictionary to support absolute dates like 'April 5, 2025' using `datetime.strptime` after regex.

Real-world use cases

  • Accept user input like 'remind me in 2 days' in a CLI todo app and schedule a notification.
  • Parse chat commands in a Discord bot where users say 'show events tomorrow' and reply with filtered results.
  • Allow non-technical staff to query log timestamps with phrases in a dashboard search box.

Sponsored

Sponsored Reserved space — layout preview until AdSense is connected

Run this sample

Open the browser IDE to tweak the example and see results without installing anything.

Open editor

More from Strings & text

Related tutorials and quizzes for this topic.