বছরগুলিতে পাইথনের টাইমডেল্টা


140

কিছু তারিখ থেকে কয়েক বছর ধরে আমার পরীক্ষা করা দরকার I বর্তমানে আমি পেয়েছেন timedeltaথেকে datetimeমডিউল এবং আমি বছর থেকে এটি রূপান্তর করতে জানে না।


4
এই উত্তরটি দেখুন: stackoverflow.com/a/9754466/65387
অ্যাডাম

সম্পর্কিত:
বছরগুলিকে

উত্তর:


156

আপনার timedeltaকতগুলি বছর কেটে গেছে তা বলার জন্য আরও কিছু প্রয়োজন ; আপনারও শুরু (বা শেষ) তারিখটি জানতে হবে। (এটি একটি লিপ ইয়ার জিনিস))

আপনার সেরা বাজিটি dateutil.relativedelta অবজেক্টটি ব্যবহার করা তবে এটি তৃতীয় পক্ষের মডিউল। যদি আপনি এটি জানতে চান 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)

আপনি যদি বরং স্ট্যান্ডার্ড লাইব্রেরিটির সাথে আটকে থাকেন তবে উত্তরটি কিছুটা জটিল complex

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)

যদি এটি 2/29, এবং 18 বছর আগে 2/29 না থাকে তবে এই ফাংশনটি 2/28 এ ফিরে আসবে। আপনি যদি বরং 3/1 ফেরত চান তবে কেবল শেষ returnবিবৃতিটি পড়তে পরিবর্তন করুন ::

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

আপনার প্রশ্নটি মূলত বলেছিল যে আপনি জানতে চেয়েছিলেন যে কোনও তারিখ থেকে এটি কত বছর হয়েছে। ধরে নিচ্ছেন যে আপনি বছরের সংখ্যার সংখ্যা চান, আপনি প্রতি বছর ৩5৫.২৫ দিনের উপর ভিত্তি করে অনুমান করতে পারেন এবং তারপরে yearsagoউপরে বর্ণিত ফাংশনগুলির কোনওটি ব্যবহার করে পরীক্ষা করতে পারেন :

def num_years(begin, end=None):
    if end is None:
        end = datetime.now()
    num_years = int((end - begin).days / 365.25)
    if begin > yearsago(num_years, end):
        return num_years - 1
    else:
        return num_years

26
আপনি 365.2425 (365.25 এর পরিবর্তে) দিয়ে পুরোপুরি নির্ভুল হতে পারেন, যা গ্রেগরিয়ান ক্যালেন্ডারের জন্য অ্যাকাউন্টে 400 বছরের ব্যতিক্রম গ্রহণ করে।
ব্রায়ানারি

3
আপনার ফাংশন আইনত যুক্তরাজ্য এবং হংকংয়ের মতো দেশগুলির জন্য বিরতি দেয় কারণ তারা লাফ বছরের জন্য 1 ই মার্চ পর্যন্ত "বৃত্তাকার" থাকে।
অ্যান্টিহিরো


3
আরো দেখুন এই এবং এই উভয় সেই সময় সম্পর্কে সত্য নয় কিছুর চমৎকার তালিকা আছে।
gvoysey

49

আপনি যদি ১৮ বছর বয়সী কিনা তা খতিয়ে দেখার চেষ্টা করছেন timedelta, লিপ বছরের কারণে কোনও প্রান্তের ক্ষেত্রে সঠিকভাবে ব্যবহার করা যাবে না। উদাহরণস্বরূপ, 1 জানুয়ারী 2000 এ জন্মগ্রহণকারী, 1 জানুয়ারী, 2018 এর ঠিক 6575 দিন পরে 18 বছর বয়সে পরিণত হবে (5 টি লিপ বর্ষ অন্তর্ভুক্ত), কিন্তু 1 জানুয়ারী, 2001-এ জন্ম নেওয়া যে কেউ, 1 জানুয়ারীর ঠিক 6574 দিন পরে 18 বছর বয়সে পরিণত হবে, 2019 (4 লিপ বছর অন্তর্ভুক্ত)। সুতরাং, আপনি যদি ঠিক 65৫74৪ দিন বয়সী হন তবে আপনি তাদের জন্ম তারিখ সম্পর্কে আরও কিছু তথ্য না জেনে তারা 17 বা 18 বছর নির্ধারণ করতে পারবেন না।

এটি করার সঠিক উপায় হ'ল দু'বছর বিয়োগ করে তারিখগুলি থেকে সরাসরি বয়স গণনা করা, এবং তারপরে বর্তমান মাস / দিন জন্মের মাস / দিন পূর্বে যদি একটি বিয়োগ করে।


9

প্রথমে, সবচেয়ে বিস্তারিত স্তরে, সমস্যাটি ঠিকভাবে সমাধান করা যায় না can't বছরগুলি দৈর্ঘ্যে পরিবর্তিত হয় এবং বছরের দৈর্ঘ্যের জন্য একটি পরিষ্কার "সঠিক পছন্দ" নেই।

