TypeError: unsupported operand type(s) for -: 'datetime.datetime' and 'datetime.date'

Hi People ! I hope that you’re doing good!
I have a question regarding streamlit, because I’m deploying an app in which you can watch meteoroligcal data, and I want to give to the user the estimated time in which the page takes to reload. I wanted to manage this with a datetime.datetime.now() at the begining of the code, an another one at the end of it, and then substracting them. I’ve try this commands before in local files and it worked good, those datetime objects can be substracted normally as far as i know. I don’t know if this is maybe a streamlit bug, or i need to do something else. If this isn’t a streamlit bug or something I want to apologize for posting the question here. Thanks to everyone!

Hi @juliosimonpedro ,

Do you mind sharing your code snippets ?

It will be easy for others to understand the issue and probably come up with a solution at earliest .

Best
Avra

hi!!! Of course! And thanks a lot!

import streamlit as st
from funciones import abrir_stats, plot, abrirtabla, path, abrir_stats
import matplotlib.pyplot as plt
import pandas as pd
import sqlite3
from datetime import datetime, timedelta, date
import numpy as np
import scipy.stats as scipy
import time


t1=datetime.now()

def tiempo(df):
    df["Tiempo Sistema"]=pd.to_datetime(df["Tiempo Sistema"], format="%Y-%m-%d %H:%M:%S")
    df.drop_duplicates(subset="Tiempo Sistema", inplace=True)
    df.sort_values(by="Tiempo Sistema", ascending=True, inplace=True)
    df.set_index("Tiempo Sistema", inplace=True)


    return df
def rain(df):
    rain=df[df["Rain Rate"]>0]
    # print("Mean: {} , min: {}, max: {}".format(rain["Rain Rate"].mean(), rain["Rain Rate"].min(),rain["Rain Rate"].max()))
    rain_mean=rain[rain["Rain Rate"]>rain["Rain Rate"].mean()]
    return 
def ciclo_anom(df):
    df["Hora-Min"]=df.index.strftime("%H:%M")
    df["Mes"]=df.index.month

    cd=df.groupby(["Mes","Hora-Min"]).mean()
    std=df.groupby(["Mes","Hora-Min"]).std()
    for i in std.columns:
        std.rename({i:"std "+i},axis=1,inplace=True)
    name={}
    for i in cd.columns:
        name[i]="CD "+i
        cd.rename(name, axis=1, inplace=True)
    cd=pd.merge(cd,std,how="inner",left_index=True,right_index=True)
    minut=np.arange(0,60,1)
    cd.reset_index(inplace=True)
    cd["Minutes"]=pd.to_datetime(cd["Hora-Min"], format="%H:%M").dt.minute
    vhora=cd["Hora-Min"][cd["Minutes"].isin(minut)].drop_duplicates().array
    vhora=np.append(vhora,["23:59"])
    cd.drop(["Minutes"],axis=1, inplace=True)

    df.reset_index(inplace=True)
    merge=pd.merge(df,cd, how="left", left_on=["Mes", "Hora-Min"], right_on=["Mes","Hora-Min"]).drop_duplicates(subset="Tiempo Sistema")
    merge.set_index("Tiempo Sistema", inplace=True)
    df.set_index("Tiempo Sistema", inplace=True)

    v=["Barometer","Outside Humidity", "Outside Temperature", "Solar Radiation", "Wind Speed", "Rain Rate"]

    for i in v:
        merge["Anomally "+i]=merge[i]-merge["CD "+i]
        merge["Lim inf "+i]=merge[i]-merge["std "+i]
        merge["Lim sup "+i]=merge[i]+merge["std "+i]


    return merge

#Caja para escoger la estación en la página que se desea revisar
estacion=st.sidebar.selectbox("Escoja la estación", ["Oriente", "Turbo"])


#Fechas y tiempos en los cuales el usuario quiere la información
t1=st.sidebar.date_input("Fecha Inicial", date.today()-timedelta(days=1))
t2=st.sidebar.date_input("Fecha Final", date.today())
tim1=st.sidebar.time_input("Ingrese Tiempo Inicial", datetime.strptime("00:00", "%H:%M").time())
tim2=st.sidebar.time_input("Ingrese Tiempo Final", datetime.strptime("23:59", "%H:%M").time())

#Combinar fecha y hora
dat1=(str(t1)+" "+str(tim1))
dat2=(str(t2)+" "+str(tim2))


#Abrir la tabla de la Database con las fechas según la estación que se escoja 
if estacion=="Oriente":
    est_escog=abrirtabla(path+"/meteoro-oriente.db", "DatosMeteoro",dat1,dat2)
    est_escog=tiempo(est_escog)
    anom=abrir_stats(path+"/meteoro-oriente.db",est_escog.index.month.drop_duplicates().array)
