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

Pandas中欧/哥本哈根时区转UTC出现重复值的解决方案问询

问题:哥本哈根时区时间转UTC出现重复值

我有一个Pandas DataFrame,需要将其中的datetime列从Europe/Copenhagen时区转换为UTC,但转换后的UTC列始终出现重复值。问题出在2024-10-27的转换中,UTC列出现了重复的2024-10-27 01:00,而非正确时间。

问题背景:

  • 输入数据包含Date(起始时间为00:00)、position、resolution、ID和quantity列
  • 单ID下每日对应23-25个position,resolution为小时级
  • 通过函数将Date、resolution和position计算为带时区的datetime再转UTC,但遇到夏令时切换(2024-10-27哥本哈根从CEST切换到CET,时钟回拨1小时)时出现重复UTC值

复现代码如下:

import pytz
import pandas as pd
import numpy as np
from datetime import datetime, timedelta

# Set up date range from 25th October 2024 to 28th October 2024
date_range = pd.date_range(start="2024-10-25", end="2024-10-28", freq="D")

# Initialize an empty list to collect data
data = []

# Populate data for each date
for date in date_range:
    # Set number of positions based on date
    if date == datetime(2024, 10, 27):
        positions = range(1, 26)  # 25 positions on 27th October
    else:
        positions = range(1, 25)  # 24 positions on other dates
    
    # Generate data entries for each position
    for pos in positions:
        data.append({
            "Date": date,
            "position": pos,
            "ID": "A",
            "quantity": np.random.randint(1, 100),
            "resolution": 'PT1H'
        })

# Create DataFrame
df = pd.DataFrame(data)

copenhagen_tz = pytz.timezone('Europe/Copenhagen')
df['Date'] = pd.to_datetime(df['Date'],utc=False)

# Define a dictionary to map resolution text to timedelta values
resolution_map = {
    'PT1H': timedelta(hours=1),
    'PT30M': timedelta(minutes=30),
    'PT15M': timedelta(minutes=15),
    'PT5M': timedelta(minutes=5)
}

# Calculate the exact datetime by applying the resolution offset
def calculate_exact_date(row):
    base_time = row['Date']
    offset = (row['position'] - 1) * resolution_map[row['resolution']]
    # Handle DST ambiguity by using `ambiguous=True` to interpret ambiguous times consistently
    exact_date = base_time + offset

    return copenhagen_tz.normalize(exact_date)

# Convert 'Date' to datetime in UTC, then localize to Europe/Copenhagen
df['Date'] = pd.to_datetime(df['Date']).dt.tz_localize('CET')

df['Date_Local'] = df.apply(calculate_exact_date, axis=1)
df['Date_UTC'] = pd.to_datetime(df['Date_Local']).dt.tz_convert('UTC') 

解决方案

问题根源是2024-10-27欧洲夏令时切换:哥本哈根当地时间从02:00回拨到01:00,导致两个本地时间(01:00 CEST和01:00 CET)对应同一个UTC时间(01:00 UTC)。但你的数据中27日有25个position,对应25小时的偏移,实际需要覆盖切换后的完整时间区间,正确的做法是直接基于本地时区的基准时间计算,明确处理夏令时切换的歧义。

以下是修改后的代码,无需修改输入数据格式:

import pytz
import pandas as pd
import numpy as np
from datetime import datetime, timedelta

# 生成数据部分保持不变
date_range = pd.date_range(start="2024-10-25", end="2024-10-28", freq="D")
data = []
for date in date_range:
    if date == datetime(2024, 10, 27):
        positions = range(1, 26)
    else:
        positions = range(1, 25)
    for pos in positions:
        data.append({
            "Date": date,
            "position": pos,
            "ID": "A",
            "quantity": np.random.randint(1, 100),
            "resolution": 'PT1H'
        })
df = pd.DataFrame(data)

copenhagen_tz = pytz.timezone('Europe/Copenhagen')
df['Date'] = pd.to_datetime(df['Date'])

resolution_map = {
    'PT1H': timedelta(hours=1),
    'PT30M': timedelta(minutes=30),
    'PT15M': timedelta(minutes=15),
    'PT5M': timedelta(minutes=5)
}

def calculate_exact_date(row):
    # 先将基准日期转为哥本哈根时区的00:00,自动处理夏令时
    base_local = copenhagen_tz.localize(row['Date'], is_dst=None)
    offset = (row['position'] - 1) * resolution_map[row['resolution']]
    # 在本地时区上叠加偏移,normalize自动处理DST切换的时间调整
    exact_local = copenhagen_tz.normalize(base_local + offset)
    return exact_local

# 计算本地时间并转换为UTC
df['Date_Local'] = df.apply(calculate_exact_date, axis=1)
df['Date_UTC'] = df['Date_Local'].dt.tz_convert('UTC')

修改说明:

  • 正确本地化基准时间:不再硬编码CET时区,而是用copenhagen_tz.localize()让pytz自动识别日期对应的时区(夏令时/冬令时),避免时区缩写的局限性。
  • 自动处理歧义时间:copenhagen_tz.normalize()会在夏令时回拨时,将重复的本地时间(如01:00)自动映射为切换后的冬令时时间,确保每个本地时间对应唯一的UTC时间。
  • 简化转换逻辑:直接使用已带时区的Date_Local列转换UTC,无需重复调用pd.to_datetime()。

验证结果:

修改后,2024-10-27的Date_UTC列将包含从2024-10-26 23:00:00+00:00到2024-10-27 23:00:00+00:00的25个唯一UTC时间,不再出现重复值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 20:11:01