Ali
Ali

Reputation: 3

generate random dates with days and time in python

hey guys i was trying to create a code that generate dates in given range but i faced some problems the code is as follows:

import datetime
import random
import os
from random import randrange
year_b = 2019 
month_b = 1
day_b = 1
year_e = 2020 
month_e = 1 
day_e = 1 

 def date_range(start, end, step: datetime.timedelta):
     while start < end:
        yield start
        start += step


rand_list=[5,8,6,9,10]


for d in date_range(
    start=datetime.datetime(year_b, month_b, day_b),
    end=datetime.datetime(year_e, month_e, day_e),
    step=datetime.timedelta(days=rand.choice(rand_list)),
    ):
    print(d)

os.system("pause")

output:

2019-01-01 00:00:00
2019-01-09 00:00:00
2019-01-17 00:00:00
2019-01-25 00:00:00
2019-02-02 00:00:00
Press any key to continue . . . 

first problem that the code only select one random value from the list and add it to the date but i need it to select random value for each date generated

second problem is that code the time it not been generated randomly

any ideas to solve those problems???!!

Upvotes: 0

Views: 1027

Answers (3)

Ali
Ali

Reputation: 3

now not all the months are showing:

  from datetime import datetime, timedelta
  import random
  samples = 10

 start = datetime(2018, 1, 1)
 end = datetime(2020, 1, 1)

 def items(start, end, samples):
     total_sec = int((end - start).total_seconds())
     deltas = random.sample(range(total_sec), samples)  # xrange if py2k!
     return (start + timedelta(seconds=delta) for delta in sorted(deltas))


 for _ in list(items(start, end, samples)):
     print(_)

output:

2018-02-01 18:25:48
2018-02-20 20:24:23
2018-06-07 22:03:48
2018-07-20 07:15:37
2018-08-22 07:04:06
2018-08-28 18:02:07
2018-10-09 03:40:58
2019-01-04 15:11:40
2019-03-22 12:16:58
2019-07-22 14:44:00

Upvotes: 0

Cireo
Cireo

Reputation: 4427

"Random" is often poorly defined. Why not select a specific number of samples uniformly from the distribution?

from datetime import datetime, timedelta

def items(start, end, samples):
    total_sec = int((end - start).total_seconds())
    deltas = random.sample(range(total_sec), samples)  # xrange if py2k!
    return (start + timedelta(seconds=delta) for delta in sorted(deltas))

Then you have

samples = 10
start = datetime(2019, 1, 1)
end = datetime(2020, 1, 1)
print(list(items(start, end, samples)))

giving, e.g.:

[datetime.datetime(2019, 1, 12, 16, 40, 53),
 datetime.datetime(2019, 2, 1, 1, 41, 45),
 datetime.datetime(2019, 2, 25, 10, 29, 51),
 datetime.datetime(2019, 3, 10, 10, 24, 48),
 datetime.datetime(2019, 4, 3, 12, 46, 14),
 datetime.datetime(2019, 8, 12, 18, 30, 57),
 datetime.datetime(2019, 9, 11, 3, 59, 6),
 datetime.datetime(2019, 9, 27, 3, 9, 36),
 datetime.datetime(2019, 10, 13, 14, 23, 37),
 datetime.datetime(2019, 12, 14, 12, 23, 5)]

From this base you can easily modify to various other distributions, or use days or microseconds, or allow duplicates.

After reading your question more closely, I'm not entirely convinced this answer is what you're looking for, but I'll leave it up in case it is helpful.

Upvotes: 1

modesitt
modesitt

Reputation: 7210

The problem is because randrange(10) evaluates as soon as it is called. You can instead make date_range take a callable that returns a "random" time delta (or a variable delta, or whatever you'd like).

def adjustable_date_range(start, end, random_delta_maker):
     while start < end:
        yield start
        start += random_delta_maker

And use it like so in your example by passing a callable that makes a random time delta on [0-10) days:

for d in adjustable_date_range(
    start=datetime.datetime(year_b, month_b, day_b),
    end=datetime.datetime(year_e, month_e, day_e),
    step=lambda: datetime.timedelta(days=randrange(10)),
):
    print(d)

Upvotes: 0

Related Questions