Find the difference between two dates/times - python

I generate and insert a time and date into my SQLite3 database in Python with the following command:
connection.execute("INSERT INTO ActiveTable (IDPK, time) VALUES (NULL, datetime('now', 'localtime'))")
The time is stored into the database in an INTEGER field with the format:
2016-07-18 08:58:48
I think that the value is actually stored as a TEXT since Sqlite3 works with type affinity, INTEGER is just left over code that I will probably change.
My goal is to query my database to get this value from a SELECT operation, and then find the difference compared to the current time using python's native time and date modules. My final goal is to have time difference from original insert to now represented similarly to this:
2d:1h:5m
To be inserted into the Database in a new field called TimeDiff.
Is this possible using time, date, or datetime in python? I'm having trouble with the syntax for these modules.

from datetime import datetime
day1 = datetime.strptime("2016-07-18 08:58:48","%Y-%m-%d %H:%M:%S")
day2 = datetime.strptime("2016-02-18 07:58:48","%Y-%m-%d %H:%M:%S")
print(day1 -day2)
Output:
151 days, 1:00:00

Related

Storing a TimeDelta in my SQL Server database

Table Tasks has 2 datetime columns, StartDate and EndDate. I used python to calculate the difference between these two, resulting in column Time_Difference. See below:
Tasks['Time_Difference'] = Tasks['EndDate'] - Tasks['StartDate']
Avg_Task_Duration = Tasks['Time_Difference'].mean()
Now, I want to store the Avg_Task_Duration value in a Stats table from my SQL Server. It is of type timedelta and looks like this: Timedelta('438 days 09:25:10')
Therefore, I have the following questions:
Is it possible to store a timedelta in my SQL Server? If yes, what data type should the column have?
If not, is there any other alternative?
Unfortunately, SQL Server does not support the ISO SQL standard interval type. You could use time for intervals less than 24 hours but need to store the value in integer units (e.g. seconds) to store longer periods.

questions about using pymongo to insert date and time into mongo

I want to insert date and time into mongo ,using pymongo.
However, I can insert datetime but not just date or time .
here is the example code :
now = datetime.datetime.now()
log_date = now.date()
log_time = now.time()
self.logs['test'].insert({'log_date_time': now, 'log_date':log_date, 'log_time':log_time})
it show errors :
bson.errors.InvalidDocument: Cannot encode object: datetime.time(9, 12, 39, 535769)
in fact , i don't know how to insert just date or time in mongo shell too.
i know insert datetime is new Date(), but I just want the date or time filed.
You are experiencing the defined behavior. MongoDB has a single datetime type (datetime). There are no separate, discrete types of just date or just time.
Workarounds: Plenty, but food for thought:
Storing just date is straightforward: assume Z time, use a time component of 00:00:00, and ignore the time offset upon retrieval.
Storing just time is trickier but doable: establish a base date like the epoch and only vary the time component, and ignore the date component upon retrieval.

Python SQLite, passing date values in sql query

I have having a problem with inserting date values into an SQL query. I am using sqlite3 and python. The query is:
c.execute("""SELECT tweeterHash.* FROM tweeterHash, tweetDates WHERE
Date(tweetDates.start) > Date(?) AND
Date(tweetDates.end) > Date(?)""",
(start,end,))
The query doesn't return any values, and there is no error message. If I use this query:
c.execute("""SELECT tweeterHash.* FROM tweeterHash, tweetDates WHERE
Date(tweetDates.start) > Date(2014-01-01) AND
Date(tweetDates.end) > Date(2015-01-01)""")
Then I get the values that I want, which is as expected?
The values start and end come from a text file:
f = open('dates.txt','r')
start = f.readline().strip('\n')
end = f.readline().strip('\n')
but I have also just tried declaring it as well:
start = '2014-01-01'
end = '2015-01-01'
I guess I don't understand why passing the string in from the start and end variables doesn't work? What is the best way to pass a date variable into a SQL query? Any help is greatly appreciated.
These aren't the same dates—and it's the non-parameterized ones you've got wrong.
Date(2014-01-01) calculates the arithmetic expression 2014 - 01 - 01, then constructs a Date from the resulting number 2012, which will get you something in 4707 BC.
Date('2014-01-01'), or Date(?) where the parameter is the string '2014-01-01', constructs the date you want, in 2014 AD.
You can see this more easily by just selecting dates directly:
>>> cur.execute('SELECT Date(2014-01-01), Date(?)', ['2014-01-01'])
>>> print(cur.fetchone())
('-4707-05-28', '2014-01-01')
Meanwhile:
What is the best way to pass a date variable into a SQL query?
Ideally, use actual date objects instead of strings. The sqlite3 library knows how to handle datetime.datetime and datetime.date. And don't call Date on the values, just compare them. (Yes, sqlite3 might then compare them as strings instead of dates, but the whole point of using ISO8601-like formats is that this always gives the same result… unless of course you have a bunch of dates from 4707 BC lying around.) So:
start = datetime.date(2014, 1, 1)
end = datetime.date(2015, 1, 1)
c.execute("""SELECT tweeterHash.* FROM tweeterHash, tweetDates WHERE
tweetDates.start > ? AND
tweetDates.end > ?""",
(start,end,))
And would this also mean that when I create the table, I would want: " start datetime, end datetime, "?
That would work, but I wouldn't do that. Python will convert date objects to ISO8601-format strings, but not convert back on SELECT, and SQLite will let you transparently compare those strings to the values returned by the Date function.
You could get the same effect with TEXT, but I believe you'd find it less confusing, DATETIME will set the column affinity to NUMERIC, which can confuse both humans and other tools when you're actually storing strings.
Or you could use the type DATE—which is just as meaningless to SQLite as DATETIME, but it can tell Python to transparently convert return values into datetime.date objects. See Default adapters and converters in the sqlite3 docs.
Also, if you haven't read Datatypes in SQLite Version 3 and SQLite and Python types, you really should; there are a lot of things that are both surprising (even—or maybe especially—if you've used other databases), and potentially very useful.
Meanwhile, if you think you're getting the "right" results from passing Date(2014-01-01) around, that means you've actually got a bunch of garbage values in your database. And there's no way to fix them, because the mistake isn't reversible. (After all, 2014-01-01 and 2015-01-02 are both 2012…) Hopefully you either don't need the old data, or can regenerate it. Otherwise, you'll need some kind of workaround that lets you deal with existing data as usefully as possible under the circumstances.