এটি বলেছিল, যে কোনও ইউনিট "প্রাকৃতিক" (সম্ভবত সেকেন্ড) যাই হোক না কেন তার মধ্যে পার্থক্য অর্জন করুন এবং বছর এবং বছরের মধ্যে অনুপাত দ্বারা ভাগ করুন। যেমন

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

...বা যাই হোক না কেন. কয়েক মাস থেকে দূরে থাকুন, যেহেতু তারা বছরের তুলনায় আরও কম সংজ্ঞাযুক্ত।


2
এটি কত বছর ধরে পরিষেবা বা একজন ব্যক্তি একটি নির্দিষ্ট বয়স অর্জন করেছে সে সম্পর্কে যখন প্রশ্ন হয় তখন কারও অর্থ বা ব্যবহার তা নয়।
জন মাচিন

3
গ্রেগরিয়ান ক্যালেন্ডারের 400 বছরের ব্যতিক্রম বিবেচনায় নিতে আপনার 365.25 হওয়া উচিত 365.2425।
ব্রায়ানারি

1
ঠিক আছে, সমস্যাটি সঠিকভাবে সমাধান করা যেতে পারে - আপনি সময়ের আগে বলতে পারবেন কোন বছরগুলিতে লিপ দিন এবং লিপ সেকেন্ড এবং সে সব have এটি ঠিক যে বছরগুলি, মাসগুলি, দিনগুলি, ইত্যাদি ... দুটি
বিভক্ত

7

এখানে একটি আপডেট করা ডিওবি ফাংশন রয়েছে, যা জন্মদিনের গণনা করে মানুষের মতো করে:

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

ডাব ২৯ ফেব্রুয়ারি হয় এবং বর্তমান বছরটি কোনও লিপ বছর নয় This
ট্রে হুনার

4

দিনের সংখ্যা পান, তারপরে বছরের পর বছর ধরে 365.2425 (গড় গ্রেগরিয়ান বছর) দ্বারা ভাগ করুন। কয়েক মাস ধরে 30.436875 (গড় গ্রেগরিয়ান মাস) দ্বারা ভাগ করুন।


2
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

29 ফেব্রুয়ারি জন্মগ্রহণকারী একজন ব্যক্তির নিম্নলিখিত 28 ফেব্রুয়ারি 1 বছর বয়স হিসাবে প্রাপ্ত হিসাবে গণ্য হবে।
জন মাচিন

ঠিক আছে. "জন্মদিন আজকের পরে" থেকে "আজকের আগের জন্মদিন" থেকে পরীক্ষা উল্টিয়ে 29 তম জন্মগ্রহণকারী জনগোষ্ঠীর 0.08% লোককে সমন্বিত করার জন্য সংশোধন করা হয়েছে। এটি কি সমাধান করে?
জন মে

এটি আপনার উদাহরণের জন্য সঠিকভাবে কাজ করে!!?! আমি যদি ২৮ শে ফেব্রুয়ারী ২০০৯ এ "আজ" সেট করে রাখি, এবং জন্মের তারিখ 29 ফেব্রুয়ারী 2008 এ এটি আমার জন্য জিরো ফিরিয়ে দেয়; আপনার পরামর্শ অনুসারে 1 নয় (পাইথন 2.5.2)। মিঃ মাচিনকে অসভ্য করার দরকার নেই। ঠিক কোন দুটি তারিখ নিয়ে আপনার সমস্যা হচ্ছে?
জন মে

আমি আবার চেষ্টা করব: 29 ফেব্রুয়ারি জন্মগ্রহণকারী একজন ব্যক্তির বেশিরভাগ লোকের দ্বারা সবচেয়ে বেশি আইনি কারণে নিম্নলিখিত 28 ফেব্রুয়ারিতে 1 বছর বয়সী হয়ে চিকিত্সা করা হবে। আপনার কোড আপনার "সংশোধন" এর আগে এবং পরে উভয়ই 0 উত্পাদন করে। প্রকৃতপক্ষে, আপনার কোডের দুটি সংস্করণ সমস্ত 9 ইনপুট সম্ভাবনার (মাসিক <==> এক্স দিন <==>) এর জন্য একই আউটপুট উত্পাদন করে। বিটিডাব্লু, 100.0 / (4 * 365 + 1) 0.068 নয়, 0.08 উত্পাদন করে।
জন মাচিন

2
দীর্ঘশ্বাস. (0) ২৯ ফেব্রুয়ারি ইস্যু সম্বোধন কোনও তারিখ গণিতের জন্য প্রয়োজনীয়; আপনি কেবল এটি উপেক্ষা করেছেন। (1) আপনার কোডটি প্রথমবারের চেয়ে ভাল ছিল না; "ঠিক একই আউটপুট উত্পাদন" তে আপনি কী বোঝেন না? (২) আজ.মেন্থ এবং dob.month এর তুলনা করে তিনটি সম্ভাব্য পারমাণবিক ফলাফল (<, ==,>); আজ.ডে এবং dob.day এর সাথে তুলনা করে তিনটি সম্ভাব্য পারমাণবিক ফলাফল; 3 * 3 == 9 (3) স্ট্যাকওভারফ্লো.com
জন মাচিন

