Get the time since a file was last accessed in Python - python

I'm trying to make a script, that takes a folder as input, and deletes files older than one week.
For some reason, my program does not output expected values.
I used:
os.stat('testFile1.txt').st_mtime
os.stat('testFile1.txt').st_atime
I expected atime to return the time the file was last accessed, and mtime last modification, in seconds.
I get a really high number on both, even though I have just opened a file.
Am I doing something wrong? Should I use another method to get the time?

The number you are getting is a timestamp in Unix format. It represents the number of seconds since the start of the year 1970 in UTC (that's why it's so big).
In order to convert it to something more usable, you can use datetime.fromtimestamp():
from datetime import datetime
filename = "testFile1.txt"
file_stat = os.stat(filename)
last_modification = datetime.fromtimestamp(file_stat.st_mtime)
last_access = datetime.fromtimestamp(file_stat.st_atime)
The time you are getting here is not "since the last change". In order to get the amount of time that has passed since a modification or access, you'll need to subtract the modification / access time from the current time:
current_time = datetime.now()
time_since_last_modification = current_time - last_modification
time_since_last_access = current_time - last_access
The code above results in two timedelta objects. In your application, you will need to convert those to days, which is trivial:
days_since_last_modification = time_since_last_modification.days
days_since_last_access = time_since_last_access.days
Whole code
To summarize, this code:
from datetime import datetime
filename = "testFile1.txt"
file_stat = os.stat(filename)
last_modification = datetime.fromtimestamp(file_stat.st_mtime)
last_access = datetime.fromtimestamp(file_stat.st_atime)
current_time = datetime.now()
time_since_last_modification = current_time - last_modification
time_since_last_access = current_time - last_access
days_since_last_modification = time_since_last_modification.days
days_since_last_access = time_since_last_access.days
msg = "{} was modified {} days ago, with last access {} days ago"
msg = msg.format(filename, days_since_last_modification,
days_since_last_access)
print(msg)
Will output something along the lines:
testFile1.txt was modified 4 days ago, last access was 2 days ago

I believe you are not converting epoch time to datetime
From https://docs.python.org/2/library/stat.html
stat.ST_ATIME - Time of last access
time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(os.stat('/tmp/test.txt').st_atime))
>>>'2018-01-15 14:51:23'
stat.ST_MTIME - Time of last modification
time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(os.stat('/tmp/test.txt').st_mtime))
>>>'2018-01-15 14:51:25'
You can even check metadta changes to a file using stat.ST_CTIME

For clarification:
| st_atime
| time of last access
| st_ctime
| time of last change
| st_mtime
| time of last modification
You are getting timestamps. I guess you want it as datetime instead?
From that you can use timedelta to find out how old a datetime is.
import os
import datetime
datetime.datetime.fromtimestamp(os.stat("test").st_mtime)
datetime.datetime.now() - datetime.datetime.fromtimestamp(os.stat("test").st_mtime)
Gives output:
datetime.datetime(2018, 1, 11, 8, 23, 23, 913330)
datetime.timedelta(4, 7252, 17055)
From input data:
drobban#xps:~/Desktop$ ls -lrt test
-rw-rw-r-- 1 drobban drobban 0 jan 11 08:23 test

Related

Subtract Time from Datetime Field in Django/Python

