Генерация случайной даты между двумя другими датами - PullRequest
109 голосов
/ 16 февраля 2009

Как бы я сгенерировал случайную дату, которая должна быть между двумя другими данными датами?

Подпись функции должна выглядеть примерно так:

randomDate("1/1/2008 1:30 PM", "1/1/2009 4:50 AM", 0.34)
                  ^                       ^          ^

           date generated has   date generated has a random number
           to be after this     to be before this

и вернет дату, такую ​​как: 2/4/2008 7:20 PM

Ответы [ 23 ]

116 голосов
/ 16 февраля 2009

Преобразуйте обе строки в метки времени (в выбранном вами разрешении, например, в миллисекундах, секундах, часах, днях и т. Д.), Вычтите более раннее из более позднего, умножьте ваше случайное число (при условии, что оно распределено в range [0, 1]) с Разница, и добавьте еще раз к предыдущему. Преобразуйте метку времени обратно в строку даты, и у вас будет случайное время в этом диапазоне.

Пример Python (вывод почти в указанном вами формате, кроме 0 padding - обвинять в соглашениях о американском формате времени):

import random
import time

def strTimeProp(start, end, format, prop):
    """Get a time at a proportion of a range of two formatted times.

    start and end should be strings specifying times formated in the
    given format (strftime-style), giving an interval [start, end].
    prop specifies how a proportion of the interval to be taken after
    start.  The returned time will be in the specified format.
    """

    stime = time.mktime(time.strptime(start, format))
    etime = time.mktime(time.strptime(end, format))

    ptime = stime + prop * (etime - stime)

    return time.strftime(format, time.localtime(ptime))


def randomDate(start, end, prop):
    return strTimeProp(start, end, '%m/%d/%Y %I:%M %p', prop)

print randomDate("1/1/2008 1:30 PM", "1/1/2009 4:50 AM", random.random())
91 голосов
/ 16 февраля 2009
from random import randrange
from datetime import timedelta

def random_date(start, end):
    """
    This function will return a random datetime between two datetime 
    objects.
    """
    delta = end - start
    int_delta = (delta.days * 24 * 60 * 60) + delta.seconds
    random_second = randrange(int_delta)
    return start + timedelta(seconds=random_second)

Точность составляет секунды. Вы можете увеличить точность до микросекунд или, если хотите, уменьшить до, например, получаса. Для этого просто измените расчет последних строк.

пример выполнения:

d1 = datetime.strptime('1/1/2008 1:30 PM', '%m/%d/%Y %I:%M %p')
d2 = datetime.strptime('1/1/2009 4:50 AM', '%m/%d/%Y %I:%M %p')

print random_date(d1, d2)

Выход:

2008-12-04 01:50:17
75 голосов
/ 17 ноября 2011

Крошечная версия.

import datetime
import random


def random_date(start, end):
    """Generate a random datetime between `start` and `end`"""
    return start + datetime.timedelta(
        # Get a random amount of seconds between `start` and `end`
        seconds=random.randint(0, int((end - start).total_seconds())),
    )

Обратите внимание, что аргументы start и end должны быть datetime объектами. Если вместо этого у вас есть строки, их довольно легко конвертировать. Остальные ответы указывают к некоторым способам сделать это.

39 голосов
/ 19 июня 2013

Обновленный ответ

Еще проще, используя Faker .

Установка

pip install faker

Использование:

from faker import Faker
fake = Faker()

fake.date_between(start_date='today', end_date='+30y')
# datetime.date(2025, 3, 12)

fake.date_time_between(start_date='-30y', end_date='now')
# datetime.datetime(2007, 2, 28, 11, 28, 16)

# Or if you need a more specific date boundaries, provide the start 
# and end dates explicitly.
import datetime
start_date = datetime.date(year=2015, month=1, day=1)
fake.date_between(start_date=start_date, end_date='+30y')

Старый ответ

Очень просто использовать радар

Установка

pip install radar

Использование

import datetime

import radar 

# Generate random datetime (parsing dates from str values)
radar.random_datetime(start='2000-05-24', stop='2013-05-24T23:59:59')

# Generate random datetime from datetime.datetime values
radar.random_datetime(
    start = datetime.datetime(year=2000, month=5, day=24),
    stop = datetime.datetime(year=2013, month=5, day=24)
)