Insert Python datetime to Oracle column of type DATE

I am trying to store a Python datetime object in an ORACLE column of type date.
so far, I have used,
rpt_time = time.strftime('%Y-%m-%d %H:%M:%S') or
rpt_time = str(datetime.datetime.now())
but all are giving ORA-01843: not a valid month
I am really confused how to insert ORACLE date type python datetime object
cx_Oracle supports passing objects of class datetime.datetime. Because of this when you already have object of this class (for example when calling datetime.datetime.now()) you should not try to format it and pass as a string but instead pass it directly. This way you prevent all errors caused by wrong format of date and/or time.
Example:
cursor.execute("INSERT INTO SomeTable VALUES(:now)", {'now': datetime.datetime.now()})
Be aware that you have to take additional steps if you want to prevent truncation of fractional part of seconds. For details please read Mastering Oracle+Python, Part 2: Working with Times and Dates article by Przemysław Piotrowski.
As far as my search shows, ORACLE can be picky on dates so this might be what you need to do.
Firstly, check the format of date you have. For example, if you have something like, 2010/01/26:11:00:00AM, then you might want to do following on your cursor execute:
insert into x
values(99, to_date('2010/01/26:11:00:00AM', 'yyyy/mm/dd:hh:mi:ssam'));
You have to convert date from python to oracle by setting nls_date_format in you session
>>> rpt_time = time.strftime('%Y-%m-%d %H:%M:%S')
>>> rpt_time
'2014-05-12 21:06:40'
Then before inserting into oracle, do the following
cursor.execute("ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS'")
datetime.now() in python gives you milliseconds and have to get rid of it before sucessfully writing to Oracle.
from datetime import datetime
....
cursor.execute("INSERT INTO myTable VALUES(to_date('" + str(datetime.now().replace(microsecond=0)) + "','yyyy-mm-dd hh24:mi:ss'))")
....

Handling dates prior to 1970 in a repeatable way in MySQL and Python

In my MySQL database I have dates going back to the mid 1700s which I need to convert somehow to ints in a format similar to Unix time. The value of the int isn't important, so long as I can take a date from either my database or from user input and generate the same int. I need to use MySQL to generate the int on the database side, and python to transform the date from the user.
Normally, the UNIX_TIMESTAMP function, would accomplish this in MySQL, but for dates before 1970, it always returns zero.
The TO_DAYS MySQL function, also could work, but I can't take a date from user input and use Python to create the same values as this function creates in MySQL.
So basically, I need a function like UNIX_TIMESTAMP that works in MySQL and Python for dates between 1700-01-01 and 2100-01-01.
Put another way, this MySQL pseudo-code:
select 1700_UNIX_TIME(date) from table;
Must equal this Python code:
1700_UNIX_TIME(date)
I don't have MySQL here installed, but when I look here: http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html#function_to-days - I see an example TO_DAYS('2008-10-07') returning 733687.
The following Python function returns datetime(2008,10,7).toordinal() = 733322, which is 365 less than the MySQL's output.
So take this:
from datetime import datetime
query = '2008-10-07'
nbOfDays = datetime.strptime(query, '%Y-%m-%d').toordinal() + 365
and it should work for dates between 1700 and 2100.
According to the link that you gave,
Given a date date, returns a day number (the number of days since year 0).
mysql> SELECT TO_DAYS(950501);
-> 728779
mysql> SELECT TO_DAYS('2007-10-07');
-> 733321
Corresponding numbers in Python:
>>> import datetime
>>> datetime.date(1995,5,1).toordinal()
728414
>>> datetime.date(2007,10,7).toordinal()
732956
So the relationship is : mySQL_int == Python_int + 365 and you can convert in the other direction by using the fromordinal class method:
>>> datetime.date.fromordinal(728779 - 365)
datetime.date(1995, 5, 1)

Categories