This question seems obvious and easy but I am getting my head stretched out here. Problem is I have datetime field in model and I want to subtract time from another attribute.
here is my code I have tried so far.
#property
def boarding_time(self):
print('---------------------------')
time = self.schedule.travel_date_time.time()
print()
time_added = self.schedule.bus_company_route.routeboardingpoint_set.get(
point=self.boarding_point
).time_added
time1 = timedelta(hours=time.hour, minutes=time.minute, seconds=time.second)
time2 = timedelta(hours=time_added.hour, minutes=time_added.minute, seconds=time_added.second)
return (time1-time2)
I am actually trying to find the time delay the vehicle reaches to certain destination. Suppose vehicle was supposed to move at 8 am but the vehicle departed from bus park at 8:15 am and passenger waiting will have 15 min added to their location but I am getting error as
'datetime.timedelta' object has no attribute 'isoformat'
Im not sure if this answers your question but you can try:
from datetime import datetime, date
datetime.combine(date.today(), exit) - datetime.combine(date.today(), enter)
combine builds a datetime, that can be subtracted. Your can google about it for more...
https://docs.python.org/3/library/datetime.html
At a high level, the adjusted boarding time is derived from taking scheduled boarding time and adding to it the amount of time that lapsed between the scheduled departure time and the actual departure time from the previous destination.
Here is a simplified example that hopefully illustrates the key concepts to help you piece together a solution for your more complex problem:
from datetime import datetime, timedelta
scheduled_boarding_time = datetime.fromisoformat("2021-01-12T10:00")
departure_delay_in_minutes = 15
adjusted_boarding_time = scheduled_boarding_time + timedelta(minutes=delay_in_minutes)
print(adjusted_boarding_time.isoformat())
2021-01-12T10:15:00
The solution to your question lies in the way you handle the time stamp format. You have your date time in AM/PM for this you have to format you date accordingly. Here is something what you can do instead of what you are doing right now
from datetime import datetime
time = '2021/1/13 8:15 am' #your date format
time_added = '2021/1/13 8:45 am' #your date format
format = '%Y/%m/%d %H:%M %p' #will format your date for further computation
time = datetime.strptime(time, format)
time
o/p
datetime.datetime(2021, 1, 13, 8, 15)
time_added = datetime.strptime(time_added, format)
time_added
o/p
datetime.datetime(2021, 1, 13, 8, 45)
time2 = time_added-time1 # this will give you time difference in seconds
divmod(time2.total_seconds(), 60)[0] #use this to get difference in minutes
o/p
30.0
This same you return in your function and it will solve your problem

Python - Calculate last quarter hour of current time

