How the Lifetrace Time Parser Utility Parses Natural Language Deadlines

The time parser utility interprets natural language deadlines by first attempting 24-hour clock parsing, then falling back to Chinese 12-hour period recognition, and finally combining these with relative day offsets to produce concrete datetime objects.

The freeu-group/lifetrace repository includes a robust time-parser module located in lifetrace/util/time_parser.py that converts human-friendly deadline expressions into machine-readable datetime objects. This utility handles everything from simple "14:30" strings to complex Chinese temporal expressions like "下午3点30分" (3:30 PM), enabling the application to schedule tasks based on natural language input.

Entry Point and Dual-Strategy Parsing

When processing a deadline string, the system invokes parse_time_string as the primary entry point. This function implements a cascading strategy that attempts two distinct parsing methods in sequence.

If the first method fails, the parser automatically falls back to the second. When both attempts fail, the utility logs a warning via the configured logger and returns None to signal an unparseable input.

24-Hour Clock Parsing

The _parse_24h_time function handles standard numeric time formats using the regex pattern r"(\d{1,2}):?(\d{2})". This pattern accommodates both colon-separated strings like "13:45" and compact four-digit sequences like "1345".

The function validates that the extracted hour falls within [0, 23] and the minute within [0, 59] before returning a (hour, minute) tuple. If validation fails, the function returns None, triggering the fallback mechanism.

Chinese 12-Hour Period Parsing

For Chinese natural language input, _parse_12h_time processes temporal expressions containing period markers. The function normalizes the input to lower-case and identifies keywords such as 凌晨 (early morning), 上午 (morning), 中午 (noon), 下午 (afternoon), 傍晚 (evening), and 晚上 (night).

Each period maps to a base hour—for example, "下午" maps to 13. The function extracts numeric components using re.findall(r"\d+", time_str), interpreting the first number as the hour and the optional second as the minute. The logic then adjusts the hour based on the detected period: afternoon and evening periods add 12 when the hour is less than 12, while midnight periods treat 12 o'clock as 0.

Handling Relative Deadlines

The parse_relative_time function interprets deadlines expressed relative to a reference point, such as "今天下午 3 点" (today at 3 PM). This function accepts relative_days (where 0 equals today, 1 equals tomorrow) and a time fragment that may use either 24-hour or Chinese 12-hour format.

The implementation parses the time fragment by delegating to parse_time_string, then constructs a target datetime by adding the specified number of days to the reference date and combining it with the parsed hour and minute. If the resulting timestamp is earlier than the reference time and relative_days equals 0, the caller may choose to roll the deadline to the next day, though the parser itself leaves this decision to the consuming service.

Absolute Timestamp Support

For ISO-8601 formatted deadlines, parse_absolute_time provides direct conversion capabilities. The function accepts strings in formats such as "2024-12-01T09:30:00" or "2024-12-01 09:30", normalizing the separator before forwarding to datetime.fromisoformat. If the input is already a datetime object, the function returns it unchanged, ensuring idempotent behavior.

Orchestration Layer

Higher-level services interact with the parser through calculate_scheduled_time, which acts as a dispatcher based on the time_type field of a time_info dictionary.

  • For "absolute" types, the function routes to parse_absolute_time
  • For "relative" types, it invokes parse_relative_time with the provided relative_days and relative_time parameters
  • Unknown time_type values trigger a warning log entry

This architecture allows the utility to interpret a wide spectrum of natural-language specifications through a unified interface.

Normalization and Canonical Output

After successful parsing, normalize_time_string converts any accepted format into a canonical "HH:MM" string representation. This function delegates to parse_time_string internally, ensuring consistency across different input styles while providing a standardized format for storage or display purposes.

Practical Implementation Examples

from datetime import datetime
from lifetrace.util.time_parser import (
    parse_time_string,
    normalize_time_string,
    calculate_scheduled_time,
)

# 24-hour format parsing

print(parse_time_string("14:45"))          # → (14, 45)

# Chinese 12-hour expression

print(parse_time_string("下午3点30分"))      # → (15, 30)

# Normalization to standard format

print(normalize_time_string("下午3点"))      # → "15:00"

# Relative deadline calculation

reference = datetime.now()
time_info = {
    "time_type": "relative",
    "relative_days": 0,
    "relative_time": "下午4点",
}
print(calculate_scheduled_time(time_info, reference))

# Absolute ISO timestamp

time_info = {
    "time_type": "absolute",
    "absolute_time": "2024-07-20T09:30:00"
}
print(calculate_scheduled_time(time_info, reference))

Summary

  • The parse_time_string function in lifetrace/util/time_parser.py serves as the primary entry point, attempting 24-hour parsing before falling back to Chinese 12-hour period recognition.
  • ** _parse_24h_time** uses regex pattern r"(\d{1,2}):?(\d{2})" to extract and validate hour-minute pairs from numeric strings.
  • ** _parse_12h_time** maps Chinese temporal keywords to base hours and adjusts values based on period context (afternoon periods add 12, midnight treats 12 as 0).
  • ** parse_relative_time** combines date offsets with parsed time components to handle expressions like "tomorrow at 3 PM".
  • ** calculate_scheduled_time** provides a unified dispatcher that routes absolute ISO-8601 timestamps and relative natural language expressions through the appropriate processing pipeline.

Frequently Asked Questions

What time formats does the Lifetrace parser support?

According to the freeu-group/lifetrace source code, the parser supports four primary categories: 24-hour clock strings (with or without colons), Chinese 12-hour period expressions containing keywords like 上午 or 下午, ISO-8601 absolute timestamps, and relative time expressions combined with day offsets. The modular design allows each format to be processed through specialized functions while exposing a unified interface.

How does the parser handle ambiguous Chinese time expressions?

The _parse_12h_time function resolves ambiguity by mapping specific period keywords to base hour values and applying contextual rules. For instance, when encountering 下午 (afternoon) or 晚上 (evening), the parser adds 12 to hours below 12 to convert to 24-hour format, while 中午 (noon) preserves 12 as-is. The 凌晨 (early morning) and 上午 (morning) periods treat 12 o'clock as 0 (midnight), ensuring accurate temporal calculation across different Chinese linguistic conventions.

What happens when the parser cannot recognize a time string?

When parse_time_string exhausts both the 24-hour and 12-hour parsing strategies without success, the utility logs a warning message and returns None. This failure mode allows calling services to implement fallback behavior, such as prompting the user for clarification or defaulting to a scheduled time. The logging integration through logging_config.py ensures that parsing failures are recorded for debugging purposes.

Can the parser handle ISO-8601 timestamps?

Yes, the parse_absolute_time function explicitly handles ISO-8601 formatted strings by normalizing space or "T" separators and delegating to Python's datetime.fromisoformat method. This implementation accepts standard formats like "2024-12-01T09:30:00" or "2024-12-01 09:30", and also passes through existing datetime objects unchanged, making it suitable for API integrations and database timestamp fields.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →