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

Python 在其他两个日期之间生成一个随机日期,python,datetime,random,Python,Datetime,Random,我如何生成一个必须介于其他两个给定日期之间的随机日期 函数的签名应该是这样的: 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 thi

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

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

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

并将返回一个日期,例如:
2/4/2008 7:20 PM
将两个字符串转换为时间戳(以您选择的分辨率,例如毫秒、秒、小时、天等),从后面减去较早的,将随机数(假设它分布在
范围[0,1]
)乘以该差值,并再次添加到前面的一个。将时间戳转换回日期字符串,则在该范围内有一个随机时间

Python示例(输出几乎是您指定的格式,而不是
0
padding-归咎于美国的时间格式约定):

  • 将输入日期转换为数字 (int,float,任何最适合 (你的用法)
  • 在两个日期号码中选择一个号码
  • 将此数字转换回日期

  • 许多操作系统已经提供了许多将日期转换为数字或从数字转换为数字的算法。

    您需要随机数做什么?通常(取决于语言),您可以从日期获取历元的秒/毫秒数。因此,对于startDate和endDate之间的随机日期,您可以执行以下操作:

  • 计算两者之间的时间(毫秒) 开始日期和结束日期 (endDate.tomillesons()- startDate.toMilliseconds())
  • 生成一个介于0和在1中获得的数字之间的数字
  • 生成一个新日期,其时间偏移量=startDate.toMilliseconds()+在2中获得的数字

  • 从概念上讲,这很简单。根据您使用的语言,您将能够将这些日期转换为某个参考32位或64位整数,通常表示自历元(1970年1月1日)起的秒数,也称为“Unix时间”,或自某个其他任意日期起的毫秒数。只需在这两个值之间生成一个随机的32或64位整数。这在任何语言中都应该是一行


    在某些平台上,可以将时间生成为双精度(日期是整数部分,时间是小数部分,是一个实现)。除了处理单精度或双精度浮点数(在C、Java和其他语言中为“floats”或“double”)外,同样的原则也适用。减去差值,乘以随机数(0最简单的方法是将两个数字转换为时间戳,然后将它们设置为随机数生成器上的最小和最大界限

    一个快速的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);
    }
    
    此函数使用
    将日期时间描述转换为Unix时间戳,并使用
    从生成的随机时间戳中生成有效日期

    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)
    
    精度为秒。如果需要,可以将精度提高到微秒,或者降低到半小时。为此,只需更改最后一行的计算

    运行示例:

    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))
    
    输出:

    2008-12-04 01:50:17
    
    在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
    library–
    pip安装python dateutil

    以下是对标题字面意思的回答,而不是对问题主体的回答:

    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)
    
    此代码大致基于公认的答案。

    一个小版本

    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())),
        )
    
    请注意,
    start
    end
    参数都应该是
    datetime
    对象。如果 相反,你有字符串,转换起来相当容易。其他的答案是
    使用ApacheCommonUtils在给定范围内生成一个随机long, 然后用这么长的时间创建日期

    例如:

    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())
    
    导入org.apache.commons.math.random.RandomData

    导入org.apache.commons.math.random.RandomDataImpl

    公共日期下一个日期(最小日期、最大日期){

    }

    最新答案 使用起来更简单

    装置 用法: 旧答案 使用雷达很简单

    装置 用法
    导入日期时间
    进口雷达
    #生成随机日期时间(从str值解析日期)
    雷达随机日期时间(开始时间=2000-05-24',停止时间=2013-05-24T23:59:59')
    #从datetime.datetime值生成随机datetime
    雷达随机时间(
    start=datetime.datetime(年=2000,月=5,日=24),
    stop=datetime.datetime(年=2013,月=5,日=24)
    )
    #只需呈现一些随机日期时间。如果没有给定范围,则“开始”默认为
    #1970-01-01和stop默认为datetime.datetime.now()
    radar.random_datetime()
    
    要插入我使用的基于熊猫的解决方案,请执行以下操作:

    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
    

    我喜欢它,因为很好的<代码> Pd。时间戳特性允许我在它上抛出不同的东西和格式。考虑下面的几个例子…

    你的签名

    >>> 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)
    
    随机位置

    >>> 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)
    
    不同的格式

    >>> random_date('2008-01-01 13:30', '2009-01-01 4:50')
    Timestamp('2008-11-18 17:20:19', tz=None)
    
    直接传递pandas/datetime对象

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

    由于Python 3
    timedelta
    支持浮点乘法,因此现在您可以执行以下操作:

    import random
    random_date = start + (end - start) * random.random()
    
    假设
    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()
    

    您可以使用混音器

    pip install mixer
    
    以及


    这是一种不同的方法,这种方法很有效

    from random import randint
    import datetime
    
    date=datetime.date(randint(2005,2025), randint(1,12),randint(1,28))
    
    更好的方法

    startdate=datetime.date(YYYY,MM,DD)
    date=startdate+datetime.timedelta(randint(1,365))
    

    我使用random和time为另一个项目创建了此文件。我使用了一种通用格式,从您可以查看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))
    

    再加一句:

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

    白天的处理需要考虑一些因素。28岁的你是在安全的网站上。

    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之间的时间增量,并将其添加到开始时间戳中。

    根据mouviciel的回答,下面是一个
    from random import randint
    import datetime
    
    date=datetime.date(randint(2005,2025), randint(1,12),randint(1,28))
    
    startdate=datetime.date(YYYY,MM,DD)
    date=startdate+datetime.timedelta(randint(1,365))
    
    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))
    
    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')
    
    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')
    
    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
    
    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())
    
    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))
    
    #!/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()
    
    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)))
    
    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(first_timestamp, second_timestamp)
        return datetime.fromtimestamp(random_timestamp)
    
    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)  # ValueError because the first date comes after the second date
    
    # needed to create data for 1000 fictitious employees for testing code 
    # code relating to randomly assigning forenames, surnames, and genders
    # has been removed as not germaine to the question asked above but FYI
    # genders were randomly assigned, forenames/surnames were web scrapped,
    # there is no accounting for leap years, and the data stored in mySQL
       
    import random 
    from datetime import datetime
    from datetime import timedelta
    
    for employee in range(1000):
        # assign a random date of birth (employees are aged between sixteen and sixty five)
        dlt = random.randint(365*16, 365*65)
        dob = datetime.today() - timedelta(days=dlt)
        # assign a random date of hire sometime between sixteenth birthday and yesterday
        doh = datetime.today() - timedelta(days=random.randint(1, dlt-365*16))
        print("born {} hired {}".format(dob.strftime("%d-%m-%y"), doh.strftime("%d-%m-%y")))
    
    # Import libraries
    import pandas as pd
    
    # Initialize
    start = '2020-01-01' # Specify start date
    end = '2020-03-10' # Specify end date
    n = 10 # Specify number of dates needed
    
    # Get random dates
    x = np.random.randint(pd.Timestamp(start).value, pd.Timestamp(end).value,n)
    random_dates = [pd.to_datetime((i/10**9)/(60*60)/24, unit='D').strftime('%Y-%m-%d')  for i in x]
    
    print(random_dates)
    
    ['2020-01-06',
     '2020-03-08',
     '2020-01-23',
     '2020-02-03',
     '2020-01-30',
     '2020-01-05',
     '2020-02-16',
     '2020-03-08',
     '2020-02-09',
     '2020-01-04']
    
    class GetRandomDateMixin:
        def get_random_date(self, start_date=None, end_date=None):
            """
            get random date between start_date and end_date.
            If any of them is None, then get random date between
            today and past 100 years.
            :param start_date: datetime obj.
                eg: datetime.datetime(1940, 1, 1).date()
            :param end_date: datetime obj
            :return: random date
            """
            if start_date is None or end_date is None:
    
                end_date = datetime.datetime.today().date()
                start_date = end_date - datetime.timedelta(
                    days=(100 * 365)
                )
    
            delta = end_date - start_date
            random_days = random.randint(1, delta.days)
            new_date = start_date + datetime.timedelta(
                days=random_days
            )
    
            return new_date
    
    import random
    import datetime
    
    start = datetime.date(1980, 1, 1)
    end = datetime.date(2000, 1, 1)
    
    random_date = start + (end - start) * random.random()
    random_date = datetime.datetime.combine(random_date, datetime.datetime.min.time())