I have 2 variables: datetime.date and datetime.datetime
import sqlite3
from datetime import date
#bot.message_handler(commands=['check'])
def start_message(message):
cursor = conn.execute("SELECT * from DATA WHERE id = ? ORDER BY DATE ", (message.from_user.id,))
row = cursor.fetchone() #datetime.datetime
datee = date.today() #datetime.date
print(datee - parse(row[2]).date())
bot.send_message(message.chat.id, row[1])
bot.send_message(message.chat.id, str(datee - parse(row[2])))
print is displaying -1 day, 0:00:00, but I need to take out the timestamp. How can I do it?
If you only want to print the days (without the hours,minutes,seconds), you can use the attribute.days, e.g.:
print((datee - parse(row[2]).date()).days)
this works because what you receive is not a date object anymore but a datetime.timedelta object.
Related
I am trying to do a patch on a weather report database. I need to manually change each rows of a date column like so: by changing the date format to this new format: .
Bear in mind that this table and its attributes was made without any conditions. So, int/str/bools/any may as well be in any of these rows and it should work.
This new format was carried out by this script, a for loop which simply extracts the old database values and returns variables containing the formatted string.
connection = sqlite3.connect('\\.db\\')
cursor = connection.cursor()
ROWID = cursor.execute('SELECT ROWID FROM update_test').fetchall()
Date = cursor.execute('SELECT Date FROM update_test').fetchall()
for row, dates in zip(ROWID, Date): # tuple
for i, x in zip(row, dates): # strings
try:
weekdays = r'^...'
regex = r'...-[\d\d]{1,}-Jan'
new_year = re.findall(regex, x)
for match in new_year:
updated_dates = f'{"2022"}{re.sub(weekdays, "", match)}'
date_object = datetime.datetime.strptime(updated_dates, '%Y-%d-%b').strftime('%Y-%m-%d')
print(i, date_object)
# update('test.db', 'update_test', 'date', date_object, i) # I want this bit to work
except TypeError:
pass
Now, I would normally just pass these variables into an INSERT function such as this:
def update(url, table, setVar, setVal, setID):
try:
connection = sqlite3.connect(url)
cursor = connection.cursor()
try:
cursor.execute(f'UPDATE {table} SET {setVar} = {setVal} WHERE ROWID = {setID}')
connection.commit()
except sqlite3.Error as error:
print(f'Error: \n {error}')
...
cursor.execute("SELECT name "
"FROM sqlite_master "
"WHERE type='table'")
... logging
... logging
... logging
... logging
... logging
connection.close()
... logging
except pandas.io.sql.DatabaseError:
...logging
But a really weird thing happens where it would only update the year of the formatted string like so:
Additionally, often, when used in a for loop, this year would increment -= 1 year. So: 2019, 2018, 2017 ... for each row specified in the update function.
My ideal output would be that dates would change into the new format I had initializing in that for loop (first script preview) and only those rows which specified (which already works anyway).
update('test.db', 'update_test', 'date', date_object, i) # I want this bit to work
The problem is that you are doing your own substitutions into the SQL. You will end up with:
UPDATE table SET setVar = 2022-03-01 WHERE ROWID = xxx
Sqlite sees that as an arithmetic expression. 2022 minus 3 minus 1 is 2018.
The short-term fix is to quote the value:
cursor.execute(f'UPDATE {table} SET {setVar} = "{setVal}" WHERE ROWID = {setID}')
A better fix is to let the connector do the substitution:
cursor.execute(f'UPDATE {table} SET {setVar} = ? WHERE ROWID = ?', (setVal, setID))
FOLLOWUP
As a side note, your regular expressions are totally unnecessary here.
connection = sqlite3.connect('\\.db\\')
cursor = connection.cursor()
rowset = cursor.execute('SELECT ROWID,Date FROM update_test')
for rowid,date in rowset:
parts = date.split('-')
if parts[2] == 'Jan':
parts[0] = '2022'
updated_dates = '-'.join(parts)
date_object = datetime.datetime.strptime(updated_dates, '%Y-%d-%b').strftime('%Y-%m-%d')
print(rowid, date_object)
I have the following code that requires the user to input a date in format 2021/12/31. It then calculates the difference between date entered and today.
date = input('Enter your date: ')
delta = datetime.strptime(date, '%Y/%m/%d') - datetime.now()
print("difference is {} days".format(delta.days))
I would like for a 0 to be displayed if the wrong date format is entered but can't quite figure it out, I assume I need if / else like my attempt below but it's not quite working as it returns 0 no matter what.
date = input('Enter your date: ')
if date == '%Y/%m/%d':
delta = datetime.strptime(date, '%Y/%m/%d') - datetime.now()
print("difference is {} days".format(delta.days))
else:
print('0')
You can use the datetime to check if the format is right like:
try:
....datetime.datetime.strptime("99/99/99","%m/%d/%y")
except ValueError as err:
....print(err)
You can check the date format like this:
from datetime import datetime
date = str(input('Enter your date: '))
print(date)
format = "%Y-%m-%d"
try:
delta = datetime.now() - datetime.strptime(date, format)
print("difference is {} days".format(delta.days))
except ValueError as err:
print(err)
Error when using timedelta from datetime.now() in SQL Server where clause
python 3.6
yesterday = datetime.now() - timedelta(days=1)
sql = "SELECT submit_dt, api_job_name, job_status, xml_record_count, x_successful_number, x_failed_number, " \
f"job_run_time, mf_job_name FROM JOB_LOG where submit_dt > {yesterday}"
try:
db = Database()
db.cursor.execute(sql)
rows = db.cursor.fetchall()
SQL ODBC Error: Incorrect syntax near '22' --- which is the time part of the datetime.
I've tried wrapping it in '' but then get convert from string error.
Consider parameterizing your query without any need of string conversion of datetime or string interpolation including F-strings.
yesterday = datetime.now() - timedelta(days=1)
sql = """SELECT submit_dt, api_job_name, job_status, xml_record_count,
x_successful_number, x_failed_number,
job_run_time, mf_job_name
FROM JOB_LOG
WHERE submit_dt > ?"""
try:
db = Database()
db.cursor.execute(sql, yesterday)
rows = db.cursor.fetchall()
The error was due to including the microseconds in the compare value. I was able to use:
yesterday_sql = yesterday.strftime("%Y-%m-$d %H:%M:%S")
I have a problem with my code python, i'm using Pandasql, and what i want is to use my (enddate) in a query so:
enddate = pd.to_datetime(datetime.today()).date()
q2 = """SELECT * FROM res_q1 t1 where t1.JOURS = (enddate) """
res_q2 = psql.sqldf(q2, locals())
Can you help me plz!!!
You can add it with formatting, e.g.
from datetime import datetime
end_date = pd.to_datetime(datetime.today()).date()
q2 = """SELECT * FROM res_q1 t1 where t1.JOURS = ({}) """.format(end_date)
res_q2 = psql.sqldf(q2, locals())
Hope this helps :)
I want to see if the user booked date is in between two other datetimes objects inside database .
I have two different times in my table start_time and end_time, so the start_time means when the booking begins and the end_time means when it will end, here is the code:
def parse_time(time):
tdateime = str(time)
date = parse(tdateime)
return date
start = '2017-08-23 11:00:00'
end = '2017-08-23 11:50:00'
p1 = parse_time(start)
p2 = parse_time(end)
p3 = 'the date to be checked'
check_is_free = Appointment.query.filter(Appointment.start_time == p1).filter(Appointment.end_time == p2).first()
original_start_date = check_is_free.start_time
original_end_date = check_is_free.end_time
if check_is_free:
if original_start_date <= p3 <= check_is_free.end_time:
error = 'already reserved.'
return jsonify({'occupied':error})
The end here is the service time period , for instance, the appointment starts at 11:00 and the service is 50 minutes by time, timedelta will add this 50 minutes to start time , so the final result will be 11:50 and this period of time must be busy and you can't make a book between this period.
If the user want to book for a service for example today at '11:30:00' it should give him the error message which is already reserved, but how can i get the third date ??, in fact , i am using bootstrap-datepicker to choose the datetime where i have just one field to choose the start date and time.
I've tried to make a few changes by parsing the start time and to put it value in variable p3, but here it will ignore all the code above and the appointment will be accepted since p3 is the same as start, if the start time matches in check_is_free it will give me the booked service and here the error will raise, but if i changed the start time by just one minute the check_is_free will return a None , thats mean the appointment will be accepted which i won't .
Could you just filter to find if any Appointments overlap with the user's desired appointment window? I mean something like:
# User's desired appointment window is start_time to end_time
# an appointment is not overlapping, if
# - the end_time is before an existing start time, or
# - the start_time is after an existing end time
overlapping = session.query(Appointment).filter(
not_(
or_(Appointment.start_time > end_time,
Appointment.end_time < start_time)))
Here's a complete working example which you can try out:
from datetime import datetime, timedelta
from sqlalchemy import create_engine, Column, DateTime, Integer
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from sqlalchemy.sql import or_, not_
engine = create_engine('sqlite:///:memory:')
Session = sessionmaker(bind=engine)
Base = declarative_base()
class Appointment(Base):
__tablename__ = 'appointments'
id = Column(Integer, primary_key=True)
start_time = Column(DateTime, nullable=False)
end_time = Column(DateTime, nullable=False)
Base.metadata.create_all(engine)
session = Session()
existing_appointment = Appointment(id=1,
start_time=datetime(2017,8,23,11,0),
end_time=datetime(2017,8,23,11,50))
session.add(existing_appointment)
session.commit()
def check_appointment(start_time):
end_time = start_time + timedelta(minutes=20)
overlapping = session.query(Appointment).filter(
not_(
or_(Appointment.start_time > end_time,
Appointment.end_time < start_time)))
return not overlapping.count()
print('check 2017-08-23 11:30 (should be False): {}'.format(check_appointment(datetime(2017,8,23,11,30))))
print('check 2017-08-23 10:30 (should be True): {}'.format(check_appointment(datetime(2017,8,23,10,30))))