如何计算两个给定日期之间的天数



如果我有两个日期(例如 '8/18/2008''9/26/2008'),获取这两个日期之间的天数的最佳方法是什么?

如果有两个日期对象,只需减去它们,即可计算出timedelta对象。

from datetime import date
d0 = date(2008, 8, 18)
d1 = date(2008, 9, 26)
delta = d1 - d0
print(delta.days)

文档的相关部分:https://docs.python.org/library/datetime.html。

有关另一个示例,请参阅此答案。

使用日期时间的力量:

from datetime import datetime
date_format = "%m/%d/%Y"
a = datetime.strptime('8/18/2008', date_format)
b = datetime.strptime('9/26/2008', date_format)
delta = b - a
print(delta.days) 
# that's it how to calculate number of days between two given dates

圣诞节前几天:

>>> import datetime
>>> today = datetime.date.today()
>>> someday = datetime.date(2008, 12, 25)
>>> diff = someday - today
>>> diff.days
86

这里更多的算术。

每个人都使用日期出色地回答了,让我尝试用熊猫来回答它

dt = pd.to_datetime('2008/08/18', format='%Y/%m/%d')
dt1 = pd.to_datetime('2008/09/26', format='%Y/%m/%d')
(dt1-dt).days

这将给出答案。如果其中一个输入是数据帧列。只需使用 dt.days 代替天数

(dt1-dt).dt.days

您需要日期时间模块。

>>> from datetime import datetime 
>>> datetime(2008,08,18) - datetime(2008,09,26) 
datetime.timedelta(4) 

再比如:

>>> import datetime 
>>> today = datetime.date.today() 
>>> print(today)
2008-09-01 
>>> last_year = datetime.date(2007, 9, 1) 
>>> print(today - last_year)
366 days, 0:00:00 

正如这里指出的

from datetime import datetime
start_date = datetime.strptime('8/18/2008', "%m/%d/%Y")
end_date = datetime.strptime('9/26/2008', "%m/%d/%Y")
print abs((end_date-start_date).days)

也可以使用 arrow 轻松完成:

import arrow
a = arrow.get('2017-05-09')
b = arrow.get('2017-05-11')
delta = (b-a)
print delta.days

供参考:http://arrow.readthedocs.io/en/latest/

不使用 Lib 只是纯代码:

