Генерация случайной даты между двумя другими датами - 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 ]

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

Самый простой способ сделать это - преобразовать оба числа в метки времени, а затем установить их как минимальные и максимальные границы в генераторе случайных чисел.

Быстрый пример PHP будет:

// Find a randomDate between $start_date and $end_date
function randomDate($start_date, $end_date)
{
    // Convert to timetamps
    $min = strtotime($start_date);
    $max = strtotime($end_date);

    // Generate random number using above bounds
    $val = rand($min, $max);

    // Convert back to desired date format
    return date('Y-m-d H:i:s', $val);
}

Эта функция использует <a href="http://ie.php.net/strtotime" rel="nofollow noreferrer">strtotime()</a> для преобразования описания даты и времени в метку времени Unix и <a href="http://ie.php.net/date" rel="nofollow noreferrer">date()</a> для создания действительной даты из случайно созданной метки времени.

2 голосов
/ 25 мая 2011

Вот ответ на буквальное значение названия, а не тела этого вопроса:

import time
import datetime
import random

def date_to_timestamp(d) :
  return int(time.mktime(d.timetuple()))

def randomDate(start, end):
  """Get a random date between two dates"""

  stime = date_to_timestamp(start)
  etime = date_to_timestamp(end)

  ptime = stime + random.random() * (etime - stime)

  return datetime.date.fromtimestamp(ptime)

Этот код основан на принятом ответе.

1 голос
/ 22 декабря 2017

Вот решение, измененное на основе подхода Эмиллера, которое возвращает массив случайных дат при любом разрешении

import numpy as np

def random_dates(start, end, size=1, resolution='s'):
    """
    Returns an array of random dates in the interval [start, end]. Valid 
    resolution arguments are numpy date/time units, as documented at: 
        https://docs.scipy.org/doc/numpy-dev/reference/arrays.datetime.html
    """
    start, end = np.datetime64(start), np.datetime64(end)
    delta = (end-start).astype('timedelta64[{}]'.format(resolution))
    delta_mat = np.random.randint(0, delta.astype('int'), size)
    return start + delta_mat.astype('timedelta64[{}]'.format(resolution))

Отчасти этот подход хорош тем, что np.datetime64 действительно хорош в приведении вещей к датам, поэтому вы можете указывать даты начала / окончания в виде строк, дат, временных отметок панд ... практически все будет работать.

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

Зачем вам нужно случайное число? Обычно (в зависимости от языка) вы можете получить количество секунд / миллисекунд от эпохи до даты. Так что для случайной даты между startDate и endDate вы можете сделать:

  1. вычислить время в мс между startDate и endDate (endDate.toMilliseconds () - startDate.toMilliseconds ())
  2. генерирует число от 0 до числа, полученного вами в 1
  3. создать новую дату со смещением времени = startDate.toMilliseconds () + число, полученное в 2
1 голос
/ 16 февраля 2009
  1. Преобразуйте введенные даты в числа (int, float, все, что лучше для ваше использование)
  2. Выберите число между двумя числами даты.
  3. Преобразовать это число обратно в дату.

Многие алгоритмы преобразования даты в числа и из цифр уже доступны во многих операционных системах.

0 голосов
/ 15 декабря 2018
start_timestamp = time.mktime(time.strptime('Jun 1 2010  01:33:00', '%b %d %Y %I:%M:%S'))
end_timestamp = time.mktime(time.strptime('Jun 1 2017  12:33:00', '%b %d %Y %I:%M:%S'))
time.strftime('%b %d %Y %I:%M:%S',time.localtime(randrange(start_timestamp,end_timestamp)))

см.

0 голосов
/ 21 июня 2017

Это модифицированный метод @ (Том Алсберг). Я изменил его, чтобы получить дату с миллисекундами.

import random
import time
import datetime

def random_date(start_time_string, end_time_string, format_string, random_number):
    """
    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.
    """
    dt_start = datetime.datetime.strptime(start_time_string, format_string)
    dt_end = datetime.datetime.strptime(end_time_string, format_string)

    start_time = time.mktime(dt_start.timetuple()) + dt_start.microsecond / 1000000.0
    end_time = time.mktime(dt_end.timetuple()) + dt_end.microsecond / 1000000.0

    random_time = start_time + random_number * (end_time - start_time)

    return datetime.datetime.fromtimestamp(random_time).strftime(format_string)

Пример:

print TestData.TestData.random_date("2000/01/01 00:00:00.000000", "2049/12/31 23:59:59.999999", '%Y/%m/%d %H:%M:%S.%f', random.random())

Выход: 2028/07/08 12:34:49.977963

0 голосов
/ 09 мая 2017

Основываясь на ответе mouviciel, вот векторизованное решение с использованием numpy. Конвертируйте начальную и конечную даты в целые, генерируйте массив случайных чисел между ними и конвертируйте весь массив обратно в даты.

import time
import datetime
import numpy as np

n_rows = 10

start_time = "01/12/2011"
end_time = "05/08/2017"

date2int = lambda s: time.mktime(datetime.datetime.strptime(s,"%d/%m/%Y").timetuple())
int2date = lambda s: datetime.datetime.fromtimestamp(s).strftime('%Y-%m-%d %H:%M:%S')

start_time = date2int(start_time)
end_time = date2int(end_time)

random_ints = np.random.randint(low=start_time, high=end_time, size=(n_rows,1))
random_dates = np.apply_along_axis(int2date, 1, random_ints).reshape(n_rows,1)

print random_dates
0 голосов
/ 05 апреля 2017

Pandas + numpy решение

import pandas as pd
import numpy as np

def RandomTimestamp(start, end):
    dts = (end - start).total_seconds()
    return start + pd.Timedelta(np.random.uniform(0, dts), 's')

dts - это разница между временными метками в секундах (с плавающей точкой). Затем он используется для создания временной шкалы панд между 0 и dts, которая добавляется к начальной отметке времени.

0 голосов
/ 26 марта 2016

Я сделал это для другого проекта, используя случайное время и время. Я использовал общий формат времени, вы можете просмотреть документацию здесь для первого аргумента в strftime (). Вторая часть - это функция random.randrange. Возвращает целое число между аргументами. Измените его на диапазоны, которые соответствуют желаемым строкам. У вас должны быть хорошие аргументы в кортеже второго аругмента.

import time
import random


def get_random_date():
    return strftime("%Y-%m-%d %H:%M:%S",(random.randrange(2000,2016),random.randrange(1,12),
    random.randrange(1,28),random.randrange(1,24),random.randrange(1,60),random.randrange(1,60),random.randrange(1,7),random.randrange(0,366),1))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...