elif estacion=="Turbo":
    est_escog=abrirtabla(path+"/turbodb.db", "2019_2021",dat1,dat2)
    est_escog=tiempo(est_escog)
    anom=abrir_stats(path+"/turbodb.db",est_escog.index.month.drop_duplicates().array)



#Calcular el ciclo diurno de las variables en el rango escogido, como se ve arriba (Función)
cd_rango=ciclo_anom(est_escog)

# Containers create on horixontal, and columns en vertical
header  = st.container()

#Definir tírulo de la página
with header:
    st.title("Página para ver gráfica de lluvia")

md="""Esta página está diseñada por ahora para comparar las variables Temperatura, Humedad Relativa y Presión 
con eventos de precipitación :rain_cloud: en las diferentes estaciones

"""
#Print el texto llamado md
st.markdown(md)

#Comando para no tener conflicto al mostrar la gŕafica
st.set_option('deprecation.showPyplotGlobalUse', False)


#Comando para graficar las variables en el rango de tiempo escogido
st.pyplot(plot(dat1,dat2,est_escog,"Rain Rate","Outside Temperature","Outside Humidity",
    "Barometer"))


md="""

A continuación se ven las anomalías de las variables de la base de datos. 

"""

st.markdown(md)

est_escog["Mes"]=est_escog.index.month
est_escog["Hora-Min"]=est_escog.index.strftime("%H:%M")

st.dataframe(est_escog)
est_escog.reset_index(inplace=True)

anomalias=pd.merge(est_escog,anom,left_on=["Mes", "Hora-Min"], right_on=["Mes", "Hora-Min"], how="left")
anomalias.set_index("Tiempo Sistema", inplace=True)
variables=["Outside Temperature","Outside Humidity","Barometer"]

for i in variables:
    anomalias["Anomally "+i]=anomalias[i]-anomalias["mean "+i]



est_escog.set_index("Tiempo Sistema", inplace=True)
st.dataframe(anomalias)

#Graficar las anomalías en el rango escogido
st.pyplot(plot(dat1,dat2,anomalias,"Rain Rate","Anomally Outside Temperature","Anomally Outside Humidity",
    "Anomally Barometer"))



var=st.selectbox("Escoja la variable sobre la cual quiere visualizar el ciclo diurno del rango de fechas escogido",["Outside Temperature","Barometer", "Outside Humidity"])

# st.dataframe(anom[estacion])

def plot_ciclo_diurno(df,variable):
    if variable[0]=="B":
        color="black"
    elif variable=="Outside Temperature":
        color="Firebrick"
    else:
        color="forestgreen"
    fig,ax=plt.subplots(figsize=(20,10))
    
    l=[]
    for i in df["Hora-Min"].drop_duplicates().sort_values().values:
        if i[-2:]=="00" or i[-2:]=="30":
            l.append(i)

    plt.plot(df["Hora-Min"].drop_duplicates().sort_values(),df.drop_duplicates(subset="Hora-Min").sort_values(by="Hora-Min")[variable],color=color,linewidth=1.5)
    plt.fill_between(df["Hora-Min"].drop_duplicates().sort_values(),df.drop_duplicates(subset="Hora-Min").sort_values(by="Hora-Min")["Lim inf "+variable],
    df.drop_duplicates(subset="Hora-Min").sort_values(by="Hora-Min")["Lim sup "+variable],color=color,alpha=0.2)
    plt.xticks(l,rotation=45)
    ax.set_ylabel(variable, size=16)
    plt.grid(alpha=0.6)
    plt.xlim(["00:00","23:59"])
    ax.yaxis.label.set_color(color)
    


st.pyplot(plot_ciclo_diurno(cd_rango,var))

t2=datetime.now()
t3=t2-t1
st.markdown(f"La página se demoró haciendo la consulta: {t3}")

hey @juliosimonpedro ,

Thanks for updating with your code.

Unfortunately, I couldn’t reproduce your case with these snippet of code. Possibly some part is missing .

However, if I understood you correctly, you aim to filter the dates between two date ranges, right ?

Best
Avra

@juliosimonpedro you have variable name collisions.

t1=datetime.now()
...
t1=st.sidebar.date_input("Fecha Inicial", date.today()-timedelta(days=1))
...
t2=datetime.now()

suggest you refactor your code

I am able to deploy this script successfully

import streamlit as st

from datetime import datetime
import time

def do_work(time_spent=5):
    time.sleep(time_spent)

time_spent = st.number_input("time")
t1 = datetime.now()
# t1 = time.time()
do_work(int(time_spent))
t2 = datetime.now()
# t2 = time.time()
st.write(f"{t2-t1}")
2 Likes

OHH!!! DUMB MEEE jejejeje thanks a lot!

Hey Avraa thanks for replying!

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.