দুটি তারিখের মধ্যে মাস খুঁজে পাওয়ার সেরা উপায়


96

পাইথনের দুটি তারিখের মধ্যে মাসগুলি সঠিকভাবে সন্ধান করার জন্য আমার প্রয়োজন হবে। আমার একটি সমাধান রয়েছে যা কার্যকর হয় তবে এটি খুব ভাল নয় (মার্জিত হিসাবে) বা দ্রুত।

dateRange = [datetime.strptime(dateRanges[0], "%Y-%m-%d"), datetime.strptime(dateRanges[1], "%Y-%m-%d")]
months = [] 

tmpTime = dateRange[0]
oneWeek = timedelta(weeks=1)
tmpTime = tmpTime.replace(day=1)
dateRange[0] = tmpTime
dateRange[1] = dateRange[1].replace(day=1)
lastMonth = tmpTime.month
months.append(tmpTime)
while tmpTime < dateRange[1]:
    if lastMonth != 12:
        while tmpTime.month <= lastMonth:
            tmpTime += oneWeek
        tmpTime = tmpTime.replace(day=1)
        months.append(tmpTime)
        lastMonth = tmpTime.month

    else:
        while tmpTime.month >= lastMonth:
            tmpTime += oneWeek
        tmpTime = tmpTime.replace(day=1)
        months.append(tmpTime)
        lastMonth = tmpTime.month

সুতরাং কেবল ব্যাখ্যা করার জন্য, আমি এখানে যা করছি তা হচ্ছে দুটি তারিখ গ্রহণ করা এবং সেগুলিকে আইসো ফর্ম্যাট থেকে পাইথন ডেটটাইম অবজেক্টে রূপান্তর করা। তারপরে আমি শুরু করার তারিখের সময় অবজেক্টে এক সপ্তাহ যোগ করে লুপ করব এবং মাসের সংখ্যাসূচক মানটি বেশি কিনা তা পরীক্ষা করে দেখি (যদি মাসটি ডিসেম্বর না হয় তবে তারিখটি কম হয় কিনা তা পরীক্ষা করে নেওয়া হয়), মানটি যদি বড় হয় তবে আমি এটিকে তালিকায় যুক্ত করি কয়েক মাস এবং আমি আমার শেষ তারিখ না পাওয়া পর্যন্ত লুপিং চালিয়ে যান।

এটি নিখুঁতভাবে কাজ করে এটি এটি করার কোনও ভাল পদ্ধতির মতো বলে মনে হচ্ছে না ...


আপনি কি দুটি তারিখের মধ্যে মাসের সংখ্যা জিজ্ঞাসা করছেন, বা আসল মাসগুলি কী?
চার্লস হুপার

আমার সমাধানে: আমি "এক মাসের মূল্য সেকেন্ডের সংখ্যার" দ্বারা বৃদ্ধি পাচ্ছি না। আমি কেবল 1 থেকে 2 নাম্বার বাড়িয়ে দিচ্ছি এবং তারপরে 2 থেকে 3 থেকে পরে।
nonopolarity

আমি কেবল আপনাকে জানতে চেয়েছিলাম যে আপনি আমার উত্তরটি পছন্দ করেননি কারণ এটির "লুপ ছিল" আপনি একটি উত্তর নির্বাচন করেছেন যাতে দুটি উত্তর আছে। তালিকার বোধগম্যতা এখনও লুপ।
চার্লস হুপার

উত্তর:


2

আপডেট 2018-04-20: মনে হয় যে ওপি @ জোশকুনজ দুটি তারিখের মধ্যে "কত মাস" এর পরিবর্তে কোন মাসের দুটি তারিখের মধ্যে রয়েছে তা জানতে চেয়েছিলেন । সুতরাং আমি নিশ্চিত না যে @ জনলআরউই কেন 100 টিরও বেশি বার আপলোড করা হয়েছে। @ জোশকুনজ মূল প্রশ্নের অধীনে মন্তব্যে ইঙ্গিত করেছেন যে তিনি মাসের সংখ্যা নির্ধারণের পরিবর্তে প্রকৃত তারিখগুলি [বা মাসগুলি] চেয়েছিলেন ।

সুতরাং এটি দুটি তারিখের মধ্যে প্রশ্নপত্র চেয়েছিলেন, হাজির 2018-04-11করার2018-06-01

Apr 2018, May 2018, June 2018 

এবং যদি এটি মধ্যে 2014-04-11হয় 2018-06-01? তাহলে উত্তর হবে

Apr 2014, May 2014, ..., Dec 2014, Jan 2015, ..., Jan 2018, ..., June 2018

তাই আমি বহু বছর আগে নিম্নলিখিত সিউডো কোডটি পেয়েছিলাম। এটি কেবলমাত্র দুটি মাসকে শেষের পয়েন্ট হিসাবে ব্যবহার করার পরামর্শ দেয় এবং লুপগুলি একবারে এক মাস বাড়িয়ে দেয়। @ জোশকুনজ উল্লেখ করেছিলেন যে তিনি "মাস" চান এবং তিনি উল্লেখ করেছিলেন যে তিনি "তারিখগুলি" চান, ঠিক না জেনেও সঠিক কোডটি লেখা মুশকিল, তবে ধারণাটি শেষ পয়েন্টগুলির মধ্যে লুপের জন্য একটি সাধারণ লুপ ব্যবহার করা এবং এক সময় এক মাস বাড়ানো।