1

আপনার এটি কতটা সঠিক হওয়া দরকার? td.days / 365.25আপনি লিপ বছর সম্পর্কে চিন্তিত হলে, আপনি খুব কাছাকাছি পাবেন।


আমি লিপ বছর সম্পর্কে সত্যিই চিন্তিত। কোনও ব্যক্তির 18 বছরের বেশি বয়সী কিনা তা পরীক্ষা করা উচিত।
মিগল

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

1

তবুও অন্য ২ য় পক্ষের লিবিটি এখানে উল্লেখ করা হয়নি এটি হ'ল এমএক্সডেটটাইম (উভয় দিকের পাইথন 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উদাহরণ হিসাবে প্রত্যাশিত ।

সাধারণ রূপান্তর datetimeকরতে 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)

এবং হ্যাঁ, প্রশ্নের মধ্যে এই একক কাজের জন্য নির্ভরতা যুক্ত করা টাইমটুল (রিক কোপল্যান্ডের প্রস্তাবিত) ব্যবহারের সাথে তুলনায় অবশ্যই একটি ওভারকিল হবে।


1

শেষ পর্যন্ত আপনার কাছে একটি গণিত ইস্যু। যদি প্রতি 4 বছর অন্তর আমাদের অতিরিক্ত দিন থাকে তবে 365 * 4 + 1 না করে 365 * 4 + 1 দ্বারা দিনের মধ্যে টাইমডেল্টা ডাইভ করে দেয়, এটি আপনাকে 4 বছরের পরিমাণ দিতে পারে। তারপরে এটিকে আবার ভাগ করুন 4 টাইমডেল্টা / ((365 * 4) +1) / 4 = টাইমডেল্টা * 4 / (365 * 4 +1)


লিপ ইয়ার জিনিসটি প্রযোজ্য হয় না যখন বছরগুলি 100 দ্বারা বিভাজ্য হয়, কেবলমাত্র যখন 400 দ্বারা বিভাজ্য হয়। একশো দ্বারা, সুতরাং এটি লাফানো উচিত নয় তবে ... - এটি 400 দ্বারা বিভাজ্য, সুতরাং এটি আসলে একটি লিপ বছর ছিল। 1900 এর জন্য: - এটি 4 দ্বারা বিভাজ্য তাই এটি লাফানো উচিত। - এটি 100 দ্বারা বিভাজ্য, তাই এটি লাফানো উচিত নয়। - এটি 400 দ্বারা বিভাজ্য নয়, সুতরাং এই বিধি প্রযোজ্য নয়। 1900 একটি লিপ বছর ছিল না।
Jblasco

1

এই সমাধানটি আমি কাজ করেছিলাম, আমি আশা করি সহায়তা করতে পারে ;-)

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

0

যদিও এই থ্রেডটি ইতিমধ্যে মারা গেছে, আমি কি একই সমস্যার মুখোমুখি হয়েছি তার জন্য একটি সমাধান সমাধানের পরামর্শ দিতে পারি। এটি এখানে (তারিখটি dd-mm-yyy ফরম্যাটের একটি স্ট্রিং):

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

0

এই ফাংশনটি দুটি তারিখের মধ্যে বছরের পার্থক্যটি প্রদান করে (আইএসও ফর্ম্যাটে স্ট্রিং হিসাবে নেওয়া, তবে এটি সহজেই কোনও ফর্ম্যাটে নিতে পরিবর্তন করতে পারে)

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

0

আমি পাইফডেটের পরামর্শ দেব

পাইফডিট কী?

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

অভিভাবকসংবঁধীয়


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


0

আমি এই প্রশ্নটি জুড়ে এসে অ্যাডামসকে সবচেয়ে সহায়ক https://stackoverflow.com/a/765862/2964689 এর উত্তর পেয়েছি

তবে তার পদ্ধতির কোনও অজগর উদাহরণ ছিল না তবে এখানে আমি কী ব্যবহার করে শেষ করেছি।

ইনপুট: ডেটটাইম অবজেক্ট

আউটপুট: পুরো বছরগুলিতে পূর্ণসংখ্যার বয়স

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

0

আমি জন মি এর সমাধানটিকে এর সরলতার জন্য পছন্দ করেছি এবং ২৮ শে ফেব্রুয়ারি জন্মগ্রহণকারী মানুষের বয়স নির্ধারণ করার জন্য ২৮ শে ফেব্রুয়ারি বা 1 মার্চ যখন লিপ বছর হয় না সে সম্পর্কে আমি উদ্বিগ্ন নই। তবে এখানে তার কোডের একটি টুইট যা আমি মনে করি অভিযোগগুলির সমাধান করে:

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
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.