# Just render some random datetime. If no range is given, start defaults to 
# 1970-01-01 and stop defaults to datetime.datetime.now()
radar.random_datetime()
17 голосов
/ 29 февраля 2016

Это другой подход - такого рода работы ..

from random import randint
import datetime

date=datetime.date(randint(2005,2025), randint(1,12),randint(1,28))

ЛУЧШИЙ ПОДХОД

startdate=datetime.date(YYYY,MM,DD)
date=startdate+datetime.timedelta(randint(1,365))
11 голосов
/ 08 ноября 2014

Поскольку Python 3 timedelta поддерживает умножение на числа с плавающей точкой, теперь вы можете сделать:

import random
random_date = start + (end - start) * random.random()

, учитывая, что start и end относятся к типу datetime.datetime. Например, чтобы сгенерировать случайное время в течение следующего дня:

import random
from datetime import datetime, timedelta

start = datetime.now()
end = start + timedelta(days=1)
random_date = start + (end - start) * random.random()
6 голосов
/ 06 марта 2014

Для чипа в решении на основе панд я использую:

import pandas as pd
import numpy as np

def random_date(start, end, position=None):
    start, end = pd.Timestamp(start), pd.Timestamp(end)
    delta = (end - start).total_seconds()
    if position is None:
        offset = np.random.uniform(0., delta)
    else:
        offset = position * delta
    offset = pd.offsets.Second(offset)
    t = start + offset
    return t

Мне это нравится, из-за приятных pd.Timestamp функций, которые позволяют мне создавать разные вещи и форматы. Рассмотрим следующие несколько примеров ...

Ваша подпись.

>>> random_date(start="1/1/2008 1:30 PM", end="1/1/2009 4:50 AM", position=0.34)
Timestamp('2008-05-04 21:06:48', tz=None)

Случайная позиция.

>>> random_date(start="1/1/2008 1:30 PM", end="1/1/2009 4:50 AM")
Timestamp('2008-10-21 05:30:10', tz=None)

Другой формат.

>>> random_date('2008-01-01 13:30', '2009-01-01 4:50')
Timestamp('2008-11-18 17:20:19', tz=None)

Передача объектов pandas / datetime.

>>> random_date(pd.datetime.now(), pd.datetime.now() + pd.offsets.Hour(3))
Timestamp('2014-03-06 14:51:16.035965', tz=None)
3 голосов
/ 12 ноября 2014

Вы можете использовать Mixer,

pip install mixer

и

from mixer import generators as gen
print gen.get_datetime(min_datetime=(1900, 1, 1, 0, 0, 0), max_datetime=(2020, 12, 31, 23, 59, 59))
2 голосов
/ 06 марта 2018
#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""Create random datetime object."""

from datetime import datetime
import random


def create_random_datetime(from_date, to_date, rand_type='uniform'):
    """
    Create random date within timeframe.

    Parameters
    ----------
    from_date : datetime object
    to_date : datetime object
    rand_type : {'uniform'}

    Examples
    --------
    >>> random.seed(28041990)
    >>> create_random_datetime(datetime(1990, 4, 28), datetime(2000, 12, 31))
    datetime.datetime(1998, 12, 13, 23, 38, 0, 121628)
    >>> create_random_datetime(datetime(1990, 4, 28), datetime(2000, 12, 31))
    datetime.datetime(2000, 3, 19, 19, 24, 31, 193940)
    """
    delta = to_date - from_date
    if rand_type == 'uniform':
        rand = random.random()
    else:
        raise NotImplementedError('Unknown random mode \'{}\''
                                  .format(rand_type))
    return from_date + rand * delta


if __name__ == '__main__':
    import doctest
    doctest.testmod()
2 голосов
/ 26 июня 2016

Просто чтобы добавить еще один:

datestring = datetime.datetime.strftime(datetime.datetime( \
    random.randint(2000, 2015), \
    random.randint(1, 12), \
    random.randint(1, 28), \
    random.randrange(23), \
    random.randrange(59), \
    random.randrange(59), \
    random.randrange(1000000)), '%Y-%m-%d %H:%M:%S')

Обработка дня требует некоторых соображений. С 28 вы на безопасном сайте.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...