You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将不完整及公元前(BC)的Wikidata日期转换为时间戳?

Solution for Parsing Wikidata Dates in Python

Let's fix your issues step by step—handling the AD/BC sign, incomplete dates, and ensuring correct UTC timestamp conversion.

Problem Breakdown

Your original code has three key flaws:

  1. Sign stripping: Removing the leading +/- means BC dates get misparsed as AD.
  2. Timezone ignorance: The Z in Wikidata dates indicates UTC, but your naive datetime uses local time for timestamp calculations, leading to incorrect values if your system isn't set to UTC.
  3. Incomplete date handling: Dates like +2018 (year only) or +2018-03 (year/month) aren't processed consistently by default.

Fixed Implementation

Here's a robust function that handles all Wikidata date formats, preserves the AD/BC sign, respects UTC, and fills missing components logically:

from datetime import datetime, timezone

def parse_wikidata_date(datestring):
    # Extract the AD/BC sign
    sign = datestring[0]
    rest = datestring[1:]
    
    # Split date and time parts (handle cases without explicit time)
    if 'T' in rest:
        date_part, time_part = rest.split('T', 1)
        time_part = time_part.rstrip('Z')  # Remove UTC indicator
    else:
        date_part = rest
        time_part = '00:00:00'  # Default to midnight UTC
    
    # Parse date components (year, month, day)
    date_components = date_part.split('-')
    year = int(sign + date_components[0])
    month = int(date_components[1]) if len(date_components) >= 2 else 1
    day = int(date_components[2]) if len(date_components) >= 3 else 1
    
    # Parse time components (hour, minute, second)
    time_components = time_part.split(':')
    hour = int(time_components[0]) if len(time_components) >= 1 else 0
    minute = int(time_components[1]) if len(time_components) >= 2 else 0
    second = int(time_components[2]) if len(time_components) >= 3 else 0
    
    # Create UTC-aware datetime object
    return datetime(year, month, day, hour, minute, second, tzinfo=timezone.utc)

# Helper to convert directly to timestamp
def wikidate_to_timestamp(datestring):
    dt = parse_wikidata_date(datestring)
    return dt.timestamp()

Test Cases

Let's verify with your example and edge cases:

1. Original AD Date (Douglas Adams' Birthday)

print(wikidate_to_timestamp('+1952-03-11T00:00:00Z'))
# Output: -562032000.0 (matches your original result, but now timezone-correct)

2. BC Date (2 BC)

print(wikidate_to_timestamp('-0001-03-11T00:00:00Z'))
# Output: -62135596800.0 (correct timestamp for March 11, 2 BC UTC)

3. Incomplete Date (Year + Month)

print(wikidate_to_timestamp('+2018-03'))
# Output: 1519862400.0 (March 1, 2018 UTC midnight)

4. Year-Only Date

print(wikidate_to_timestamp('+2018'))
# Output: 1514764800.0 (January 1, 2018 UTC midnight)

Key Improvements

  • Sign Preservation: The leading +/- is retained to correctly parse AD/BC dates, including year 0 (which represents 1 BC).
  • UTC Awareness: We create a timezone-aware datetime, so timestamp() always uses UTC (no local time skew).
  • Incomplete Date Handling: Missing month/day defaults to January 1; missing time defaults to midnight UTC.

Notes

  • Python's datetime supports proleptic Gregorian calendar dates, including year 0 (1 BC) and negative years (BC dates).
  • Timestamp precision: For extremely ancient dates (millions of years ago), floating-point timestamp precision may degrade, but this is negligible for historical dates.

内容的提问来源于stack exchange,提问作者pajamas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 04:27:38