I'm trying to generate random list of 24hr timestamps. I can generate one sample of date and time between the set range using the code below. I'm hoping to generate multiple samples (e.g. 10 samples)
Also, the date component isn't a priority for me. If i could drop that and just generate random 24hr timestamps that would be good.
Most threads I've found only consider generate random dates. I can find anything that concerns time.
import random
import time
from datetime import datetime
def randomDate(start, end):
frmt = '%d-%m-%Y %H:%M:%S'
stime = time.mktime(time.strptime(start, frmt))
etime = time.mktime(time.strptime(end, frmt))
ptime = stime + random.random() * (etime - stime)
dt = datetime.fromtimestamp(time.mktime(time.localtime(ptime)))
return dt
random_datetime = randomDate("20-01-2018 13:30:00", "23-01-2018 04:50:34")
print(random_datetime)
Output:
2018-01-21 03:33:55
The whole point of the datetime library: datetime, timedelta, etc. objects act as much like numbers as possible, so you can just do arithmetic on them.
So, to generate a uniform distribution over a day, just take a uniform distribution from 0.0 to 1.0, and multiply it by a day:1
td = random.random() * datetime.timedelta(days=1)
To generate a uniform random time on some particular day, just add that to midnight on that day:
dt = datetime.datetime(2018, 5, 1) + random.random() * datetime.timedelta(days=1)
To generate a random timestamp between two timestamps:
dt = random.random() * (end - start) + start
And if you want 10 of those:
[random.random() * (end - start) + start for _ in range(10)]
That's all there is to it. Stay away from all those other time formats from the time module; they're only needed if you need compatibility with stuff like C libraries and filesystem data. Just use datetime in the first place:
def randomtimes(stime, etime, n):
frmt = '%d-%m-%Y %H:%M:%S'
stime = datetime.datetime.strptime(start, frmt)
etime = datetime.datetime.strptime(end, frmt)
td = etime - stime
return [random.random() * td + stime for _ in range(n)]
1. However, keep in mind that if you're dealing with local rather than UTC times, some days are actually 23 or 25 hours long, because of Daylight Saving Time. A timedelta doesn't understand that.
Depending on your needs, it might be well worth the trouble to learn the Python datetime and time modules. If your code will do lots of different manipulations, then go with #abarnert's answer. If all you need is a time string (rather than a Python timestamp), this function will crank it out for you:
import random
def randomTime():
# generate random number scaled to number of seconds in a day
# (24*60*60) = 86,400
rtime = int(random.random()*86400)
hours = int(rtime/3600)
minutes = int((rtime - hours*3600)/60)
seconds = rtime - hours*3600 - minutes*60
time_string = '%02d:%02d:%02d' % (hours, minutes, seconds)
return time_string
for i in range(10):
print(randomTime())
this outputs:
19:07:31
16:32:00
02:01:30
20:31:21
20:20:26
09:49:12
19:38:42
10:49:32
13:13:36
15:02:54
But if you don't want 24 hour time, then you can intercept the 'hours' variable before you stuff it in into the string:
import random
def randomTime():
# generate random number scaled to number of seconds in a day
# (24*60*60) = 86,400
rtime = int(random.random()*86400)
hours = int(rtime/3600)
minutes = int((rtime - hours*3600)/60)
seconds = rtime - hours*3600 - minutes*60
# figure out AM or PM
if hours >= 12:
suffix = 'PM'
if hours > 12:
hours = hours - 12
else:
suffix = 'AM'
time_string = '%02d:%02d:%02d' % (hours, minutes, seconds)
time_string += ' ' + suffix
return time_string
for i in range(10):
print(randomTime())
which gives :
05:11:45 PM
02:28:44 PM
08:09:19 PM
02:52:30 PM
07:40:02 PM
03:55:16 PM
03:48:44 AM
12:35:43 PM
01:32:51 PM
07:54:26 PM
In case you need continuous times:
from datetime import datetime,timedelta
time_starter = datetime.strptime("12:00:00","%H:%M:%S")
for i in range(1,10):
time = time_starter + timedelta(hours=i)
time = time.strftime("%H:%M:%S")
print(time)
if you need random or continuous minutes use:
time = time_starter + timedelta(minutes=i) #continuous
time = time_starter + timedelta(minutes=randint(0,60)) #random
import random
import time
from datetime import datetime
dates = []
def randomDate(start, end):
frmt = '%d-%m-%Y %H:%M:%S'
stime = time.mktime(time.strptime(start, frmt))
etime = time.mktime(time.strptime(end, frmt))
ptime = stime + random.random() * (etime - stime)
dt = datetime.fromtimestamp(time.mktime(time.localtime(ptime)))
return dt
for i in range(0 , 10)
dates.append(randomDate("20-01-2018 13:30:00", "23-01-2018 04:50:34"))
Your dates will have a list of 10 sample date :)
Good Luck
Related
I'm trying to make a program that tells me how long there is (in minutes) until a certain time of day in the future. I've been trying to write working code all night, but I just can't wrap my head around strftime, timedelta and datetime. I'm quite new to python, and being able to do this would be quite useful to my day-to-day life; Can someone help me out?
from datetime import datetime
def minutes_until(hour, minute):
#get the current time
now = datetime.now()
#get the current hour
current_hour = now.hour
#get the current minute
current_minute = now.minute
#get the current second
current_second = now.second
#get the current microsecond
current_microsecond = now.microsecond
#get the time until the specified hour
time_until_hour = hour - current_hour
#get the time until the specified minute
time_until_minute = minute - current_minute
#get the time until the specified second
time_until_second = 60 - current_second
#get the time until the specified microsecond
time_until_microsecond = 1000000 - current_microsecond
#get the total time until the specified time
total_time = time_until_hour * 3600 + time_until_minute * 60 + time_until_second + time_until_microsecond / 1000000
#get the total time in minutes
total_time_in_minutes = total_time / 60
#return the total time in minutes
return total_time_in_minutes
print(minutes_until(15, 0)) #time now is 2 PM, how long until 15:00 (3PM)? = 60 minutes
You can try:
from datetime import datetime
target = '2023-01-01 00:00:00'
t = datetime.strptime(target, '%Y-%m-%d %H:%M:%S')
now = datetime.now()
print(f'{(t-now).total_seconds()/60:.0f} minutes')
output: 104445 minutes
I have a time representation as string in the format:
9:00 am
8:45 pm
e.g., 12-hour, no leading hour 0, am/pm suffix
I need to get the time difference in minutes between then and now.
The time is always in the future, so if it's 09:00 right now, 9:10 am is in 10 mins time and 8:50 am is in 23h, 50m.
I've been playing with strptime but I can't seem to work out how to get my parsed time and now() in a compatible format to do arithmetic on.
something like this, indeed with strptime:
from datetime import datetime
timeString1 = "9:00 am"
timeString2 = "8:45 pm"
format = '%I:%M %p'
datetime1 = datetime.strptime(timeString1, format)
datetime2 = datetime.strptime(timeString2, format)
minutes_diff = (datetime2 - datetime1).total_seconds() / 60.0
print(f"the time difference in minutes is: {minutes_diff}")
this is a variant using datetime.
the format string FMT = "%I:%M %p" is selected according to strptime#time.strftime. and as only datetime objects support differences, i use those only (using datetime.combine).
from datetime import datetime, timedelta
FMT = "%I:%M %p"
TODAY_DATE = datetime.today().date()
def to_datetime(t_str):
return datetime.combine(TODAY_DATE, datetime.strptime(t_str, FMT).time())
NOW = to_datetime("9:00 am")
for t_str in ("9:10 am", "8:45 pm"):
t = to_datetime(t_str)
if t < NOW:
t += timedelta(days=1)
print(f"{t_str}, {(t - NOW)}, {(t - NOW).total_seconds() / 60:.0f} min")
it outputs:
9:10 am, 0:10:00, 10 min
8:45 pm, 11:45:00, 705 min
There are most likely better suited modules for that. But quick and dirty you could do:
def to_minutes(time_str)
time, suffix = time_str.split(" ")
hours, min = time.split(":")
if suffix == "pm":
hours+=12
min = hours*60+min
return min
time1 = to_minuntes("9:00 am")
time2 = to_minutes("8:45 pm")
diff = time2-time1
if diff < 0:
diff+= 24*60
# and if necessary you can do a
hours = diff //60
minutes = diff % 60
if hours > 0:
final_diff = f"{hours}h {minutes}min"
else:
final_diff = f"{minutes}min"
I am trying to get get the time delta i minutes from two different time values.
time1 = 2020-11-28T10:31:12Z
time2 = 2020-11-28T09:10:23.203+0000
Then i will make i condition: if time difference is bigger then x minutes, run code...
Anyone have a solution for that.
I have tried using datetime.datetime.strptime() but cant get them on same format.
Thanks
Using date parser to let it figure out the date format
Code
from dateutil.parser import parse
def time_difference(time1, time2):
# Parse strings into datetime objects
dt1 = parse(time1)
dt2 = parse(time2)
# Get timedelta object
c = dt1 - dt2
# Difference in minutes
return (c.total_seconds()/60)
Test
time1 = "2020-11-28T10:31:12Z"
time2 = "2020-11-28T09:10:23.203+0000"
print(time_difference(time1, time2))
# Output: 80.81328333333333
well assuming you don't need split seconds you could do something like that:
time1 = '2020-11-28T10:31:12Z'
time2 = '2020-11-28T09:10:23.203+0000'
import time
import datetime
def get_timestamp(time_str):
time_splited = time_str.split('T')
time_str_formatted = ' '.join([time_splited[0],time_splited[1][:8]])
return time.mktime(datetime.datetime.strptime(time_str_formatted,"%Y-%m-%d %H:%M:%S").timetuple())
print(get_timestamp(time1))
print(get_timestamp(time2))
reformatting both times to the same time format.
then your condition would look like:
if abs(get_timestamp(time1) -get_timestamp(time2) ) > x*60:
do_something(....)
The times are not uniform so you will have to make them the same to use strptime. For accuracy I prefer to convert to seconds then you can also at a later stage compare seconds, minutes or hours if you needed to.
import datetime
time1 = '2020-11-28T10:31:12Z'
time2 = '2020-11-28T09:10:23.203+0000'
def minutes_diff():
#Make the times uniform so you can then use strptime
date_time1 = datetime.datetime.strptime(time1[:-1], "%Y-%m-%dT%H:%M:%S")
date_time2 = datetime.datetime.strptime(time2[:-9], "%Y-%m-%dT%H:%M:%S")
#Convert to seconds for accuracy
a_timedelta = date_time1 - datetime.datetime(1900, 1, 1)
b_timedelta = date_time2 - datetime.datetime(1900, 1, 1)
seconds_time_a = a_timedelta.total_seconds()
seconds_time_b = b_timedelta.total_seconds()
#Take one from each other for minutes
time_in_minutes = (seconds_time_a - seconds_time_b) / 60
#Then decide what to do with it
if time_in_minutes < 60: # 1 hour
print('Less than an hours do something')
else:
print('More than an hour do nothing')
minutes_diff()
DARRYL, JOHNNY and MARCIN, thanks for your solutions, problem solved!!
Andy
I'm trying to get my head around the datetime module. I know the time now as an epoch and the time an event last happened (as an epoch time). What I need to do is figure out whether that event happened between midnight and midnight of yesterday.
t = time.time() # is now
t2 = 1234567890 # some arbitrary time from my log
24 hours ago is t - 86400, but how can I round that up and down to midnight. I'm having real trouble finding a way to get timestamps in and out of datetime or then manipulating a datetime to set the time.
In the Middle of the Night
Generating the last midnight is easy:
from datetime import datetime, time
midnight = datetime.combine(datetime.today(), time.min)
That combines today's date (you can use date() or a datetime() instance, your pick), together with time.min to form a datetime object at midnight.
Yesterday
With a timedelta() you can calculate the previous midnight:
from datetime import timedelta
yesterday_midnight = midnight - timedelta(days=1)
That Was Yesterday
Now test if your timestamp is in between these two points:
timestamp = datetime.fromtimestamp(some_timestamp_from_your_log)
if yesterday_midnight <= timestamp < midnight:
# this happened between 00:00:00 and 23:59:59 yesterday
All Together Now
Combined into one function:
from datetime import datetime, time, timedelta
def is_yesterday(timestamp):
midnight = datetime.combine(datetime.today(), time.min)
yesterday_midnight = midnight - timedelta(days=1)
return yesterday_midnight <= timestamp < midnight:
if is_yesterday(datetime.fromtimestamp(some_timestamp_from_your_log)):
# ...
Midnight at the start of today is:
midnight = (int(time.time() // 86400)) * 86400
so yesterday's midnight is:
midnight = (int(time.time() // 86400)) * 86400 - 86400
Given such a timestamp, you can use divmod to compute the number of days since the epoch (which you don't care about), and how many seconds are leftover (which you do):
days_since, remaining_seconds = divmod(t, 24*3600) # Divide by number of seconds in one day
Then, you subtract the leftover seconds from your original timestamp, which produces midnight
of the current day.
t -= remaining_seconds
Rounding up is as simple as shifting your target timestamp forward exactly one day before rounding down.
tomorrow_t = t + 24 * 3600
days_since, remaining_seconds = divmod(tomorrow_t, 24*3600)
t = tomorrow_t - remaining_seconds
To get the specific timezone's midnight timestamp:
from datetime import datetime
import pytz
TZ = "Asia/Shanghai"
datetime.now(pytz.timezone(TZ)).replace(hour=0, minute=0, second=0, microsecond=0).timestamp()
In my estimation, many date and time manipulations are easier to do, and to understand, using the arrow library. This is one of them.
Create an arbitrary date and time.
>>> import arrow
>>> arbitrary = arrow.get(2017,8,16,11,5)
Calculate midnight_yesterday: first, midnight of arbitrary as its 'day' floor; then shift this back by one day. Display the result.
>>> midnight_yesterday = arbitrary.floor('day').shift(days=-1)
>>> midnight_yesterday
<Arrow [2017-08-15T00:00:00+00:00]>
Use timestamp for the desired overall result, for Python 3.3+.
>>> midnight_yesterday.datetime.timestamp()
1502755200.0
Or use this expression for Python 2.7. (Credit: https://stackoverflow.com/a/11743262/131187 for the latter two expressions.)
>>> (midnight_yesterday-arrow.get(1970,1,1)).total_seconds()
1502755200.0
You can use this code:
import time
seconds_of_day = 24 * 60 * 60 # 86400
last_midnight = (round(time.time()) // seconds_of_day) * seconds_of_day
yesterday_last_midnight = last_midnight - seconds_of_day
import time
start_str = time.strftime( "%m/%d/%Y" ) + " 00:00:00"
end_str = time.strftime( "%m/%d/%Y ") + " 23:59:59"
start_ts = int( time.mktime( time.strptime( start_str, "%m/%d/%Y %H:%M:%S" ) ) )
end_ts = int( time.mktime( time.strptime( end_str, "%m/%d/%Y %H:%M:%S" ) ) )
print (start_ts) # timestamp today at 00:00:00
print (end_ts) # timestamp today at 23:59:59
# 1552435200
# 1552521599
Source Python get unix epoch for today’s midnight and today’s 23:59:59 (start of day, end of day)
There has to be an easier way to do this. I have objects that want to be refreshed every so often, so I want to record when they were created, check against the current timestamp, and refresh as necessary.
datetime.datetime has proven to be difficult, and I don't want to dive into the ctime library. Is there anything easier for this sort of thing?
if you want to compute differences between two known dates, use total_seconds like this:
import datetime as dt
a = dt.datetime(2013,12,30,23,59,59)
b = dt.datetime(2013,12,31,23,59,59)
(b-a).total_seconds()
86400.0
#note that seconds doesn't give you what you want:
(b-a).seconds
0
import time
current = time.time()
...job...
end = time.time()
diff = end - current
would that work for you?
>>> from datetime import datetime
>>> a = datetime.now()
# wait a bit
>>> b = datetime.now()
>>> d = b - a # yields a timedelta object
>>> d.seconds
7
(7 will be whatever amount of time you waited a bit above)
I find datetime.datetime to be fairly useful, so if there's a complicated or awkward scenario that you've encountered, please let us know.
EDIT: Thanks to #WoLpH for pointing out that one is not always necessarily looking to refresh so frequently that the datetimes will be close together. By accounting for the days in the delta, you can handle longer timestamp discrepancies:
>>> a = datetime(2010, 12, 5)
>>> b = datetime(2010, 12, 7)
>>> d = b - a
>>> d.seconds
0
>>> d.days
2
>>> d.seconds + d.days * 86400
172800
We have function total_seconds() with Python 2.7
Please see below code for python 2.6
import datetime
import time
def diffdates(d1, d2):
#Date format: %Y-%m-%d %H:%M:%S
return (time.mktime(time.strptime(d2,"%Y-%m-%d %H:%M:%S")) -
time.mktime(time.strptime(d1, "%Y-%m-%d %H:%M:%S")))
d1 = datetime.now()
d2 = datetime.now() + timedelta(days=1)
diff = diffdates(d1, d2)
Here's the one that is working for me.
from datetime import datetime
date_format = "%H:%M:%S"
# You could also pass datetime.time object in this part and convert it to string.
time_start = str('09:00:00')
time_end = str('18:00:00')
# Then get the difference here.
diff = datetime.strptime(time_end, date_format) - datetime.strptime(time_start, date_format)
# Get the time in hours i.e. 9.60, 8.5
result = diff.seconds / 3600;
Hope this helps!
Another approach is to use timestamp values:
end_time.timestamp() - start_time.timestamp()
By reading the source code, I came to a conclusion: the time difference cannot be obtained by .seconds:
#property
def seconds(self):
"""seconds"""
return self._seconds
# in the `__new__`, you can find the `seconds` is modulo by the total number of seconds in a day
def __new__(cls, days=0, seconds=0, microseconds=0,
milliseconds=0, minutes=0, hours=0, weeks=0):
seconds += minutes*60 + hours*3600
# ...
if isinstance(microseconds, float):
microseconds = round(microseconds + usdouble)
seconds, microseconds = divmod(microseconds, 1000000)
# ! 👇
days, seconds = divmod(seconds, 24*3600)
d += days
s += seconds
else:
microseconds = int(microseconds)
seconds, microseconds = divmod(microseconds, 1000000)
# ! 👇
days, seconds = divmod(seconds, 24*3600)
d += days
s += seconds
microseconds = round(microseconds + usdouble)
# ...
total_seconds can get an accurate difference between the two times
def total_seconds(self):
"""Total seconds in the duration."""
return ((self.days * 86400 + self.seconds) * 10**6 +
self.microseconds) / 10**6
in conclusion:
from datetime import datetime
dt1 = datetime.now()
dt2 = datetime.now()
print((dt2 - dt1).total_seconds())