代码之家  ›  专栏  ›  技术社区  ›  Migol

Python时间增量(以年为单位)

  •  109
  • Migol  · 技术社区  · 17 年前

    我需要核实一下,是否已经过去了几年。目前我有 timedelta datetime 模块,我不知道如何将其转换为年。

    14 回复  |  直到 5 年前
        1
  •  176
  •   Braiam nahurmf    5 年前

    timedelta

    dateutil.relativedelta object ,但那是第三方模块。如果你想知道 datetime 那是 n

    from dateutil.relativedelta import relativedelta
    
    def yearsago(years, from_date=None):
        if from_date is None:
            from_date = datetime.now()
        return from_date - relativedelta(years=years)
    

    如果你宁愿坚持使用标准库,答案会稍微复杂一些:

    from datetime import datetime
    def yearsago(years, from_date=None):
        if from_date is None:
            from_date = datetime.now()
        try:
            return from_date.replace(year=from_date.year - years)
        except ValueError:
            # Must be 2/29!
            assert from_date.month == 2 and from_date.day == 29 # can be removed
            return from_date.replace(month=2, day=28,
                                     year=from_date.year-years)
    

    return

        return from_date.replace(month=3, day=1,
                                 year=from_date.year-years)
    

    你的问题最初说你想知道从某个日期到现在已经有多少年了。假设你想要一个整数年,你可以根据每年365.2425天进行猜测,然后使用以下任一方法进行检查 yearsago

    def num_years(begin, end=None):
        if end is None:
            end = datetime.now()
        num_years = int((end - begin).days / 365.2425)
        if begin > yearsago(num_years, end):
            return num_years - 1
        else:
            return num_years
    
        2
  •  56
  •   Adam Rosenfield    17 年前

    如果你想检查某人是否年满18岁,请使用 timedelta 由于闰年的原因,在某些边缘情况下无法正常工作。例如,2000年1月1日出生的人将在2018年1月3日(包括5个闰年)后恰好6575天满18岁,但2001年1月2日出生的个人将在2019年1月4日(包括4个闰年在内)后正好6574天满18周岁。因此,如果一个人恰好是6574天大,在不知道更多关于他们出生日期的信息的情况下,你无法确定他们是17岁还是18岁。

        3
  •  10
  •   MarkusQ    17 年前

    delta_in_days / (365.25)
    delta_in_seconds / (365.25*24*60*60)
    

    …或者别的什么。远离月份,因为它们比年份更不明确。

        4
  •  8
  •   antihero    12 年前

    这是一个更新的DOB函数,它以与人类相同的方式计算生日:

    import datetime
    import locale
    
    
    # Source: https://en.wikipedia.org/wiki/February_29
    PRE = [
        'US',
        'TW',
    ]
    POST = [
        'GB',
        'HK',
    ]
    
    
    def get_country():
        code, _ = locale.getlocale()
        try:
            return code.split('_')[1]
        except IndexError:
            raise Exception('Country cannot be ascertained from locale.')
    
    
    def get_leap_birthday(year):
        country = get_country()
        if country in PRE:
            return datetime.date(year, 2, 28)
        elif country in POST:
            return datetime.date(year, 3, 1)
        else:
            raise Exception('It is unknown whether your country treats leap year '
                          + 'birthdays as being on the 28th of February or '
                          + 'the 1st of March. Please consult your country\'s '
                          + 'legal code for in order to ascertain an answer.')
    def age(dob):
        today = datetime.date.today()
        years = today.year - dob.year
    
        try:
            birthday = datetime.date(today.year, dob.month, dob.day)
        except ValueError as e:
            if dob.month == 2 and dob.day == 29:
                birthday = get_leap_birthday(today.year)
            else:
                raise e
    
        if today < birthday:
            years -= 1
        return years
    
    print(age(datetime.date(1988, 2, 29)))
    
        5
  •  6
  •   brianary    16 年前

        6
  •  4
  •   eduffy    17 年前

    你需要它有多精确? td.days / 365.25 如果你担心闰年,它会让你非常接近。

        7
  •  2
  •   John Mee    16 年前
    def age(dob):
        import datetime
        today = datetime.date.today()
    
        if today.month < dob.month or \
          (today.month == dob.month and today.day < dob.day):
            return today.year - dob.year - 1
        else:
            return today.year - dob.year
    
    >>> import datetime
    >>> datetime.date.today()
    datetime.date(2009, 12, 1)
    >>> age(datetime.date(2008, 11, 30))
    1
    >>> age(datetime.date(2008, 12, 1))
    1
    >>> age(datetime.date(2008, 12, 2))
    0
    
        8
  •  1
  •   Antony Hatchkins Alexander Hamilton    16 年前

    ` 简单的解决方案!

    import datetime as dt
    from dateutil.relativedelta import relativedelta
    
    dt1 = dt.datetime(1990,2,1)
    dt2 = dt.datetime(2021,5,16)
    out = relativedelta(dt2, dt1)
    
    print(f'Complete: {out}')
    print(f'years:{out.years}, months:{out.months}, days:{out.days}') `
    

    年:31,月:3,日:15

        9
  •  1
  •   Norberto    16 年前

    b = birthday
    today = datetime.datetime.today()
    age = today.year - b.year + (today.month - b.month > 0 or 
                                 (today.month == b.month > 0 and 
                                  today.day - b.day > 0))
    
        10
  •  1
  •   pvilas    15 年前

    def calculate_age(birthday_date, fmt="%Y-%m-%d"):
        birthday = datetime.datetime.strptime(birthday_date, fmt)
        age = datetime.datetime.now() - birthday
        # first datime valid is (1, 1, 1), I use (1, 12, 31) => (2, 0, 0) to hack the lib
        age = (datetime.datetime(1, 12, 31) + age)
        return age.year - 2
    

    这个解决方案很奇怪,所以我和你分享了。这可能不是最优雅的功能。

    now : 2019-09-21
    
    print(calculate_age("2019-09-21")) => 2 (Done) 
    
    -> age + (1,12,31) = 0004-01-01 23:42:17.767031
    
    print(calculate_age("2020-09-21")) => 0 (Undone)
    
    -> age + (1,12,31) = 0002-12-31 23:46:39.144091
    

    要纠正这种不希望的行为,您需要使用生日年份来添加结果。

        11
  •  1
  •   Sajid    5 年前

    这里没有提到的另一个第三方库是mxDateTime(这两个python的前身) datetime timeutil )可用于此任务。

    前述的 yearsago 将是:

    from mx.DateTime import now, RelativeDateTime
    
    def years_ago(years, from_date=None):
        if from_date == None:
            from_date = now()
        return from_date-RelativeDateTime(years=years)
    

    第一个参数应该是 DateTime 例子

    日期时间 日期时间 您可以将其用于1秒精度):

    def DT_from_dt_s(t):
        return DT.DateTimeFromTicks(time.mktime(t.timetuple()))
    

    或者,对于1微秒的精度:

    def DT_from_dt_u(t):
        return DT.DateTime(t.year, t.month, t.day, t.hour,
      t.minute, t.second + t.microsecond * 1e-6)
    

    是的,与使用timeutil(由Rick Copeland建议)相比,为这个有问题的单一任务添加依赖关系肯定是一种过度的做法。

        12
  •  1
  •   ouflak    4 年前

    时间增量/(365*4)+1)/4=时间增量*4/(365*4+1)

        13
  •  0
  •       17 年前

    这是我想出的解决方案,希望能有所帮助;-)

    def menor_edad_legal(birthday):
        """ returns true if aged<18 in days """ 
        try:
    
            today = time.localtime()                        
    
            fa_divuit_anys=date(year=today.tm_year-18, month=today.tm_mon, day=today.tm_mday)
    
            if birthday>fa_divuit_anys:
                return True
            else:
                return False            
    
        except Exception, ex_edad:
            logging.error('Error menor de edad: %s' % ex_edad)
            return True
    
        14
  •  0
  •   Mauro Bianchi    16 年前

    为了我的目的,从减两开始 datetime timedelta 只有a days

    >>> admit = datetime.strptime('20130530', '%Y%m%d')
    >>> birth = datetime.strptime('20010621', '%Y%m%d')
    >>> age = (admit - birth).days/365.2425
    >>> age
    11.940012457476882
    
        15
  •  0
  •   twils    16 年前

    def validatedate(date):
        parts = date.strip().split('-')
    
        if len(parts) == 3 and False not in [x.isdigit() for x in parts]: 
            birth = datetime.date(int(parts[2]), int(parts[1]), int(parts[0]))
            today = datetime.date.today()
    
            b = (birth.year * 10000) + (birth.month * 100) + (birth.day)
            t = (today.year * 10000) + (today.month * 100) + (today.day)
    
            if (t - 18 * 10000) >= b:
                return True
    
        return False
    
        16
  •  0
  •   Andres Hurtis    6 年前

    此函数返回两个日期之间的年差(以ISO格式作为字符串,但可以很容易地修改为任何格式)

    import time
    def years(earlydateiso,  laterdateiso):
        """difference in years between two dates in ISO format"""
    
        ed =  time.strptime(earlydateiso, "%Y-%m-%d")
        ld =  time.strptime(laterdateiso, "%Y-%m-%d")
        #switch dates if needed
        if  ld < ed:
            ld,  ed = ed,  ld            
    
        res = ld[0] - ed [0]
        if res > 0:
            if ld[1]< ed[1]:
                res -= 1
            elif  ld[1] == ed[1]:
                if ld[2]< ed[2]:
                    res -= 1
        return res
    
        17
  •  0
  •   Sam    6 年前

    Pyfdate

    语言及其工作特性 它们应该是用户友好的 pyfdate的目的是弥补这一点 使用以下日期和时间 Python的其余部分。

    tutorial

        18
  •  0
  •   Rick Graves    6 年前
    import datetime
    
    def check_if_old_enough(years_needed, old_date):
    
        limit_date = datetime.date(old_date.year + years_needed,  old_date.month, old_date.day)
    
        today = datetime.datetime.now().date()
    
        old_enough = False
    
        if limit_date <= today:
            old_enough = True
    
        return old_enough
    
    
    
    def test_ages():
    
        years_needed = 30
    
        born_date_Logan = datetime.datetime(1988, 3, 5)
    
        if check_if_old_enough(years_needed, born_date_Logan):
            print("Logan is old enough")
        else:
            print("Logan is not old enough")
    
    
        born_date_Jessica = datetime.datetime(1997, 3, 6)
    
        if check_if_old_enough(years_needed, born_date_Jessica):
            print("Jessica is old enough")
        else:
            print("Jessica is not old enough")
    
    
    test_ages()
    

    这是卡鲁塞尔操作员在洛根的《奔跑》电影中运行的代码;)

    https://en.wikipedia.org/wiki/Logan%27s_Run_(film)

        19
  •  0
  •   Sebastian Meckovski    5 年前

    我遇到了这个问题,发现亚当斯的回答最有帮助 https://stackoverflow.com/a/765862/2964689

    但他的方法没有python示例,但这是我最终使用的方法。

    def age(birthday):
        birthday = birthday.date()
        today = date.today()
    
        years = today.year - birthday.year
    
        if (today.month < birthday.month or
           (today.month == birthday.month and today.day < birthday.day)):
    
            years = years - 1
    
        return years
    
        20
  •  0
  •   Hebe Hilhorst    5 年前

    def age(dob):
        import datetime
        today = datetime.date.today()
        age = today.year - dob.year
        if ( today.month == dob.month == 2 and
             today.day == 28 and dob.day == 29 ):
             pass
        elif today.month < dob.month or \
          (today.month == dob.month and today.day < dob.day):
            age -= 1
        return age
    
        21
  •  0
  •   jimh    5 年前

    我会用 datetime.date 数据类型,因为检查已经过去了多少年、几个月和几天更简单:

    now = date.today()
    birthday = date(1993, 4, 4)
    print("you are", now.year - birthday.year, "years,", now.month - birthday.month, "months and",
      now.day - birthday.day, "days old")
    

    输出:

    you are 27 years, 7 months and 11 days old
    

    我用 timedelta

    age = now - birthday
    print("addition of days to a date: ", birthday + timedelta(days=age.days))
    

    输出:

    addition of days to a date:  2020-11-15