Wie würde ich ein zufälliges Datum generieren, das zwischen zwei anderen angegebenen Daten liegen muss?
Die Signatur der Funktion sollte etwa so aussehen:
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
und würde ein Datum zurückgeben, wie: 2/4/2008 7:20 PM
Konvertieren Sie beide Zeichenfolgen in Zeitstempel (in der von Ihnen gewählten Auflösung, z. B. Millisekunden, Sekunden, Stunden, Tage usw.), subtrahieren Sie den früheren Wert von den späteren, multiplizieren Sie Ihre Zufallszahl (vorausgesetzt, sie wird im range [0, 1]
verteilt) mit diesem Unterschied und addiert sie erneut zum früheren. Wandeln Sie den Zeitstempel zurück in die Datumszeichenfolge, und Sie haben eine zufällige Zeit in diesem Bereich.
Python-Beispiel (die Ausgabe hat fast das von Ihnen angegebene Format, anders als 0
padding - Schuld an den amerikanischen Zeitformatkonventionen):
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())
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)
Die Präzision ist Sekunden. Sie können die Genauigkeit auf Mikrosekunden erhöhen oder auf halbe Stunden reduzieren, wenn Sie möchten. Dazu einfach die letzte Zeilenberechnung ändern.
beispiellauf:
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)
ausgabe:
2008-12-04 01:50:17
Eine winzige Version.
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())),
)
Beachten Sie, dass sowohl start
als auch end
-Argumente datetime
-Objekte sein sollten. Wenn Sie stattdessen über Strings verfügen, ist die Konvertierung relativ einfach. Die anderen Antworten zeigen auf einige Möglichkeiten, dies zu tun.
Noch einfacher geht es mit 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')
Es ist sehr einfach, Radar zu verwenden
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()
Dies ist ein anderer Ansatz - diese Art von Arbeiten ..
from random import randint
import datetime
date=datetime.date(randint(2005,2025), randint(1,12),randint(1,28))
BESSERER ANSATZ
startdate=datetime.date(YYYY,MM,DD)
date=startdate+datetime.timedelta(randint(1,365))
Da Python 3 timedelta
die Multiplikation mit Floats unterstützt, können Sie jetzt Folgendes tun:
import random
random_date = start + (end - start) * random.random()
vorausgesetzt, dass start
und end
vom Typ datetime.datetime
sind. Um beispielsweise eine zufällige Datumszeit innerhalb des nächsten Tages zu generieren:
import random
from datetime import datetime, timedelta
start = datetime.now()
end = start + timedelta(days=1)
random_date = start + (end - start) * random.random()
Um in eine Pandas-basierte Lösung einzugreifen, verwende ich:
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
Ich mag es, wegen der Nice pd.Timestamp
-Funktionen, die es mir ermöglichen, verschiedene Dinge und Formate darauf zu werfen. Betrachten Sie die folgenden Beispiele ...
Ihre Unterschrift.
>>> 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)
Zufällige Position.
>>> 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)
Anderes Format.
>>> random_date('2008-01-01 13:30', '2009-01-01 4:50')
Timestamp('2008-11-18 17:20:19', tz=None)
Pandas/Datetime-Objekte direkt übergeben.
>>> random_date(pd.datetime.now(), pd.datetime.now() + pd.offsets.Hour(3))
Timestamp('2014-03-06 14:51:16.035965', tz=None)
Sie können Mixer
verwenden,
pip install mixer
und,
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))
Um noch einen hinzuzufügen:
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')
Die Tagesbehandlung erfordert einige Überlegungen. Mit 28 sind Sie auf der sicheren Seite.
Am einfachsten ist es, beide Zahlen in Zeitmarken umzuwandeln und diese dann als minimale und maximale Grenze für einen Zufallszahlengenerator festzulegen.
Ein schnelles PHP Beispiel wäre:
// 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);
}
Diese Funktion verwendet strtotime()
, um eine Datums-/Zeitbeschreibung in einen Unix-Zeitstempel zu konvertieren, und date()
, um aus dem generierten zufälligen Zeitstempel ein gültiges Datum zu machen.
#!/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 __== '__main__':
import doctest
doctest.testmod()
Hier ist eine Antwort auf die wörtliche Bedeutung des Titels und nicht auf den Inhalt dieser Frage:
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)
Dieser Code basiert lose auf der akzeptierten Antwort.
Hier ist eine von emyllers Ansatz modifizierte Lösung, die bei jeder Auflösung ein Array von zufälligen Datumsangaben zurückgibt
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))
Das Schöne an diesem Ansatz ist, dass np.datetime64
wirklich gut darin ist, Dinge zu Datumsangaben zu zwingen, sodass Sie Ihre Start- und Enddaten als Zeichenfolgen, Datumsangaben und Pandas-Zeitstempel angeben können.
Viele Algorithmen zum Konvertieren von Datumsangaben in und von Zahlen sind in vielen Betriebssystemen bereits verfügbar.
Wofür brauchen Sie die Zufallszahl? Normalerweise (abhängig von der Sprache) können Sie die Anzahl der Sekunden/Millisekunden aus der Epoche von einem Datum abrufen. Für ein zufälliges Datum zwischen startDate und endDate können Sie Folgendes tun:
Basierend auf der Antwort von mouviciel ist hier eine vektorisierte Lösung mit numpy. Konvertieren Sie das Start- und Enddatum in ints, generieren Sie ein Array aus Zufallszahlen und konvertieren Sie das gesamte Array wieder in Datumsangaben.
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
Pandas + numpy Lösung
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 ist die Differenz zwischen Zeitstempeln in Sekunden (Float). Es wird dann verwendet, um ein Pandas-Zeitdelta zwischen 0 und dts zu erstellen, das zum Startzeitstempel hinzugefügt wird.
In 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)
(Python dateutil
-Bibliothek benötigen - pip install python-dateutil
)
Konzeptionell ist es ziemlich einfach. Abhängig von der verwendeten Sprache können Sie diese Datumsangaben in eine 32- oder 64-Bit-Ganzzahl mit Referenzwert konvertieren, die in der Regel Sekunden seit Epoche (1. Januar 1970) oder "Millisekunden" seit einem anderen beliebigen Datum darstellt. Erzeugen Sie einfach eine zufällige 32- oder 64-Bit-Ganzzahl zwischen diesen beiden Werten. Dies sollte in jeder Sprache ein Einzeiler sein.
Auf einigen Plattformen können Sie eine Zeit als Double generieren (Datum ist der ganzzahlige Teil, Zeit ist der gebrochene Teil ist eine Implementierung). Dasselbe Prinzip gilt, es sei denn, Sie haben Gleitkommazahlen mit einfacher oder doppelter Genauigkeit ("Floats" oder "Doubles" in C, Java und anderen Sprachen). Subtrahiere die Differenz, multipliziere mit der Zufallszahl (0 <= r <= 1), addiere zur Startzeit und fertig.
Ich habe dies für ein anderes Projekt mit Zufall und Zeit gemacht. Ich habe ein allgemeines Format verwendet, ab dem Sie die Dokumentation hier für das erste Argument in strftime () anzeigen können. Der zweite Teil ist eine random.randrange-Funktion. Es gibt eine ganze Zahl zwischen den Argumenten zurück. Ändern Sie ihn in die Bereiche, die den gewünschten Zeichenfolgen entsprechen. Sie müssen Nizza-Argumente im Tupel der zweiten Argumentation haben.
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))
Verwenden Sie ApacheCommonUtils, um einen zufälligen Long innerhalb eines bestimmten Bereichs zu generieren, Und erstellen Sie dann Date aus diesem Long.
Beispiel:
import org.Apache.commons.math.random.RandomData;
import org.Apache.commons.math.random.RandomDataImpl;
public Date nextDate (Datum min, Datum max) {
RandomData randomData = new RandomDataImpl();
return new Date(randomData.nextLong(min.getTime(), max.getTime()));
}
Es ist eine modifizierte Methode von @ (Tom Alsberg). Ich habe es geändert, um ein Datum mit Millisekunden zu erhalten.
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)
Beispiel:
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())
Ausgabe: 2028/07/08 12:34:49.977963
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)))
Konvertieren Sie Ihre Daten in Zeitstempel und rufen Sie random.randint
mit den Zeitstempeln auf. Konvertieren Sie dann den zufällig generierten Zeitstempel zurück in ein Datum:
from datetime import datetime
import random
def random_date(first_date, second_date):
first_timestamp = int(first_date.timestamp())
second_timestamp = int(second_date.timestamp())
random_timestamp = random.randint(
min(first_timestamp, second_timestamp), max(first_timestamp, second_timestamp)
)
return datetime.fromtimestamp(random_timestamp)
Dann können Sie es so verwenden
from datetime import datetime
d1 = datetime.strptime("1/1/2018 1:30 PM", "%m/%d/%Y %I:%M %p")
d2 = datetime.strptime("1/1/2019 4:50 AM", "%m/%d/%Y %I:%M %p")
random_date(d1, d2)
random_date(d2, d1) # works the same
Wenn Sie sich für Zeitzonen interessieren, sollten Sie einfach die Bibliothek faker
verwenden, aus der ich diesen Code gestohlen habe , wie eine andere Antwort bereits nahelegt.