8 বছর আগে 2010 সালে উত্তর:

যদি এক সপ্তাহের মধ্যে যোগ করা হয়, তবে এটি প্রয়োজন হিসাবে প্রায় 435 গুণ কাজ করবে। কেন শুধু না:

1. get start date in array of integer, set it to i: [2008, 3, 12], 
       and change it to [2008, 3, 1]
2. get end date in array: [2010, 10, 26]
3. add the date to your result by parsing i
       increment the month in i
       if month is >= 13, then set it to 1, and increment the year by 1
   until either the year in i is > year in end_date, 
           or (year in i == year in end_date and month in i > month in end_date)

আপাতত কেবলমাত্র pseduo কোড, পরীক্ষা করা হয়নি, তবে আমি মনে করি একই লাইনের সাথে ধারণাটি কাজ করবে।


4
ঠিক আছে, আমি ফেব্রুয়ারির মতো মাসগুলিতে কিছু সমস্যা দেখছি যদি মাসে বাড়ানো হয় weeks সপ্তাহের চেয়ে বেশি than
জোশকুঞ্জ

আমি "এক মাসের মূল্য সেকেন্ডের সংখ্যার" দ্বারা বৃদ্ধি পাচ্ছি না। আমি নিছক সংখ্যা বৃদ্ধিশীল করছি 1করার 2, এবং তারপর থেকে 2করার 3পরে।
nonopolarity

201

কিছু পরীক্ষার কেস সংজ্ঞা দিয়ে শুরু করুন, তারপরে আপনি দেখতে পাবেন যে ফাংশনটি খুব সাধারণ এবং কোনও লুপের প্রয়োজন নেই

from datetime import datetime

def diff_month(d1, d2):
    return (d1.year - d2.year) * 12 + d1.month - d2.month

assert diff_month(datetime(2010,10,1), datetime(2010,9,1)) == 1
assert diff_month(datetime(2010,10,1), datetime(2009,10,1)) == 12
assert diff_month(datetime(2010,10,1), datetime(2009,11,1)) == 11
assert diff_month(datetime(2010,10,1), datetime(2009,8,1)) == 14

আপনার প্রশ্নে আপনার কয়েকটি পরীক্ষার কেস যুক্ত করা উচিত, কারণ অনেকগুলি সম্ভাব্য কোণাগুলি কেস করার জন্য রয়েছে - দুটি তারিখের মধ্যে মাসের সংখ্যা নির্ধারণ করার একাধিক উপায় রয়েছে।


4
এটি ভুল ফলাফল দেয়। "2015-04-30" এবং "2015-05-01" এর মধ্যে 1 মাসের ফলাফল আসে যা আসলে মাত্র 1 দিন।
রাও

21
@ রাও। এ কারণেই আমি বলেছিলাম "দুটি তারিখের মধ্যে মাসের সংখ্যা নির্ধারণের একাধিক উপায় রয়েছে"। প্রশ্নটির এখনও একটি আনুষ্ঠানিক সংজ্ঞা নেই। এই কারণেই আমি সুপারিশ করি সংজ্ঞা পাশাপাশি টেস্টকেসগুলি সরবরাহ করা উচিত।
জন লা রুই

4
আমি ডি 2-কে ডি 2-এর চেয়ে ছোট হওয়ার জন্য সাবস্ট্রাকশনগুলির আশেপাশে অ্যাবস () যোগ করার পরামর্শ দিচ্ছি: রিটার্ন অ্যাবস (d1.year - d2.year) * 12 + অ্যাবস (d1.month - d2.month)
lszrh

আপনি কি নিশ্চিত যে @ লুকাসচুলজে? ডি 1 যদি ডি 2 এর চেয়ে ছোট হয় তবে আপনাকে প্রথমে যে কোনওভাবেই বিয়োগ করতে হবে, তাই না?
লিলিথ-এলিনা

42

দুটি তারিখের মধ্যে মাসের বর্ধিত তারিখের তালিকা সন্ধান করার জন্য একটি লাইনার।

import datetime
from dateutil.rrule import rrule, MONTHLY

strt_dt = datetime.date(2001,1,1)
end_dt = datetime.date(2005,6,1)

dates = [dt for dt in rrule(MONTHLY, dtstart=strt_dt, until=end_dt)]

এই! এটি প্রচুর অভিনব বিশেষ পরিস্থিতিতে অ্যাডজাস্ট করে ব্যবহার করার জন্য ধন্যবাদ। দ্রষ্টব্য আউটপুট মানগুলি তারিখের সময় তাই অন্যেরা যা দেখায় তার সাথে মেলে আপনি নিজের পছন্দ অনুযায়ী (স্ট্রিং সহ) রূপান্তর করতে পারেন।
এজেকিয়েল ক্রিগলিক

এই বছর ব্যর্থ হয় যখন strt_dt 2001-1-29 হয়, সেই বছর কোনও লিপ দিবসের কারণে না।
সিএস

4
ওপি শুরু এবং শেষের তারিখগুলির মধ্যে মাসের একটি তালিকা চেয়েছিল। ফেব্রুয়ারী আমার উদাহরণটিতে আপনার পদ্ধতি ব্যবহার করে মিস হয়েছে। অবশ্যই, আপনার সমাধানটি এখনও মাসের প্রথমটির সাথে শুরু করার তারিখটি সামঞ্জস্য করে উদ্ধার করা যেতে পারে।
সিএস

