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

调用Oura API获取combined_df时出现时间格式不匹配错误求助

Python调用Oura Ring数据时日期格式不匹配问题排查

问题现象

使用OuraClientDataFrame调用Oura Ring数据时,readiness_df(start='2018-11-01')能正常返回数据,无日期相关问题;但调用combined_df_edited(start='2018-11-01')触发时间格式不匹配错误,报错信息如下:

Traceback (most recent call last):
  File "c:\Users\stefa\OneDrive\Coding\Oura\test.py", line 22, in <module>
    combined_df = client.combined_df_edited(start=start)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\stefa\AppData\Local\Programs\Python\Python311\Lib\site-packages\oura\client_pandas.py", line 198, in combined_df_edited
    sleep_df = self.sleep_df(start, end, metrics)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\stefa\AppData\Local\Programs\Python\Python311\Lib\site-packages\oura\client_pandas.py", line 104, in sleep_df
    return SleepConverter(convert_cols).convert_metrics(df)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\stefa\AppData\Local\Programs\Python\Python311\Lib\site-packages\oura\converters.py", line 119, in convert_metrics
    df = super().convert_metrics(df)
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\stefa\AppData\Local\Programs\Python\Python311\Lib\site-packages\oura\converters.py", line 86, in convert_metrics
    df = self._convert_to_dt(df, dt_metrics)
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\stefa\AppData\Local\Programs\Python\Python311\Lib\site-packages\oura\converters.py", line 57, in _convert_to_dt
    df[dt_metric] = pd.to_datetime(df[dt_metric], format="%Y-%m-%d %H:%M:%S")
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\stefa\AppData\Local\Programs\Python\Python311\Lib\site-packages\pandas\core\tools\datetimes.py", line 1050, in to_datetime
    values = convert_listlike(arg._values, format)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\stefa\AppData\Local\Programs\Python\Python311\Lib\site-packages\pandas\core\tools\datetimes.py", line 453, in _convert_listlike_datetimes
    return _array_strptime_with_fallback(arg, name, utc, format, exact, errors)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\stefa\AppData\Local\Programs\Python\Python311\Lib\site-packages\pandas\core\tools\datetimes.py", line 484, in _array_strptime_with_fallback
    result, timezones = array_strptime(arg, fmt, exact=exact, errors=errors, utc=utc)
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "pandas\_libs\tslibs\strptime.pyx", line 530, in pandas._libs.tslibs.strptime.array_strptime
  File "pandas\_libs\tslibs\strptime.pyx", line 351, in pandas._libs.tslibs.strptime.array_strptime
ValueError: time data "2018-11-15T08:02:30+01:00" doesn't match format "%Y-%m-%d %H:%M:%S", at position 0. You might want to try:
    - passing `format` if your strings have a consistent format;
    - passing `format='ISO8601'` if your strings are all ISO8601 but not necessarily in exactly the same format;
    - passing `format='mixed'`, and the format will be inferred for each element individually. You might want to use `dayfirst` alongside this.

用户使用的代码如下:

import pandas as pd
from datetime import date, timedelta
from oura import OuraClientDataFrame
from api_token import API_TOKEN

oura_token = API_TOKEN # Your Oura token
client = OuraClientDataFrame(personal_access_token=oura_token) # Make connection

# Check you the connection is working and you have access to your account
who_am_i_df = client.user_info_df()
print(who_am_i_df)

start = '2018-11-01'
days = 7
week_past = str(date.today() - timedelta(days))
#######

# Pull readiness data and combined features into separate dataframes
# Start is set to beginning of 01-NOV-2018 -> earliest available months for me
readiness_df = client.readiness_df(start=start)
print(readiness_df.head())
combined_df = client.combined_df_edited(start=start)

注:这段代码在Spyder环境中可正常运行,仅当前环境报错。

问题根源

问题出在oura库的converters.py文件中,第57行硬编码了时间转换格式为"%Y-%m-%d %H:%M:%S",但Oura API返回的时间是带时区的ISO8601格式(如2018-11-15T08:02:30+01:00),两者格式不匹配导致报错。

Spyder能正常运行的原因是:Spyder环境中的pandas版本较低,旧版本pd.to_datetime会自动兼容格式;而当前环境使用的新版本pandas对格式校验更严格,必须完全匹配指定格式才会执行转换。

解决办法

1. 修改库源码(临时快速解决)

找到本地Python环境中oura库的converters.py文件,路径为C:\Users\stefa\AppData\Local\Programs\Python\Python311\Lib\site-packages\oura\converters.py,定位到第57行:

df[dt_metric] = pd.to_datetime(df[dt_metric], format="%Y-%m-%d %H:%M:%S")

将其修改为以下两种方式之一:

  • 指定ISO8601格式:
    df[dt_metric] = pd.to_datetime(df[dt_metric], format="ISO8601")
    
  • 去掉format参数,让pandas自动推断格式:
    df[dt_metric] = pd.to_datetime(df[dt_metric])
    

2. 自定义数据转换(更稳妥,不修改库文件)

绕过库自带的转换逻辑,手动处理时间列:

# 获取未转换的原始睡眠数据
sleep_raw = client.sleep_df(start=start, convert=False)
# 手动转换所有时间列(根据实际列名调整,比如bedtime_start、bedtime_end等)
time_columns = ['bedtime_start', 'bedtime_end']
for col in time_columns:
    sleep_raw[col] = pd.to_datetime(sleep_raw[col])

# 同理处理其他数据类型
activity_raw = client.activity_df(start=start, convert=False)
for col in ['day_start', 'day_end']:
    activity_raw[col] = pd.to_datetime(activity_raw[col])

readiness_raw = client.readiness_df(start=start, convert=False)
for col in ['day_start', 'day_end']:
    readiness_raw[col] = pd.to_datetime(readiness_raw[col])

# 合并数据(参考库中combined_df_edited的逻辑)
combined_df = pd.merge(sleep_raw, activity_raw, on='summary_date', how='outer')
combined_df = pd.merge(combined_df, readiness_raw, on='summary_date', how='outer')

3. 降级pandas版本

如果不想修改代码或库文件,可降级到旧版pandas,让它自动兼容格式:

pip install pandas==1.5.3

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 07:27:56