python - horas - Genera una fecha aleatoria entre otras dos fechas
insertar fechas aleatorias sql (22)
Respuesta actualizada
Es incluso más simple usar Faker .
Instalación
pip install faker
Uso:
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)
Respuesta anterior
Es muy simple usar el radar
Instalación
pip install radar
Uso
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()
¿Cómo generaría una fecha aleatoria que tiene que estar entre otras dos fechas determinadas? La firma de funciones debería ser algo como esto-
randomDate("1/1/2008 1:30 PM", "1/1/2009 4:50 AM", 0.34)
^ ^ ^
date generated has date generated has random number
to be after this to be before this
y devolvería una fecha como "2/4/2008 7:20 PM"
- Convierta sus fechas de entrada a números (int, float, lo que sea mejor para su uso)
- Elige un número entre tus dos números de fecha.
- Convierte este número a una fecha.
Muchos algoritmos para convertir fechas hacia y desde números ya están disponibles en muchos sistemas operativos.
¿Para qué necesitas el número aleatorio? Usualmente (dependiendo del idioma) puede obtener la cantidad de segundos / milisegundos de la Época desde una fecha. Entonces, para una fecha aleatoria entre startDate y endDate podrías hacer:
- calcule el tiempo en ms entre startDate y endDate (endDate.toMilliseconds () - startDate.toMilliseconds ())
- genera un número entre 0 y el número que obtuviste en 1
- generar una nueva fecha con time offset = startDate.toMilliseconds () + number obtenida en 2
Aquí hay una respuesta al significado literal del título en lugar del cuerpo de esta pregunta:
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)
Este código se basa libremente en la respuesta aceptada.
Aquí hay una solución modificada del enfoque de emyller que devuelve una matriz de fechas aleatorias con cualquier resolución
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))
Parte de lo bueno de este enfoque es que np.datetime64
es realmente bueno para np.datetime64
a las cosas a las fechas, por lo que puede especificar sus fechas de inicio / finalización como cadenas, fechas y marcas de tiempo de pandas ... casi cualquier cosa funcionará.
Basado en la respuesta de mouviciel, aquí hay una solución vectorizada usando numpy. Convierta las fechas de inicio y fin en enteros, genere una matriz de números aleatorios entre ellos y convierta toda la matriz a fechas.
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
Como Python 3 timedelta
admite la multiplicación con flotantes, ahora puede hacer lo siguiente:
import random
random_date = start + (end - start) * random.random()
dado que el start
y el end
son del tipo datetime.datetime
. Por ejemplo, para generar una fecha aleatoria dentro del día siguiente:
import random
from datetime import datetime, timedelta
start = datetime.now()
end = start + timedelta(days=1)
random_date = start + (end - start) * random.random()
Conceptualmente es bastante simple. Según el idioma que utilice, podrá convertir esas fechas en un número entero de referencia de 32 o 64 bits, que generalmente representa segundos desde epoch (1 de enero de 1970), también conocido como "tiempo Unix" o milisegundos desde alguna otra fecha arbitraria. Simplemente genere un entero aleatorio de 32 o 64 bits entre esos dos valores. Esto debería ser un trazador de líneas en cualquier idioma.
En algunas plataformas puede generar un tiempo como un doble (la fecha es la parte entera, el tiempo es la parte fraccional es una implementación). Se aplica el mismo principio, excepto que se trata de números de coma flotante de precisión simple o doble ("flotantes" o "dobles" en C, Java y otros idiomas). Reste la diferencia, multiplique por número aleatorio (0 <= r <= 1), agregue a la hora de inicio y termine.
Convierta ambas cadenas en marcas de tiempo (en la resolución elegida, por ejemplo, milisegundos, segundos, horas, días, lo que sea), reste las anteriores de las anteriores, multiplique su número aleatorio (suponiendo que se distribuya en el rango [0, 1]) con ese diferencia, y agregar nuevamente a la anterior. Convierta la marca de fecha y hora en la cadena de fecha y tiene un tiempo aleatorio en ese rango.
Ejemplo de Python (la salida está casi en el formato que usted especificó, aparte de 0 padding - culpe a las convenciones de formato de hora americanas):
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())
En Python:
>>> from dateutil.rrule import rrule, DAILY
>>> import datetime, random
>>> random.choice(
list(
rrule(DAILY,
dtstart=datetime.date(2009,8,21),
until=datetime.date(2010,10,12))
)
)
datetime.datetime(2010, 2, 1, 0, 0)
(necesita la biblioteca de python dateutil
- pip install python-dateutil
)
Es un método modificado de @ (Tom Alsberg). Lo modifiqué para obtener la fecha con milisegundos.
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)
Ejemplo:
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())
Salida: 2028/07/08 12:34:49.977963
Este es un enfoque diferente, ese tipo de obras ...
from random import randint
import datetime
date=datetime.date(randint(2005,2025), randint(1,12),randint(1,28))
WAIITT: MEJOR ENFOQUE
startdate=datetime.date(YYYY,MM,DD)
date=startdate+datetime.timedelta(randint(1,365))
Hice esto para otro proyecto utilizando el azar y el tiempo. Utilicé un formato general desde el momento en que puede ver la documentación here para el primer argumento en strftime (). La segunda parte es una función random.randrange. Devuelve un número entero entre los argumentos. Cámbielo a los rangos que coincidan con las cadenas que desea. Debe tener buenos argumentos en la tupla del segundo arugmento.
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))
La forma más fácil de hacerlo es convertir ambos números a marcas de tiempo, luego establecer estos como los límites mínimo y máximo en un generador de números aleatorios.
Un ejemplo rápido de PHP sería:
// 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);
}
Esta función utiliza strtotime()
para convertir una descripción de fecha y hora en una marca de tiempo de Unix, y date()
para hacer una fecha válida de la marca de tiempo aleatoria que se ha generado.
Pandas + solución 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 es la diferencia entre las marcas de tiempo en segundos (flotante). Luego se usa para crear un panda timedelta entre 0 y dts, que se agrega a la marca de tiempo de inicio.
Para crear una solución basada en pandas, uso:
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
Me gusta, debido a las buenas características pd.Timestamp
que me permiten arrojar diferentes cosas y formatos. Considere los siguientes ejemplos ...
Su firma.
>>> 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)
Posición aleatoria
>>> 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)
Formato diferente.
>>> random_date(''2008-01-01 13:30'', ''2009-01-01 4:50'')
Timestamp(''2008-11-18 17:20:19'', tz=None)
Pasando pandas / objetos datetime directamente.
>>> random_date(pd.datetime.now(), pd.datetime.now() + pd.offsets.Hour(3))
Timestamp(''2014-03-06 14:51:16.035965'', tz=None)
Puedes usar Mixer
,
pip install mixer
y,
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))
Solo para agregar otro:
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'')
El manejo del día necesita algunas consideraciones. Con 28 estás en el sitio seguro.
Una pequeña versión.
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())),
)
Tenga en cuenta que tanto los argumentos de start
como los end
deben ser objetos de datetime
. Si tiene cadenas en su lugar, es bastante fácil de convertir. Las otras respuestas apuntan a algunas maneras de hacerlo.
Utilice ApacheCommonUtils para generar una longitud aleatoria dentro de un rango determinado, y luego cree una fecha fuera de ese largo.
Ejemplo:
import org.apache.commons.math.random.RandomData;
import org.apache.commons.math.random.RandomDataImpl;
public Date nextDate (Date min, Date max) {
RandomData randomData = new RandomDataImpl();
return new Date(randomData.nextLong(min.getTime(), max.getTime()));
}
#!/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()
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)
La precisión es segundos. Puede aumentar la precisión hasta microsegundos o disminuir, por ejemplo, a medias horas, si lo desea. Para eso simplemente cambie el cálculo de las últimas líneas.
Ejemplo de ejecución:
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)
salida:
2008-12-04 01:50:17