4
এটি একটি দুর্দান্ত সমাধান এবং এটি আমার অনেক সময় সাশ্রয় করে। আমরা প্রারম্ভের তারিখটি দিয়ে আরও বেশি উন্নত করতে পারি[dt for dt in rrule(MONTHLY, bymonthday=10,dtstart=strt_dt, until=end_dt)]
পেঙ্গজু ঝাও

4
এটি সম্পর্কে সচেতন হতে হবে। তাদের কাছে ডকুমেন্টেশনে একটি নোট রয়েছে যা বলছে যে "অভাবনীয় আচরণ হতে পারে উদাহরণস্বরূপ, মাসের শেষের দিকে শুরু করার তারিখটি ঘটে" ( ডেটুটিল.ড্রেডহেডসকস.ইও / এএন / স্টেবল / র্রোল.এইচটিএমএল নোট দেখুন )। এড়ানোর এক উপায় start_date_first = start_date.replace(day=1), end_date_first = end_date.replace(day=1)হ'ল মাসের প্রথম দিনটির মধ্যে তারিখগুলি প্রতিস্থাপন করা: তারপরে rrule মাস গণনা সঠিকভাবে করা হয়।
আল্লা সরোকিনা

39

এটি আমার পক্ষে কাজ করেছে -

from datetime import datetime
from dateutil import relativedelta
date1 = datetime.strptime('2011-08-15 12:00:00', '%Y-%m-%d %H:%M:%S')
date2 = datetime.strptime('2012-02-15', '%Y-%m-%d')
r = relativedelta.relativedelta(date2, date1)
r.months + (12*r.years)

str()স্ট্রিং আক্ষরিক চারপাশে অপ্রয়োজনীয় অপসারণ ।
jfs

7
ডেল্টাটি 1 বছরের বেশি হলে, r.months0 থেকে শুরু হবে Wor
জেবি কে কেডিডি

4
@ jbkkd যে বিষয়ে কথা বলছিল তার সাথে সামঞ্জস্য রেখে সাধারণত আমি r.months * (r.years + 1) করি

9
@triunenature এই সৌন্দর্য ভুল, নিশ্চয় এটা r.months ভালো কিছু হওয়া উচিত + + (r.years * 12)
Moataz Elmasry

4
হ্যাঁ, তারিখগুলি এক বছরের বেশি আলাদা থাকলে এটি কাজ করে না।
HansG600

12

ডেটুটিল মডিউল থেকে আপনি সহজেই এটি ব্যবহার করতে পারেন :

from dateutil import rrule
from datetime import date

print(list(rrule.rrule(rrule.MONTHLY, dtstart=date(2013, 11, 1), until=date(2014, 2, 1))))

তোমাকে দিবে:

 [datetime.datetime(2013, 11, 1, 0, 0),
 datetime.datetime(2013, 12, 1, 0, 0),
 datetime.datetime(2014, 1, 1, 0, 0),
 datetime.datetime(2014, 2, 1, 0, 0)]

10

সমাপ্তি মাসটি পান (প্রারম্ভিক মাসের বছর এবং মাসের তুলনায় প্রাক্তন: ২০১১ জানুয়ারী = ১৩ যদি আপনার শুরুর তারিখটি ২0 অক্টোবর থেকে শুরু হয়) এবং তারপরে শুরুর মাসের শুরুতে এবং শেষের মাসটিকে এভাবে তৈরি করুন:

dt1, dt2 = dateRange
start_month=dt1.month
end_months=(dt2.year-dt1.year)*12 + dt2.month+1
dates=[datetime.datetime(year=yr, month=mn, day=1) for (yr, mn) in (
          ((m - 1) / 12 + dt1.year, (m - 1) % 12 + 1) for m in range(start_month, end_months)
      )]

যদি উভয় তারিখ একই বছর হয়, তবে এটি সহজভাবে লেখা যেতে পারে:

dates=[datetime.datetime(year=dt1.year, month=mn, day=1) for mn in range(dt1.month, dt2.month + 1)]

8

এই পোস্টে এটি নখ! ব্যবহার dateutil.relativedelta

from datetime import datetime
from dateutil import relativedelta
date1 = datetime.strptime(str('2011-08-15 12:00:00'), '%Y-%m-%d %H:%M:%S')
date2 = datetime.strptime(str('2012-02-15'), '%Y-%m-%d')
r = relativedelta.relativedelta(date2, date1)
r.months

4
@ এডওয়ার্ড আমি যে উদাহরণটি দিয়েছি তাতে আপনি দেখতে পাচ্ছেন, তারিখগুলি বিভিন্ন বছরে। তবুও, str()আমি যে কাস্ট করেছি তা সম্পূর্ণ অপ্রয়োজনীয়।
srodriguex

6
তারিখগুলি এক বছরেরও বেশি সময় জুড়ে থাকলে এটি কাজ করে না, আপনাকে যোগ করতে হবেrelativedelta.relativedelta(date2, date1).years * 12
মিউন

delta.years*12 + delta.months
ব্যবহারকারী2682863

7

আমার সহজ সমাধান:

import datetime

def months(d1, d2):
    return d1.month - d2.month + 12*(d1.year - d2.year)

d1 = datetime.datetime(2009, 9, 26)  
d2 = datetime.datetime(2019, 9, 26) 

print(months(d1, d2))

কম প্রশংসা সমাধান
reabow


4

নির্ধারণ করুন একটি "মাস" হিসেবে 1 / 12 বছর, তারপর এই একটি করুন:

