I have a problem that seems really easy but I can't figure it out.
I want to achieve the following:
Time_as_string - time_now = minutes left until time as string.
I scrape a time from a website as a string, for example: '15:30'.
I want to subtract the current time from this to show how many minutes
are left untill the scraped time string.
I tried many things like strftime(), converting to unix timestamp, googling solutions etc.
I can make a time object from the string through strftime() but I can't subtract it from the current time.
What is the best way to achieve this?
from datetime import datetime
s = "15:30"
t1 = datetime.strptime(s,"%H:%M")
diff = t1 - datetime.strptime(datetime.now().strftime("%H:%M"),"%H:%M")
print(diff.total_seconds() / 60)
94.0
If '15:30' belongs to today:
#!/usr/bin/env python3
from datetime import datetime, timedelta
now = datetime.now()
then = datetime.combine(now, datetime.strptime('15:30', '%H:%M').time())
minutes = (then - now) // timedelta(minutes=1)
If there could be midnight between now and then i.e., if then is tomorrow; you could consider a negative difference (if then appears to be in the past relative to now) to be an indicator of that:
while then < now:
then += timedelta(days=1)
minutes = (then - now) // timedelta(minutes=1)
On older Python version, (then - now) // timedelta(minutes=1) doesn't work and you could use (then - now).total_seconds() // 60 instead.
The code assumes that the utc offset for the local timezone is the same now and then. See more details on how to find the difference in the presence of different utc offsets in this answer.
The easiest way is probably to subtract two datetimes from each other and use total_seconds():
>>> d1 = datetime.datetime(2000, 1, 1, 20, 00)
>>> d2 = datetime.datetime(2000, 1, 1, 16, 30)
>>> (d1 - d2).total_seconds()
12600.0
Note that this won't work if the times are in different timezones (I just picked January 1, 2000 to make it a datetime). Otherwise, construct two datetimes in the same timezones (or UTC), subtract those and use total_seconds() again to get the difference (time left) in seconds.
Related
I have a user-defined function (return_times) that takes json file and returns two datetime-like strings.
time_1, time_2= return_times("file.json")
print(time_1, time_2) # outputs: 00:00:11.352 00:01:51.936
By datetime-like string I mean 00:00:11.352 which suits '%H:%M:%S.%f' formatting. However, when I try to convert them into milliseconds, I get negative values.
from datetime import datetime
dt_obj_1 = datetime.strptime(time_1, '%H:%M:%S.%f')
start_ms = dt_obj_1.timestamp() * 1000
dt_obj_2 = datetime.strptime(time_2, '%H:%M:%S.%f')
end_ms = dt_obj_2.timestamp() * 1000
print(start_ms, end_ms ) # outputs: -2209019260648.0 -2209019160064.0
If I success I would like to trim a video with the following command:
from moviepy.video.io.ffmpeg_tools import ffmpeg_extract_subclip
ffmpeg_extract_subclip("long_video.mp4", start_ms, end_ms, targetname="video_trimmed.mp4"), so just delete ` * 1000` part.
Note that ffmpeg_extract_subclip requires its t1 and t2 parameters to be in seconds, not in milliseconds as I initially thought.
Because of those negative integers I am not able to successfully run the trimming process.
I searched the web that mainly discusses several formats for the year, month and day, but not '%H:%M:%S.%f'.
What may I be overlooking?
What may I be overlooking?
time.strptime docs
The default values used to fill in any missing data when more accurate
values cannot be inferred are (1900, 1, 1, 0, 0, 0, 0, 1, -1).
whilst start of epoch is 1970. You might get what you want by computing delta between what you parsed and default strptime as follows:
import datetime
time1 = "00:00:11.352"
delta = datetime.datetime.strptime(time1, "%H:%M:%S.%f") - datetime.datetime.strptime("", "")
time_s = delta.total_seconds()
print(time_s)
output
11.352
You need to add the year date (year, month, day) to datetime, else this will default to 1 January 1900.
What you do is this:
from datetime import datetime
s = "00:00:11.352"
f = '%H:%M:%S.%f'
datetime.strptime(s, f) # datetime.datetime(1900, 1, 1, 0, 0, 11, 352000)
One way to do this is to append the date-string to the time-string you receive from return_times
From https://stackoverflow.com/a/59200108/2681662
The year 1900 was before the beginning of the UNIX epoch, which
was in 1970, so the number of seconds returned by timestamp must be
negative.
What to do?
It's better to use a time object instead of a datetime object.
from datetime import time
time_1 = "00:00:11.352"
hours, minutes, seconds = time_1.split(":")
print(time(hour=int(hours), minute=int(minutes), second=int(float(seconds)),
microsecond=int(float(seconds) % 1 * 1000000)))
You can split the time string into hours, minutes, seconds and miliseconds and with some simple math calculations, you get the whole time in miliseconds
from datetime import datetime as dt
I have 2 datetime fields
dt.now() returns 2019-01-08 11:46:26.035303
This is PST
x is my dataset
x['CreatedDate'] returns 2019-01-08T20:35:47.000+0000
dt.strptime(x['CreatedDate'.split('.')[0],'%Y-%m-%dT%H:%M:%S)) - datetime.timedelta(hours=8) returns 2019-01-08 08:43:33
I subtract the two,
tdelta = dt.now() - (dt.strptime(x['CreatedDate'.split('.')[0],'%Y-%m-%dT%H:%M:%S)) - datetime.timedelta(hours=8))
which is 2019-01-08 11:46:26.035303 - 2019-01-08 08:43:33
The difference should be ~3 hours but the result I'm getting is -1 day, 11:02:53.039790
-13H 12M 53S
I'm confused as to what is being returned.
Disclaimer
I am having a tough time making the datetime objects that you made. So, my answer will not be a direct solution to your exact problem.
I dont have x defined in my code. If you supply it, I can adjust my answer to be more specific.
Answer
But if you use this code:
import datetime as dt
first_time = dt.datetime(2019, 1, 8, 8, 43, 33) #This is a good way to make a datetime object
To make your datetime object then this code below will make the correct calculations and print it effectively for you:
second_time = dt.datetime.now()
my_delta = first_time - second_time
print("Minutes: " + str(my_delta.total_seconds()/60))
print("Hours: " + str(my_delta.total_seconds()/3600))
print("Days: " + str(my_delta.total_seconds()/3600/24))
Note
dt.datetime takes (year, month, day, hour, minute, second) here but dt.datetime.now() is making one with microseconds as well (year, month, day, hour, minute, second, microseconds). The function can handle being given different time specificities without error.
Note 2
If you do print(my_delta) and get something like: -1 day, 16:56:54.481901 this will equate to your difference if your difference is Hours: -7.051532805277778 This is because 24-16.95 = -7.05
The issue is with the subtraction of datetime.timedelta(hours=8) I removed that from changed the dt.now to dt.utcnow() and it works fine.
The standard two line element (TLE) format contains times as 2-digit year plus decimal days, so 16012.375 would be January 12, 2016 at 09:00. Using python's time or datatime modules, how can I convert this to seconds after epoch? I think I should use structured time but I am not sure how. seconds_of is a fictitious function - need to replace with something real.
EDIT: It will be most helpful if the answer is long (verbose) - like one step per line or so, so I can understand what is happening.
EDIT 2: After seeing the comments from #J.F.Sebastian I looked at the link for TLE and found it nowhere states "UTC". So I should point out the initial information and final information are UTC. There is no reference to local time, time zone, or system time.
e.g.
tim = "16012.375"
year = 2000 + int(tim[0:2])
decimal_days = float(tim[2:])
print year, decimal_days
2016, 12.375
# seconds_of is a fictitious function - need to replace with something real
seconds_after_epoch = seconds_of(2016,1,1) + (3600. * 24.) * decimal_days
You could try something like this [EDIT according to the comments].
import datetime
import time
# get year 2 digit and floating seconds days
y_d, nbs = "16012.375".split('.')
# parse to datetime (since midnight and add the seconds) %j Day of the year as a zero-padded decimal number.
d = datetime.datetime.strptime(y_d, "%y%j") + datetime.timedelta(seconds=float("." + nbs) * 24 * 60 * 60)
# 1.0 => 1 day
# from time tuple get epoch time.
time.mktime(d.timetuple())
#1481896800.0
It is easy to get datetime object given year and decimal_days:
>>> from datetime import datetime, timedelta
>>> year = 2016
>>> decimal_days = 12.375
>>> datetime(year, 1, 1) + timedelta(decimal_days - 1)
datetime.datetime(2016, 1, 12, 9, 0)
How to convert the datetime object into "seconds since epoch" depends on the timezone (local, utc, etc). See Converting datetime.date to UTC timestamp in Python e.g., if your input is in UTC then it is simple to get "seconds since the Epoch":
>>> utc_time = datetime(2016, 1, 12, 9, 0)
>>> (utc_time - datetime(1970, 1, 1)).total_seconds()
1452589200.0
I want to find time difference between two date and then compare the difference time in hours. Something like this,
StartTime = 2011-03-10 15:45:48
EndTime = 2011-03-10 18:04:00
And then find the difference as,
timeDifference = abs(StartTime - EndTime)
And then I need to compare the results as,
If timeDifference > 6 hours
...
When I use this method, the results I got was is in time format, how should I change time format into hours in python?
Thank you,
Let's assume that you have your two dates and times as datetime objects (see datetime.datetime):
>>> import datetime
>>> start_time = datetime.datetime(2011,3,10,15,45,48)
>>> end_time = datetime.datetime(2011,3,10,18,4,0)
Subtracting one datetime from another gives you a timedelta object, and you can use abs to ensure the time difference is positive:
>>> start_time - end_time
datetime.timedelta(-1, 78108)
>>> abs(start_time - end_time)
datetime.timedelta(0, 8292)
Now, to convert the seconds difference from a timedelta into hours, just divide by 3600:
>>> hours_difference = abs(start_time - end_time).total_seconds() / 3600.0
>>> hours_difference
2.3033333333333332
Note that the total_seconds() method was introduced in Python 2.7, so if you want that on an earlier version, you'll need to calculate it yourself from .days and .seconds as in this answer
Update: Jochen Ritzel points out in a comment below that if it's just the comparison with a number of hours that you're interested in, rather that the raw value, you can do that more easily with:
abs(start_time - end_time) > timedelta(hours=6)
What I am trying to do is to subtract 7 hours from a date. I searched stack overflow and found the answer on how to do it here. I then went to go read the documentation on timedelta because I was unable to understand what that line in the accepted answer does, rewritten here for ease:
from datetime import datetime
dt = datetime.strptime( date, '%Y-%m-%d %H:%M' )
dt_plus_25 = dt + datetime.timedelta( 0, 2*60*60 + 30*60 )
Unfortunately, even after reading the documentation I still do not understand how that line works.
What is the timedelta line doing? How does it work?
Additionally, before I found this stackoverflow post, I was working with time.struct_time tuples. I had a variable tm:
tm = time.strptime(...)
I was simply accessing the hour through tm.tm_hour and subtracting seven from it but this, for obvious reasons, does not work. This is why I am now trying to use datetime. tm now has the value
tm = datetime.strptime(...)
I'm assuming using datetime is the best way to subtract seven hours?
Note: subtracting seven hours because I want to go from UTC to US/Pacific timezone. Is there a built-in way to do this?
What is the timedelta line doing? How does it work?
It creates a timedelta object.
There are two meanings of "time".
"Point in Time" (i.e, date or datetime)
"Duration" or interval or "time delta"
A time delta is an interval, a duration, a span of time. You provided 3 values.
0 days.
2*60*60 + 30*60 seconds.
timedelta() generates an object representing an amount of timeāthe Greek letter delta is used in math to represent "difference". So to compute an addition or a subtraction of an amount of time, you take the starting time and add the change, or delta, that you want.
The specific call you've quoted is for generating the timedelta for 2.5 hours. The first parameter is days, and the second is seconds, so you have (0 days, 2.5 hours), and 2.5 hours in seconds is (2 hours * 60 minutes/hour * 60 seconds/minute) + (30 minutes * 60 seconds / minute).
For your case, you have a negative time delta of 0 days, 7 hours, so you'd write:
timedelta(0, -7 * 60 * 60)
... or timedelta(0, -7 * 3600) or whatever makes it clear to you what you're doing.
Note: subtracting seven hours because I want to go from UTC to US/Pacific timezone. Is there a built-in way to do this?
Yes there is: datetime has built-in timezone conversion capabilities. If you get your datetime object using something like this:
tm = datetime.strptime(date_string, '%Y-%m-%d %H:%M')
it will not have any particular timezone "attached" to it at first, but you can give it a timezone using
tm_utc = tm.replace(tzinfo=pytz.UTC)
Then you can convert it to US/Pacific with
tm_pacific = tm_utc.astimezone(pytz.all_timezones('US/Pacific'))
I'd suggest doing this instead of subtracting seven hours manually because it makes it clear that you're keeping the actual time the same, just converting it to a different timezone, whereas if you manually subtracted seven hours, it looks more like you're actually trying to get a time seven hours in the past. Besides, the timezone conversion properly handles oddities like daylight savings time.
To do this you will need to install the pytz package, which is not included in the Python standard library.