How do I round the time to last quarter hour for the current time. I am able to find the last quarter hour minute, however, not able to fit this into the correct time format.
import datetime
import time
time = datetime.datetime.now()
last_quarter_minute = 15*(time.minute//15)
current_time = time.strftime("%Y/%m/%d %H:%M")
print last_quarter_minute
print current_time
Ideally, I want to be able to compare the time I get from a log, to the last quarter time.
You need to replace minute part of the time, using datetime.datetime.replace (returns a new datetime object with the specifieid field replaced):
>>> time.strftime("%Y/%m/%d %H:%M")
'2016/05/13 12:57'
>>> time.replace(minute=last_quarter_minute).strftime("%Y/%m/%d %H:%M")
'2016/05/13 12:45'
To be more precise, you need to also set second, microsecond also.

Python - difference between time

Looking for easiest way to calculate the difference between 2 python times and display the millisecond delta
I have 2 times
startTime = datetime.datetime.now().time()
do some stuff...
endTime= datetime.datetime.now().time()
This works fine and when I log the times out and I get something like this in my logs...
RequestStartTime = 08:56:19.188999
ResponseTime = 08:56:19.905999
When I try to simply subtract them like this
delta = endTime - startTime
I get the following error
unsupported operand type(s) for -: 'time' and 'time'
All I want to do is show the difference in microseconds and I can't figure it out
I want to show is 717000 ms
If you just use the result of now(), and don't convert them to times, you can take the difference & extract the bits you want in the form you want; for example:
startTime = datetime.datetime.now()
endTime= datetime.datetime.now()
delta = endTime - startTime
print str(delta).split(":")[2]
Try this:
from datetime import datetime, date
datetime.combine(date.today(), endTime) - datetime.combine(date.today(), startTime)
Hope this Helps.
To measure the difference manually, you should use time.monotonic() instead.
If you don't care about leap seconds (~1s error once per year and a half) and you need to display the local time:
#!/usr/bin/env python3
from datetime import datetime, timedelta, timezone
start = datetime.now(timezone.utc).astimezone() # current local time
# print("RequestStartTime = %s" % start.time())
end = datetime.now(timezone.utc).astimezone()
diff_milliseconds = (end - start) / timedelta(milliseconds=1)
print("%.0f ms" % diff_milliseconds)
The code works fine around/during DST transitions.
Note: it is different from the code that uses just .now(). If you use .now() (no argument) then you get a naive datetime object that represents local time and in that case if a DST transition happens between start and end times then end - start returns a completely wrong result i.e., the code may be wrong by an hour approximately couple of times per year in some timezones.
the reason why you are getting an error is because class time does not support subtraction. You must turn time into miliseconds (int format) to subtract from one another.
instead of using datetime, use time
import time
def timenow():
return int(round(time.time() * 1000))
startTime = timenow()
time.sleep(1)
endTime = timenow()
delta = endTime - startTime
print delta
The simplest solution would be to convert the datetime objects to timestamps and subtract those. If you use Python 3.3 or later you can simply do something along these lines
startTime = datetime.datetime.now(timezone.utc).timestamp()
...
endTime = datetime.datetime.now(timezone.utc).timestamp()
Then you can just subtract those.
In Python 2 you do not have the timestamp method available. One way around would be to use a timedelta object:
startTime = datetime.datetime.now(timezone.utc)
...
endTime = datetime.datetime.now(timezone.utc)
dt = (endTime - startTime).total_seconds()
A third option is to simply use raw timestamps with time.time() and subtract them to get the time interval in seconds and fraction of seconds.
To be extra safe you could use time.monotonic() as #Sebastian mentions.
This is the best answer for this problem:
https://stackoverflow.com/a/39651061/2686243
from datetime import datetime, date
duration = datetime.combine(date.min, end) - datetime.combine(date.min, beginning)

How to convert tomorrows (at specific time) date to a timestamp

How can i actually create a timestamp for the next 6 o'clock, whether that's today or tomorrow?
I tried something with datetime.datetime.today() and replace the day with +1 and hour = 6 but i couldnt convert it into a timestamp.
Need your help
To generate a timestamp for tomorrow at 6 AM, you can use something like the following. This creates a datetime object representing the current time, checks to see if the current hour is < 6 o'clock or not, creates a datetime object for the next 6 o'clock (including adding incrementing the day if necessary), and finally converts the datetime object into a timestamp
from datetime import datetime, timedelta
import time
# Get today's datetime
dtnow = datetime.now()
# Create datetime variable for 6 AM
dt6 = None
# If today's hour is < 6 AM
if dtnow.hour < 6:
# Create date object for today's year, month, day at 6 AM
dt6 = datetime(dtnow.year, dtnow.month, dtnow.day, 6, 0, 0, 0)
# If today is past 6 AM, increment date by 1 day
else:
# Get 1 day duration to add
day = timedelta(days=1)
# Generate tomorrow's datetime
tomorrow = dtnow + day
# Create new datetime object using tomorrow's year, month, day at 6 AM
dt6 = datetime(tomorrow.year, tomorrow.month, tomorrow.day, 6, 0, 0, 0)
# Create timestamp from datetime object
timestamp = time.mktime(dt6.timetuple())
print(timestamp)
To get the next 6 o'clock while handling timezones that observe Daylight saving time (DST) correctly:
from datetime import datetime, time, timedelta
import pytz # $ pip install pytz
from tzlocal import get_localzone # $ pip install tzlocal
DAY = timedelta(1)
local_timezone = get_localzone()
now = datetime.now(local_timezone)
naive_dt6 = datetime.combine(now, time(6))
while True:
try:
dt6 = local_timezone.localize(naive_dt6, is_dst=None)
except pytz.NonExistentTimeError: # no such time today
pass
except pytz.AmbiguousTimeError: # DST transition (or similar)
dst = local_timezone.localize(naive_dt6, is_dst=True)
std = local_timezone.localize(naive_dt6, is_dst=False)
if now < min(dst, std):
dt6 = min(dst, std)
break
elif now < max(dst, std):
dt6 = max(dst, std)
break
else:
if now < dt6:
break
naive_dt6 += DAY
Once you have an aware datetime object that represents the next 6 o'clock in the local timezone, it is easy to get the timestamp:
timestamp = dt6.timestamp() # in Python 3.3+
Or on older Python versions:
timestamp = (dt6 - datetime(1970, 1, 1, tzinfo=pytz.utc)).total_seconds()
See Converting datetime.date to UTC timestamp in Python.
The solution works even if any of the following happens:
python (e.g., time.mktime() calls) has no access to a historical timezone database on a given system (notably: Windows)—pytz provides a portable access to the tz database
there is a DST transition between now and the next X hour (where X is 6am in your case) or if the UTC offset for the local timezone has changed for any other reason—"naive datetime object + relativedelta" solution would fail silently to find the correct number of seconds but timezone-aware datetime objects could enable to find the right time difference
the nominal next X hour (today or tomorrow) does not exist or ambiguous in the local time zone (most often, it happens during DST transitions—every year in many timezones). Solutions using dateutil tzinfos or pytz-based solutions that use .localize() without is_dst=None would fail silently. The application should handle NonExistentTimeError and AmbiguousTimeError exceptions explicitly in this case
the current time is after the first time an ambiguous X hour happens in the local timezone but before the second time the X hour happens —"rrule + return min(localize(ndt, is_dst=True), localize(ndt, is_dst=False))" solution would fail silently. The min/max code in the AmbiguousTimeError clause above handles it correctly.

Python - Time delta from string and now()

I have spent some time trying to figure out how to get a time delta between time values. The only issue is that one of the times was stored in a file. So I have one string which is in essence str(datetime.datetime.now()) and datetime.datetime.now().
Specifically, I am having issues getting a delta because one of the objects is a datetime object and the other is a string.
I think the answer is that I need to get the string back in a datetime object for the delta to work.
I have looked at some of the other Stack Overflow questions relating to this including the following:
Python - Date & Time Comparison using timestamps, timedelta
Comparing a time delta in python
Convert string into datetime.time object
Converting string into datetime
Example code is as follows:
f = open('date.txt', 'r+')
line = f.readline()
date = line[:26]
now = datetime.datetime.now()
then = time.strptime(date)
delta = now - then # This does not work
Can anyone tell me where I am going wrong?
For reference, the first 26 characters are acquired from the first line of the file because this is how I am storing time e.g.
f.write(str(datetime.datetime.now())
Which would write the following:
2014-01-05 13:09:42.348000
time.strptime returns a struct_time.
datetime.datetime.now() returns a datetime object.
The two can not be subtracted directly.
Instead of time.strptime you could use datetime.datetime.strptime, which returns a datetime object. Then you could subtract now and then.
For example,
import datetime as DT
now = DT.datetime.now()
then = DT.datetime.strptime('2014-1-2', '%Y-%m-%d')
delta = now - then
print(delta)
# 3 days, 8:17:14.428035
By the way, you need to supply a date format string to time.strptime or DT.datetime.strptime.
time.strptime(date)
should have raised a ValueError.
It looks like your date string is 26 characters long. That might mean you have a date string like 'Fri, 10 Jun 2011 11:04:17 '.
If that is true, you may want to parse it like this:
then = DT.datetime.strptime('Fri, 10 Jun 2011 11:04:17 '.strip(), "%a, %d %b %Y %H:%M:%S")
print(then)
# 2011-06-10 11:04:17
There is a table describing the available directives (like %Y, %m, etc.) here.
Try this:
import time
import datetime
d = datetime.datetime.now()
now = time.mktime(d.timetuple())
And then apply the delta
if you have the year,month,day of 'then' you may use:
year = 2013
month = 1
day = 1
now_date = datetime.datetime.now()
then_date = now_date.replace(year = year, month = month, day = day)
delta = now_date - then_date

Categories

Resources