def month_diff(d1, d2): 
    """Return the number of months between d1 and d2, 
    such that d2 + month_diff(d1, d2) == d1
    """
    diff = (12 * d1.year + d1.month) - (12 * d2.year + d2.month)
    return diff

আপনি কোনও মাসকে "29, 28, 30 বা 31 দিনের (বছরের উপর নির্ভর করে) সময় হিসাবে" সংজ্ঞায়িত করার চেষ্টা করতে পারেন। তবে আপনি এটি করেন, সমাধান করার জন্য আপনার একটি অতিরিক্ত সমস্যা রয়েছে।

যদিও এটা সাধারণত পরিষ্কার যে 15 জুন তম +1 মাস হওয়া উচিত জুলাই 15 তম , তাই না সাধারণত পরিষ্কার যদি জানুয়ারি 30 তম + 1 টি মাস ফেব্রুয়ারি বা মার্চ মাসে হয়। পরেরটির ক্ষেত্রে, আপনি ফেব্রুয়ারি 30 তারিখ গনা করতে বাধ্য করা হতে পারে 2 মার্চ, তারপর "সঠিক" এটা য় । কিন্তু যখন আপনি যে কি, আপনি বুঝতে পারবেন, মার্চ 2 য় - 1 মাস পরিষ্কারভাবে 2 ফেব্রুয়ারি য় । তবুও, কমানোর বিজ্ঞাপন (এই অপারেশন ভাল সংজ্ঞায়িত করা হয় না)।


4

360 দিনের বছরের উপর ভিত্তি করে একটি সহজ সমাধান রয়েছে, যেখানে সমস্ত মাসে 30 দিন থাকে। এটি বেশিরভাগ ব্যবহারের ক্ষেত্রে খাপ খায় যেখানে দুটি তারিখ দেওয়া হলে, আপনাকে পুরো মাসের সংখ্যা এবং বাকি দিনগুলি গণনা করতে হবে।

from datetime import datetime, timedelta

def months_between(start_date, end_date):
    #Add 1 day to end date to solve different last days of month 
    s1, e1 = start_date , end_date  + timedelta(days=1)
    #Convert to 360 days
    s360 = (s1.year * 12 + s1.month) * 30 + s1.day
    e360 = (e1.year * 12 + e1.month) * 30 + e1.day
    #Count days between the two 360 dates and return tuple (months, days)
    return divmod(e360 - s360, 30)

print "Counting full and half months"
print months_between( datetime(2012, 01, 1), datetime(2012, 03, 31)) #3m
print months_between( datetime(2012, 01, 1), datetime(2012, 03, 15)) #2m 15d
print months_between( datetime(2012, 01, 16), datetime(2012, 03, 31)) #2m 15d
print months_between( datetime(2012, 01, 16), datetime(2012, 03, 15)) #2m
print "Adding +1d and -1d to 31 day month"
print months_between( datetime(2011, 12, 01), datetime(2011, 12, 31)) #1m 0d
print months_between( datetime(2011, 12, 02), datetime(2011, 12, 31)) #-1d => 29d
print months_between( datetime(2011, 12, 01), datetime(2011, 12, 30)) #30d => 1m
print "Adding +1d and -1d to 29 day month"
print months_between( datetime(2012, 02, 01), datetime(2012, 02, 29)) #1m 0d
print months_between( datetime(2012, 02, 02), datetime(2012, 02, 29)) #-1d => 29d
print months_between( datetime(2012, 02, 01), datetime(2012, 02, 28)) #28d
print "Every month has 30 days - 26/M to 5/M+1 always counts 10 days"
print months_between( datetime(2011, 02, 26), datetime(2011, 03, 05))
print months_between( datetime(2012, 02, 26), datetime(2012, 03, 05))
print months_between( datetime(2012, 03, 26), datetime(2012, 04, 05))

4

@ ভিন-জি দ্বারা কিছুটা পূর্বনির্ধারিত সমাধান।

import datetime

def monthrange(start, finish):
  months = (finish.year - start.year) * 12 + finish.month + 1 
  for i in xrange(start.month, months):
    year  = (i - 1) / 12 + start.year 
    month = (i - 1) % 12 + 1
    yield datetime.date(year, month, 1)

4

আপনি তীর লাইব্রেরিও ব্যবহার করতে পারেন । এটি একটি সহজ উদাহরণ:

from datetime import datetime
import arrow

start = datetime(2014, 1, 17)
end = datetime(2014, 6, 20)

for d in arrow.Arrow.range('month', start, end):
    print d.month, d.format('MMMM')

এটি মুদ্রণ করবে:

1 January
2 February
3 March
4 April
5 May
6 June

আশাকরি এটা সাহায্য করবে!


3

এরকম কিছু চেষ্টা করুন। এটি উভয় তারিখ একই মাসে হয় যদি বর্তমানে এটি মাস অন্তর্ভুক্ত।

from datetime import datetime,timedelta

def months_between(start,end):
    months = []
    cursor = start

    while cursor <= end:
        if cursor.month not in months:
            months.append(cursor.month)
        cursor += timedelta(weeks=1)

    return months

আউটপুট দেখে মনে হচ্ছে:

>>> start = datetime.now() - timedelta(days=120)
>>> end = datetime.now()
>>> months_between(start,end)
[6, 7, 8, 9, 10]

