wake-up-neo.com

Erzeugen Sie ein zufälliges Datum zwischen zwei anderen Daten

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

102
quilby

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())
112
Tom Alsberg
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
89
nosklo

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.

72
emyller

Antwort aktualisiert

Noch einfacher geht es mit Faker .

Installation

pip install faker

Verwendungszweck:

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')

Alte Antwort

Es ist sehr einfach, Radar zu verwenden

Installation

pip install radar

Verwendungszweck

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()
35

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))
14
amchugh89

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()
8
Pieter Bos

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)
6
metakermit

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))
3
Nima Soroush

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.

2
tobmei05

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.

2
ConroyP
#!/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()
2
Martin Thoma

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.

2
Zach Dwiel

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.

1
David Marx
  1. Konvertieren Sie Ihre Eingabedaten in Zahlen (Int, float, wie auch immer Ihre Verwendung)
  2. Wählen Sie eine Nummer zwischen Ihren beiden Datumsnummern.
  3. Wandeln Sie diese Zahl in ein Datum zurück.

Viele Algorithmen zum Konvertieren von Datumsangaben in und von Zahlen sind in vielen Betriebssystemen bereits verfügbar.

1
mouviciel

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:

  1. berechne die Zeit in ms zwischen startDate und endDate (endDate.toMilliseconds () - startDate.toMilliseconds ())
  2. generieren Sie eine Zahl zwischen 0 und der Zahl, die Sie in 1 erhalten haben
  3. erzeugen Sie ein neues Datum mit Zeitversatz = startDate.toMilliseconds () + Nummer, die in 2 erhalten wird
1
tehvan

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
0
spring

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.

0
Carlos Santos

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)

0
Artur

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.

0
cletus

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))
0
user2723240

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()));

}

0
uris

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

0
TukanF1
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)))

verweisen

0
muthu

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.

0
Boris