#Calculate the Days between Two Date
daysOfMonths = [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
def isLeapYear(year):
    # Pseudo code for this algorithm is found at
    # http://en.wikipedia.org/wiki/Leap_year#Algorithm
    ## if (year is not divisible by 4) then (it is a common Year)
    #else if (year is not divisable by 100) then (ut us a leap year)
    #else if (year is not disible by 400) then (it is a common year)
    #else(it is aleap year)
    return (year % 4 == 0 and year % 100 != 0) or year % 400 == 0
def Count_Days(year1, month1, day1):
    if month1 ==2:
        if isLeapYear(year1):
            if day1 < daysOfMonths[month1-1]+1:
                return year1, month1, day1+1
            else:
                if month1 ==12:
                    return year1+1,1,1
                else:
                    return year1, month1 +1 , 1
        else: 
            if day1 < daysOfMonths[month1-1]:
                return year1, month1, day1+1
            else:
                if month1 ==12:
                    return year1+1,1,1
                else:
                    return year1, month1 +1 , 1
    else:
        if day1 < daysOfMonths[month1-1]:
             return year1, month1, day1+1
        else:
            if month1 ==12:
                return year1+1,1,1
            else:
                    return year1, month1 +1 , 1

def daysBetweenDates(y1, m1, d1, y2, m2, d2,end_day):
    if y1 > y2:
        m1,m2 = m2,m1
        y1,y2 = y2,y1
        d1,d2 = d2,d1
    days=0
    while(not(m1==m2 and y1==y2 and d1==d2)):
        y1,m1,d1 = Count_Days(y1,m1,d1)
        days+=1
    if end_day:
        days+=1
    return days

# Test Case
def test():
    test_cases = [((2012,1,1,2012,2,28,False), 58), 
                  ((2012,1,1,2012,3,1,False), 60),
                  ((2011,6,30,2012,6,30,False), 366),
                  ((2011,1,1,2012,8,8,False), 585 ),
                  ((1994,5,15,2019,8,31,False), 9239),
                  ((1999,3,24,2018,2,4,False), 6892),
                  ((1999,6,24,2018,8,4,False),6981),
                  ((1995,5,24,2018,12,15,False),8606),
                  ((1994,8,24,2019,12,15,True),9245),
                  ((2019,12,15,1994,8,24,True),9245),
                  ((2019,5,15,1994,10,24,True),8970),
                  ((1994,11,24,2019,8,15,True),9031)]
    for (args, answer) in test_cases:
        result = daysBetweenDates(*args)
        if result != answer:
            print "Test with data:", args, "failed"
        else:
            print "Test case passed!"
test()

要计算日期和时间,有几个选项,但我会写简单的方法:

from datetime import timedelta, datetime, date
import dateutil.relativedelta
# current time
date_and_time = datetime.now()
date_only = date.today()
time_only = datetime.now().time()
# calculate date and time
result = date_and_time - timedelta(hours=26, minutes=25, seconds=10)
# calculate dates: years (-/+)
result = date_only - dateutil.relativedelta.relativedelta(years=10)
# months
result = date_only - dateutil.relativedelta.relativedelta(months=10)
# week
results = date_only - dateutil.relativedelta.relativedelta(weeks=1)
# days
result = date_only - dateutil.relativedelta.relativedelta(days=10)
# calculate time 
result = date_and_time - timedelta(hours=26, minutes=25, seconds=10)
result.time()

希望对你有帮助

from datetime import date
def d(s):
  [month, day, year] = map(int, s.split('/'))
  return date(year, month, day)
def days(start, end):
  return (d(end) - d(start)).days
print days('8/18/2008', '9/26/2008')

当然,这假设您已经验证了日期的格式为 r'd+/d+/d+' .

还有一个尚未提及的datetime.toordinal()方法:

import datetime
print(datetime.date(2008,9,26).toordinal() - datetime.date(2008,8,18).toordinal())  # 39

https://docs.python.org/3/library/datetime.html#datetime.date.toordinal

date. toordinal()

返回日期的外推公历序数,其中第 1 年的 1 月 1 日具有序数 1。对于任何date对象 ddate.fromordinal(d.toordinal()) == d .

似乎非常适合计算天差,尽管不像timedelta.days那样可读。

这里有三种方法可以解决这个问题:

from datetime import datetime
Now = datetime.now()
StartDate = datetime.strptime(str(Now.year) +'-01-01', '%Y-%m-%d')
NumberOfDays = (Now - StartDate)
print(NumberOfDays.days)                     # Starts at 0
print(datetime.now().timetuple().tm_yday)    # Starts at 1
print(Now.strftime('%j'))                    # Starts at 1

如果你想自己编写计算代码,那么这里有一个函数,它将返回给定年份、月份和日期的序数:

def ordinal(year, month, day):
    return ((year-1)*365 + (year-1)//4 - (year-1)//100 + (year-1)//400
         + [ 0,31,59,90,120,151,181,212,243,273,304,334][month - 1]
         + day
         + int(((year%4==0 and year%100!=0) or year%400==0) and month > 2))

此函数与日期时间模块中的date.toordinal方法兼容。

您可以获取两个日期之间的差天数,如下所示:

print(ordinal(2021, 5, 10) - ordinal(2001, 9, 11))

在python中不使用datetime对象。

# A date has day 'd', month 'm' and year 'y' 
class Date:
    def __init__(self, d, m, y):
            self.d = d
            self.m = m
            self.y = y
# To store number of days in all months from 
# January to Dec. 
monthDays = [31, 28, 31, 30, 31, 30,
                                            31, 31, 30, 31, 30, 31 ]
# This function counts number of leap years 
# before the given date 
def countLeapYears(d):
    years = d.y
    # Check if the current year needs to be considered 
    # for the count of leap years or not 
    if (d.m <= 2) :
            years-= 1
    # An year is a leap year if it is a multiple of 4, 
    # multiple of 400 and not a multiple of 100. 
    return int(years / 4 - years / 100 + years / 400 )

# This function returns number of days between two 
# given dates 
def getDifference(dt1, dt2) :
    # COUNT TOTAL NUMBER OF DAYS BEFORE FIRST DATE 'dt1' 
    # initialize count using years and day 
    n1 = dt1.y * 365 + dt1.d
    # Add days for months in given date 
    for i in range(0, dt1.m - 1) :
            n1 += monthDays[i]
    # Since every leap year is of 366 days, 
    # Add a day for every leap year 
    n1 += countLeapYears(dt1)
    # SIMILARLY, COUNT TOTAL NUMBER OF DAYS BEFORE 'dt2' 
    n2 = dt2.y * 365 + dt2.d
    for i in range(0, dt2.m - 1) :
            n2 += monthDays[i]
    n2 += countLeapYears(dt2)
    # return difference between two counts 
    return (n2 - n1)

# Driver program 
dt1 = Date(31, 12, 2018 )
dt2 = Date(1, 1, 2019 )
print(getDifference(dt1, dt2), "days")

如果你没有日期处理库(或者你怀疑它有错误),这里有一个抽象算法,应该很容易翻译成大多数语言。

在每个日期执行以下计算,然后简单地减去两个结果。所有商和余数都是正整数。

步骤A.首先将日期的各个部分标识为Y(年),M(月)和D(日)。这些变量会随着我们的发展而变化。

步骤 B. 从 M 中减去 3

(因此 1 月是 -2,12 月是 9)。

步骤C。如果 M 为负数,则在 M 上加 12,然后从 Y 年中减去 1。

(这会将"年初"更改为 3 月 1 日,月份编号为 0(3 月)到 11(2 月)。这样做的原因是为了让"一年内的日数"在闰年和普通年之间不会发生变化,并且"短"月份在年底,因此没有下一个月份需要特殊处理。

步骤 D.将 M 除以 5 得到商 Q₁ 和余数 R₁。将 Q₁ × 153 添加到 D。在下一步中使用 R₁。

(从3月1日开始,每5个月有153天。

步骤 E. 将 R₁ 除以 2 得到商 Q₂ 并忽略余数。将 R₁ × 31 - Q₂ 添加到 D。

(每组5个月,每2个月有61天,每对月的第一个月为31天。可以安全地忽略 2 月短于 30 天的事实,因为此时您只关心 2 月 1 日的天数,而不关心次年 3 月 1 日的天数。

步骤D和E组合 - 替代方法

首次使用前设置L=[0,31,61,92,122,153,184,214,245,275,306,337]

(这是每月第一天之前(调整后的)一年中累计天数的表格。

将 L[M] 添加到 D。

步骤 F如果使用儒略历日期而不是公历日期,请跳过此步骤;转换因国家而异,但在大多数英语国家被视为 1752 年 9 月 3 日,在欧洲大部分地区被视为 1582 年 10 月 4 日。

如果您确定永远不必处理 1900 年 3 月 1 日到 2100 年 2 月 28 日范围之外的日期,也可以跳过此步骤,但随后必须对处理的所有日期做出相同的选择。

将 Y 除以 100 得到商 Q₃ 和余数 R₃。将 Q₃ 除以 4 得到另一个商 Q₄ 并忽略余数。将 Q₄ + 36524 × Q₃ 添加到 D。

将 R₃ 分配给 Y。

步骤 G.将 Y 除以 4 得到商 Q₅ 并忽略余数。将 Q₅ + 365 × Y 添加到 D。

步骤 H. (可选)您可以将您选择的常量添加到 D,以强制特定日期具有特定的日期编号。

为每个日期执行步骤 A~G,得到 D₁ 和 D₂。

步骤一.从 D₂ 中减去 D₁ 得到 D₂ 在 D₁ 之后的天数。

最后,评论一下:在处理大约1760年之前的日期时要格外小心,因为对于哪个月份是一年的开始没有达成一致;许多地方将3月1日视为新年。

如果你想为

起点和终点之间的每个日历日都有一个日期对象,那么这段代码可能会有所帮助。它返回开始和结束之间每天的日期对象:

from math import ceil
from datetime import date, datetime, timedelta

def day_range(start: datetime, end: datetime) -> date:
    first_day = start.replace(hour=0, minute=0, second=0, microsecond=0)
    daycount = ceil((end - first_day) / timedelta(days=1))
    for n in range(daycount):
        yield (start + timedelta(days=n)).date()

start = datetime(2023, 1, 1, 23, 0)
end = datetime(2023, 1, 4, 0, 20)
for day in day_range(start, end):
    print(f"Day: {day}")

相关内容

  • 没有找到相关文章

最新更新