এটি এখনও একই লুপিং পদ্ধতির গ্রহণ করে, তাই আমি অগত্যা এই সুবিধাটি দেখতে পাচ্ছি না ...
জোশকুঞ্জ

4
আমি দেখতে পাচ্ছি না যে কিভাবে সমস্যা। লুপগুলি আপনার শত্রু নয়।
চার্লস হুপার

ভাল এটি প্রতিবারই করা উচিত তাদের একটি এজাক্স কোয়েরি। আমি জানি যে লুপগুলি শত্রু নয় তবে মনে হয় এগুলি কোনও সমস্যার ধীর সমাধান যা খুব সহজ উপায়ে সমাধান করা উচিত।
জোশকুঞ্জ


3

পান্ডাস এফডাব্লুআইডাব্লু দিয়ে এটি কীভাবে করা যায় তা এখানে:

import pandas as pd
pd.date_range("1990/04/03", "2014/12/31", freq="MS")

DatetimeIndex(['1990-05-01', '1990-06-01', '1990-07-01', '1990-08-01',
               '1990-09-01', '1990-10-01', '1990-11-01', '1990-12-01',
               '1991-01-01', '1991-02-01',
               ...
               '2014-03-01', '2014-04-01', '2014-05-01', '2014-06-01',
               '2014-07-01', '2014-08-01', '2014-09-01', '2014-10-01',
               '2014-11-01', '2014-12-01'],
              dtype='datetime64[ns]', length=296, freq='MS')

লক্ষ্য করুন এটি প্রদত্ত শুরুর তারিখের পরের মাস থেকেই শুরু হয় ।


2

এটি ডেটটাইম.টিমেডেল্টা ব্যবহার করে করা যেতে পারে, যেখানে পরের মাসে স্কিপিংয়ের জন্য দিনের সংখ্যা ক্যালেন্ডার.মেনথ্রেঞ্জের মাধ্যমে পাওয়া যায়। মাসরেঞ্জ সপ্তাহের দিন (0-6 ~ সোম-সান) এবং প্রদত্ত বছর এবং মাসের জন্য দিনের সংখ্যা (28-31) দেয়
উদাহরণস্বরূপ: মাসরেঞ্জ (2017, 1) রিটার্ন (6,31)।

এখানে দুই মাসের মধ্যে পুনরাবৃত্তি করতে এই যুক্তিটি ব্যবহার করে স্ক্রিপ্টটি এখানে দেওয়া হয়েছে।

from datetime import timedelta
import datetime as dt
from calendar import monthrange

def month_iterator(start_month, end_month):
    start_month = dt.datetime.strptime(start_month,
                                   '%Y-%m-%d').date().replace(day=1)
    end_month = dt.datetime.strptime(end_month,
                                 '%Y-%m-%d').date().replace(day=1)
    while start_month <= end_month:
        yield start_month
        start_month = start_month + timedelta(days=monthrange(start_month.year, 
                                                         start_month.month)[1])

