在两个其他日期之间生成随机日期

qui*_*lby 119 python random datetime

我如何生成一个必须在两个其他给定日期之间的随机日期?

函数的签名应该是这样的:

random_date("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
Run Code Online (Sandbox Code Playgroud)

并会返回如下日期: 2/4/2008 7:20 PM

Tom*_*erg 130

将两个字符串转换为时间戳(以您选择的分辨率,例如毫秒,秒,小时,天等),从较晚的值中减去较早的值,将您的随机数乘以(假设它分布在该值中range [0, 1]),并再次添加较早的一个.将时间戳转换回日期字符串,您在该范围内有一个随机时间.

Python示例(输出几乎采用您指定的格式,而不是0填充 - 指责美国时间格式约定):

import random
import time

def str_time_prop(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 random_date(start, end, prop):
    return str_time_prop(start, end, '%m/%d/%Y %I:%M %p', prop)

print(random_date("1/1/2008 1:30 PM", "1/1/2009 4:50 AM", random.random()))
Run Code Online (Sandbox Code Playgroud)


nos*_*klo 97

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)
Run Code Online (Sandbox Code Playgroud)

精度是秒.如果需要,您可以将精度提高到微秒,或者减少到半小时.为此,只需更改最后一行计算.

示例运行:

from datetime import datetime

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))
Run Code Online (Sandbox Code Playgroud)

输出:

2008-12-04 01:50:17
Run Code Online (Sandbox Code Playgroud)

  • @emyller:不,我正在使用`(delta.days*24*60*60)+ delta.seconds`,这会产生总秒数.`total_seconds()`方法在python 2.7中是新的,并且在我回答问题时在2009年不存在.如果你有python 2.7,你应该使用它,但代码工作正常. (6认同)
  • 在这种情况下使用`start`变量是完全正确的.我在代码中看到的唯一问题是使用结果`delta`中的`seconds`属性.这不会返回整个时间间隔内的总秒数; 相反,它只是"时间"组件的秒数(0到60之间); `timedelta`对象有一个`total_seconds`方法,应该使用它. (3认同)

emy*_*ler 77

一个小版本.

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())),
    )
Run Code Online (Sandbox Code Playgroud)

请注意,参数startend参数都应该是datetime对象.如果你有字符串,那么转换相当容易.其他答案指出了一些方法.


Art*_*yan 47

更新的答案

使用Faker更简单.

安装

pip install faker
Run Code Online (Sandbox Code Playgroud)

用法:

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')
Run Code Online (Sandbox Code Playgroud)

老答案

使用雷达非常简单

安装

pip install radar
Run Code Online (Sandbox Code Playgroud)

用法

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()
Run Code Online (Sandbox Code Playgroud)

  • upvote建议faker模块..我用来生成配置文件,但没有使用日期实用程序faker是一个非常好的模块测试时. (3认同)

amc*_*h89 19

这是一种不同的方法 - 那种作品..

from random import randint
import datetime

date=datetime.date(randint(2005,2025), randint(1,12),randint(1,28))
Run Code Online (Sandbox Code Playgroud)

更好的方法

startdate=datetime.date(YYYY,MM,DD)
date=startdate+datetime.timedelta(randint(1,365))
Run Code Online (Sandbox Code Playgroud)

  • 第一种方法永远不会选择以 29 日、30 日或 31 日结束的日期,而第二种方法不考虑闰年,即一年有 366 天,即如果“startdate”+ 1 年在闰年经过 12 月 31 日年,此代码永远不会选择一年后的同一日期。这两种方法都只允许您指定开始日期和未来多少年,而问题是询问指定两个日期,在我看来这是一个更有用的 API。 (2认同)

Pie*_*Bos 13

由于Python 3 timedelta支持乘法浮点数,所以现在你可以这样做:

import random
random_date = start + (end - start) * random.random()
Run Code Online (Sandbox Code Playgroud)

鉴于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()
Run Code Online (Sandbox Code Playgroud)


met*_*mit 6

为了插入基于熊猫的解决方案,我使用:

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
Run Code Online (Sandbox Code Playgroud)

我喜欢它,因为它具有很好的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)
Run Code Online (Sandbox Code Playgroud)

随机位置.

>>> 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)
Run Code Online (Sandbox Code Playgroud)

格式不同.

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

直接传递pandas/datetime对象.

>>> random_date(pd.datetime.now(), pd.datetime.now() + pd.offsets.Hour(3))
Timestamp('2014-03-06 14:51:16.035965', tz=None)
Run Code Online (Sandbox Code Playgroud)