`


আপনি দয়া করে ব্যাখ্যা করতে পারেন যে এটি কীভাবে সমস্যার সমাধান করে? আমরা লোকদের তাদের উত্তরের প্রসঙ্গ যুক্ত করতে উত্সাহিত করি; ধন্যবাদ
Gi0rgi0s

4
একটি ব্যাখ্যা যুক্ত করা হয়েছে
পঙ্কজ কুমার

2

অনেকে এর সমাধান করার জন্য ইতিমধ্যে আপনাকে ভাল উত্তর দিয়েছে তবে আমি কোনও ব্যবহারের তালিকা বোধগম্যতা পড়িনি তাই আমি আপনাকে যা অনুরূপ ব্যবহারের ক্ষেত্রে ব্যবহার করেছি তা আপনাকে দিয়ে দিচ্ছি:


def compute_months(first_date, second_date):
    year1, month1, year2, month2 = map(
        int, 
        (first_date[:4], first_date[5:7], second_date[:4], second_date[5:7])
    )

    return [
        '{:0>4}-{:0>2}'.format(year, month)
        for year in range(year1, year2 + 1)
        for month in range(month1 if year == year1 else 1, month2 + 1 if year == year2 else 13)
    ]

>>> first_date = "2016-05"
>>> second_date = "2017-11"
>>> compute_months(first_date, second_date)
['2016-05',
 '2016-06',
 '2016-07',
 '2016-08',
 '2016-09',
 '2016-10',
 '2016-11',
 '2016-12',
 '2017-01',
 '2017-02',
 '2017-03',
 '2017-04',
 '2017-05',
 '2017-06',
 '2017-07',
 '2017-08',
 '2017-09',
 '2017-10',
 '2017-11']


1
#This definition gives an array of months between two dates.
import datetime
def MonthsBetweenDates(BeginDate, EndDate):
    firstyearmonths = [mn for mn in range(BeginDate.month, 13)]<p>
    lastyearmonths = [mn for mn in range(1, EndDate.month+1)]<p>
    months = [mn for mn in range(1, 13)]<p>
    numberofyearsbetween = EndDate.year - BeginDate.year - 1<p>
    return firstyearmonths + months * numberofyearsbetween + lastyearmonths<p>

#example
BD = datetime.datetime.strptime("2000-35", '%Y-%j')
ED = datetime.datetime.strptime("2004-200", '%Y-%j')
MonthsBetweenDates(BD, ED)

1

ঠিক যেমন rangeফাংশন, যখন মাস 13 হয় , পরের বছর যান

def year_month_range(start_date, end_date):
    '''
    start_date: datetime.date(2015, 9, 1) or datetime.datetime
    end_date: datetime.date(2016, 3, 1) or datetime.datetime
    return: datetime.date list of 201509, 201510, 201511, 201512, 201601, 201602
    '''
    start, end = start_date.strftime('%Y%m'), end_date.strftime('%Y%m')
    assert len(start) == 6 and len(end) == 6
    start, end = int(start), int(end)

    year_month_list = []
    while start < end:
        year, month = divmod(start, 100)
        if month == 13:
            start += 88  # 201513 + 88 = 201601
            continue
        year_month_list.append(datetime.date(year, month, 1))

        start += 1
    return year_month_list

পাইথন শেল উদাহরণস্বরূপ

>>> import datetime
>>> s = datetime.date(2015,9,1)
>>> e = datetime.date(2016, 3, 1)
>>> year_month_set_range(s, e)
[datetime.date(2015, 11, 1), datetime.date(2015, 9, 1), datetime.date(2016, 1, 1), datetime.date(2016, 2, 1),
 datetime.date(2015, 12, 1), datetime.date(2015, 10, 1)]

1

সাধারণত 90 দিন 3 মাস আক্ষরিক নয়, কেবল একটি রেফারেন্স।

সুতরাং, অবশেষে, আপনাকে মাসের কাউন্টারে +1 যোগ করতে 15 দিনের চেয়ে বড় কিনা তা পরীক্ষা করা উচিত। বা আরও ভাল, অর্ধ মাসের কাউন্টার সহ অন্য এলিফ যুক্ত করুন।

থেকে অন্য Stackoverflow উত্তর পরিশেষে আমি যে দিয়ে শেষ করেছি:

#/usr/bin/env python
# -*- coding: utf8 -*-

import datetime
from datetime import timedelta
from dateutil.relativedelta import relativedelta
import calendar

start_date = datetime.date.today()
end_date = start_date + timedelta(days=111)
start_month = calendar.month_abbr[int(start_date.strftime("%m"))]

print str(start_date) + " to " + str(end_date)

months = relativedelta(end_date, start_date).months
days = relativedelta(end_date, start_date).days

print months, "months", days, "days"

if days > 16:
    months += 1

print "around " + str(months) + " months", "(",

for i in range(0, months):
    print calendar.month_abbr[int(start_date.strftime("%m"))],
    start_date = start_date + relativedelta(months=1)

print ")"

আউটপুট:

2016-02-29 2016-06-14
3 months 16 days
around 4 months ( Feb Mar Apr May )

আমি লক্ষ্য করেছি যে আপনি যদি চলতি বছরে আরও বেশি দিন যোগ করেন তবে তা কাজ করে না এবং এটি অপ্রত্যাশিত।


1

দেখে মনে হচ্ছে উত্তরগুলি অসন্তুষ্টিজনক এবং এর পরে আমার নিজের কোডটি ব্যবহার করা হয়েছে যা বোঝা সহজ

from datetime import datetime
from dateutil import relativedelta

date1 = datetime.strptime(str('2017-01-01'), '%Y-%m-%d')
date2 = datetime.strptime(str('2019-03-19'), '%Y-%m-%d')

difference = relativedelta.relativedelta(date2, date1)
months = difference.months
years = difference.years
# add in the number of months (12) for difference in years
months += 12 * difference.years
months

1
from datetime import datetime
from dateutil import relativedelta

def get_months(d1, d2):
    date1 = datetime.strptime(str(d1), '%Y-%m-%d')
    date2 = datetime.strptime(str(d2), '%Y-%m-%d')
    print (date2, date1)
    r = relativedelta.relativedelta(date2, date1)
    months = r.months +  12 * r.years
    if r.days > 0:
        months += 1
    print (months)
    return  months


assert  get_months('2018-08-13','2019-06-19') == 11
assert  get_months('2018-01-01','2019-06-19') == 18
assert  get_months('2018-07-20','2019-06-19') == 11
assert  get_months('2018-07-18','2019-06-19') == 12
assert  get_months('2019-03-01','2019-06-19') == 4
assert  get_months('2019-03-20','2019-06-19') == 3
assert  get_months('2019-01-01','2019-06-19') == 6
assert  get_months('2018-09-09','2019-06-19') == 10

1

এটির জন্য আমার সমাধানটি এখানে:

def calc_age_months(from_date, to_date):
    from_date = time.strptime(from_date, "%Y-%m-%d")
    to_date = time.strptime(to_date, "%Y-%m-%d")

    age_in_months = (to_date.tm_year - from_date.tm_year)*12 + (to_date.tm_mon - from_date.tm_mon)

    if to_date.tm_mday < from_date.tm_mday:
        return age_in_months -1
    else
        return age_in_months

এটি কিছু প্রান্তের কেসগুলি পরিচালনা করবে যেখানে 31 শে ডিসেম্বর 2018 এবং 1 জানুয়ারী 2019 এর মধ্যে মাসের পার্থক্য শূন্য হবে (যেহেতু পার্থক্যটি কেবলমাত্র এক দিনের)।


0

উচ্চতর তারিখ ধরে নেওয়া সর্বদা নিম্নের তারিখের চেয়ে পরে এবং উভয়ই ডেটটাইম ডেট অবজেক্ট:

if lowerDate.year == upperDate.year:
    monthsInBetween = range( lowerDate.month + 1, upperDate.month )
elif upperDate.year > lowerDate.year:
    monthsInBetween = range( lowerDate.month + 1, 12 )
    for year in range( lowerDate.year + 1, upperDate.year ):
        monthsInBetween.extend( range(1,13) )
    monthsInBetween.extend( range( 1, upperDate.month ) )

আমি এটি পুরোপুরি পরীক্ষা করে দেখিনি, তবে দেখে মনে হচ্ছে এটি কৌশলটি করা উচিত।


0

এখানে একটি পদ্ধতি:

def months_between(start_dt, stop_dt):
    month_list = []
    total_months = 12*(stop_dt.year-start_dt.year)+(stop_dt.month-start_d.month)+1
    if total_months > 0:
        month_list=[ datetime.date(start_dt.year+int((start_dt+i-1)/12), 
                                   ((start_dt-1+i)%12)+1,
                                   1) for i in xrange(0,total_months) ]
    return month_list

এটি সর্বমোট দুটি তারিখের মধ্যে মাসের মোট সংখ্যা গণনা করছে। তারপরে এটি বেস হিসাবে প্রথম তারিখটি ব্যবহার করে একটি তালিকা তৈরি করে এবং তারিখের অবজেক্টগুলি তৈরি করতে মডুলা গাণিতিক সম্পাদন করে।


0

আমার আসলে ঠিক এখন অনুরূপ কিছু করা দরকার

একটি ফাংশন লেখার সমাপ্তি ঘটে যা দুটি সেট তারিখের মধ্যে startএবং endপ্রতিটি মাসের মধ্যে নির্দেশিত টিউপসগুলির একটি তালিকা দেয় যাতে আমি মাসিক মোট বিক্রয় ইত্যাদির জন্য এর পিছনে কিছু এসকিউএল প্রশ্ন লিখতে পারি could

আমি নিশ্চিত যে এটির দ্বারা উন্নতি করা যেতে পারে যে কেউ জানে যে তারা কী করছে তবে আশা করি এটি সাহায্য করবে ...

নিম্নোক্ত প্রত্যাশিত মান চেহারা (আজকের জন্য উত্পন্ন হচ্ছে - উদাহরণ হিসাবে আজ অবধি ৩5৫ দিন)

[   (datetime.date(2013, 5, 1), datetime.date(2013, 5, 31)),
    (datetime.date(2013, 6, 1), datetime.date(2013, 6, 30)),
    (datetime.date(2013, 7, 1), datetime.date(2013, 7, 31)),
    (datetime.date(2013, 8, 1), datetime.date(2013, 8, 31)),
    (datetime.date(2013, 9, 1), datetime.date(2013, 9, 30)),
    (datetime.date(2013, 10, 1), datetime.date(2013, 10, 31)),
    (datetime.date(2013, 11, 1), datetime.date(2013, 11, 30)),
    (datetime.date(2013, 12, 1), datetime.date(2013, 12, 31)),
    (datetime.date(2014, 1, 1), datetime.date(2014, 1, 31)),
    (datetime.date(2014, 2, 1), datetime.date(2014, 2, 28)),
    (datetime.date(2014, 3, 1), datetime.date(2014, 3, 31)),
    (datetime.date(2014, 4, 1), datetime.date(2014, 4, 30)),
    (datetime.date(2014, 5, 1), datetime.date(2014, 5, 31))]

নীচের কোডে (কিছু ডিবাগ স্টাফ রয়েছে যা সরানো যেতে পারে):

#! /usr/env/python
import datetime

def gen_month_ranges(start_date=None, end_date=None, debug=False):
    today = datetime.date.today()
    if not start_date: start_date = datetime.datetime.strptime(
        "{0}/01/01".format(today.year),"%Y/%m/%d").date()  # start of this year
    if not end_date: end_date = today
    if debug: print("Start: {0} | End {1}".format(start_date, end_date))

    # sense-check
    if end_date < start_date:
        print("Error. Start Date of {0} is greater than End Date of {1}?!".format(start_date, end_date))
        return None

    date_ranges = []  # list of tuples (month_start, month_end)

    current_year = start_date.year
    current_month = start_date.month

    while current_year <= end_date.year:
        next_month = current_month + 1
        next_year = current_year
        if next_month > 12:
            next_month = 1
            next_year = current_year + 1

        month_start = datetime.datetime.strptime(
            "{0}/{1}/01".format(current_year,
                                current_month),"%Y/%m/%d").date()  # start of month
        month_end = datetime.datetime.strptime(
            "{0}/{1}/01".format(next_year,
                                next_month),"%Y/%m/%d").date()  # start of next month
        month_end  = month_end+datetime.timedelta(days=-1)  # start of next month less one day

        range_tuple = (month_start, month_end)
        if debug: print("Month runs from {0} --> {1}".format(
            range_tuple[0], range_tuple[1]))
        date_ranges.append(range_tuple)

        if current_month == 12:
            current_month = 1
            current_year += 1
            if debug: print("End of year encountered, resetting months")
        else:
            current_month += 1
            if debug: print("Next iteration for {0}-{1}".format(
                current_year, current_month))

        if current_year == end_date.year and current_month > end_date.month:
            if debug: print("Final month encountered. Terminating loop")
            break

    return date_ranges


if __name__ == '__main__':
    print("Running in standalone mode. Debug set to True")
    from pprint import pprint
    pprint(gen_month_ranges(debug=True), indent=4)
    pprint(gen_month_ranges(start_date=datetime.date.today()+datetime.timedelta(days=-365),
                            debug=True), indent=4)

0

ধরে নিলাম যে আপনি তারিখগুলি ছিল সে মাসের "ভগ্নাংশ" জানতে চেয়েছিলেন, যা আমি করেছি, তখন আপনাকে আরও কিছু কাজ করা দরকার।

from datetime import datetime, date
import calendar

def monthdiff(start_period, end_period, decimal_places = 2):
    if start_period > end_period:
        raise Exception('Start is after end')
    if start_period.year == end_period.year and start_period.month == end_period.month:
        days_in_month = calendar.monthrange(start_period.year, start_period.month)[1]
        days_to_charge = end_period.day - start_period.day+1
        diff = round(float(days_to_charge)/float(days_in_month), decimal_places)
        return diff
    months = 0
    # we have a start date within one month and not at the start, and an end date that is not
    # in the same month as the start date
    if start_period.day > 1:
        last_day_in_start_month = calendar.monthrange(start_period.year, start_period.month)[1]
        days_to_charge = last_day_in_start_month - start_period.day +1
        months = months + round(float(days_to_charge)/float(last_day_in_start_month), decimal_places)
        start_period = datetime(start_period.year, start_period.month+1, 1)

    last_day_in_last_month = calendar.monthrange(end_period.year, end_period.month)[1]
    if end_period.day != last_day_in_last_month:
        # we have lest days in the last month
        months = months + round(float(end_period.day) / float(last_day_in_last_month), decimal_places)
        last_day_in_previous_month = calendar.monthrange(end_period.year, end_period.month - 1)[1]
        end_period = datetime(end_period.year, end_period.month - 1, last_day_in_previous_month)

    #whatever happens, we now have a period of whole months to calculate the difference between

    if start_period != end_period:
        months = months + (end_period.year - start_period.year) * 12 + (end_period.month - start_period.month) + 1

    # just counter for any final decimal place manipulation
    diff = round(months, decimal_places)
    return diff

assert monthdiff(datetime(2015,1,1), datetime(2015,1,31)) == 1
assert monthdiff(datetime(2015,1,1), datetime(2015,02,01)) == 1.04
assert monthdiff(datetime(2014,1,1), datetime(2014,12,31)) == 12
assert monthdiff(datetime(2014,7,1), datetime(2015,06,30)) == 12
assert monthdiff(datetime(2015,1,10), datetime(2015,01,20)) == 0.35
assert monthdiff(datetime(2015,1,10), datetime(2015,02,20)) == 0.71 + 0.71
assert monthdiff(datetime(2015,1,31), datetime(2015,02,01)) == round(1.0/31.0,2) + round(1.0/28.0,2)
assert monthdiff(datetime(2013,1,31), datetime(2015,02,01)) == 12*2 + round(1.0/31.0,2) + round(1.0/28.0,2)

একটি উদাহরণ প্রদান করে যা অন্তর্ভুক্তভাবে দুটি তারিখের মধ্যে মাসের সংখ্যা নির্ধারণ করে, যার সাথে তারিখটি প্রতি মাসের ভগ্নাংশ অন্তর্ভুক্ত থাকে This এর অর্থ আপনি 2015-01-20 থেকে 2015-02-14 এর মধ্যে কত মাসের কাজ করতে পারেন তা বোঝাতে পারেন that যেখানে জানুয়ারী মাসে তারিখের ভগ্নাংশ জানুয়ারীর দিন সংখ্যা দ্বারা নির্ধারিত হয়; বা সমানভাবে বিবেচনায় রেখে ফেব্রুয়ারির দিনগুলির সংখ্যা বছরের পর বছর পরিবর্তিত হতে পারে।

আমার রেফারেন্সের জন্য, এই কোডটি গিথুবেও রয়েছে - https://gist.github.com/andrewyager/6b9284a4f1cdb1779b10


0

এটা চেষ্টা কর:

 dateRange = [datetime.strptime(dateRanges[0], "%Y-%m-%d"),
             datetime.strptime(dateRanges[1], "%Y-%m-%d")]
delta_time = max(dateRange) - min(dateRange)
#Need to use min(dateRange).month to account for different length month
#Note that timedelta returns a number of days
delta_datetime = (datetime(1, min(dateRange).month, 1) + delta_time -
                           timedelta(days=1)) #min y/m/d are 1
months = ((delta_datetime.year - 1) * 12 + delta_datetime.month -
          min(dateRange).month)
print months

আপনি তারিখগুলি ইনপুট কী অর্ডার করবেন তা বিবেচনা করা উচিত নয় এবং এটি মাসের দৈর্ঘ্যের পার্থক্যের বিষয়টি বিবেচনা করে।


নোট করুন এটি আপনার তারিখগুলি একই হওয়ার জন্য অ্যাকাউন্ট করে না। ডেল্টা_টাইম.ডেস = 0: মাস = 0 অন্য রুটিনের সাথে থাকলে সবচেয়ে সহজ উপায়।
om_henners

0

এইটা কাজ করে...

from datetime import datetime as dt
from dateutil.relativedelta import relativedelta
def number_of_months(d1, d2):
    months = 0
    r = relativedelta(d1,d2)
    if r.years==0:
        months = r.months
    if r.years>=1:
        months = 12*r.years+r.months
    return months
#example 
number_of_months(dt(2017,9,1),dt(2016,8,1))
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.