पायथन में तारीखों की एक श्रृंखला बनाना


373

मैं आज से शुरू होने वाली तारीखों की एक सूची बनाना चाहता हूं, और 100 दिनों की एक अनियंत्रित संख्या वापस जा रहा हूं, कहते हैं, मेरे उदाहरण में 100 दिन हैं। क्या इससे बेहतर कोई उपाय है?

import datetime

a = datetime.datetime.today()
numdays = 100
dateList = []
for x in range (0, numdays):
    dateList.append(a - datetime.timedelta(days = x))
print dateList

जवाबों:


458

मार्जिन बेहतर ...

base = datetime.datetime.today()
date_list = [base - datetime.timedelta(days=x) for x in range(numdays)]

6
अगर आप टाइमज़ोन अवगत डेटाटाइम का उपयोग करते हैं तो यह काम नहीं करता है और डीएसटी की एक पारी है !!! मेरा मतलब है, जब आप एक शुरुआत और समाप्ति तिथि का उपयोग करते हैं और इसे इस तरह से
भरते हैं

@ s-lott क्या आप range(0, numdays)इस मामले में उपयोग नहीं कर सकते ?
लुकास जुहरीक

3
मैंने दस, 5 मिनट के अंतराल, +/- कुछ मूल्य (मेरे मामले में 30 सेकंड) उत्पन्न करने के लिए इस पद्धति का थोड़ा अलग तरीके से उपयोग किया। मुझे लगा कि मैं साझा करूँगा: datetimes = [start + timedelta(seconds=x*60+randint(-30, 30)) for x in range (0, range_end*5, 5)]जहाँ range_end = 10
मिकी

246

Pandas सामान्य रूप से समय श्रृंखला के लिए महान है, और तिथि सीमाओं के लिए प्रत्यक्ष समर्थन है।

उदाहरण के लिए pd.date_range():

import pandas as pd
from datetime import datetime

datelist = pd.date_range(datetime.today(), periods=100).tolist()

जीवन को आसान बनाने के लिए इसके पास बहुत सारे विकल्प हैं। उदाहरण के लिए यदि आप केवल कार्यदिवस चाहते हैं, तो आप बस स्वैप करेंगे bdate_range

दिनांक सीमा दस्तावेज़ देखें

इसके अलावा यह पूरी तरह से पाइट्ज़ टाइमज़ोन का समर्थन करता है और वसंत / शरद ऋतु डीएसटी बदलावों को आसानी से फैला सकता है।

ED द्वारा EDIT:

यदि आपको पंडों के टाइमस्टैम्प के विपरीत वास्तविक अजगर डेटेट की आवश्यकता है, तो:

import pandas as pd
from datetime import datetime

pd.date_range(end = datetime.today(), periods = 100).to_pydatetime().tolist()

#OR

pd.date_range(start="2018-09-09",end="2020-02-02")

यह मूल प्रश्न से मेल करने के लिए "अंत" पैरामीटर का उपयोग करता है, लेकिन यदि आप अवरोही तिथियां चाहते हैं:

pd.date_range(datetime.today(), periods=100).to_pydatetime().tolist()

22
पंडों को पहले से ही इस्तेमाल किया जा रहा है, तो सबसे अच्छा उत्तर दें। केवल एक चीज जो मैं जोड़ूंगा वह यह है कि यदि आप अपनी तारीखों को मूल पद के अनुसार पीछे ले जा रहे हैं तो आप अंत = पैरामीटर का उपयोग करेंगे। pd.date_range (अंत = pd.datetime.today (), अवधी = 100) .tolist ()
थॉमस ब्राउन

5
इस तरीके के साथ एक समस्या यह है कि जब आपको पायथन डेटाइम प्रकार की आवश्यकता होती है ... पंडों या संख्यात्मक तिथि सीमा विधियों का उपयोग करके टाइमस्टैम्प और डेटाटाइम 64 प्रकार बनाएंगे ... आपको डेटाटाइम list(map(pd.Timestamp.to_pydatetime, datelist))प्रकार वापस प्राप्त करने की आवश्यकता है ...
मलिक कोन

pandas.datetimeवर्ग पदावनत है और उसे भावी संस्करण में पांडा से निकाल दिया जाएगा। datetimeइसके बजाय मॉड्यूल से आयात करें ।
ट्रेंटन मैककिनी

82

निर्दिष्ट प्रारंभ और समाप्ति तिथि के बीच दिनांक की सीमा प्राप्त करें (समय और स्थान की जटिलता के लिए अनुकूलित):

import datetime

start = datetime.datetime.strptime("21-06-2014", "%d-%m-%Y")
end = datetime.datetime.strptime("07-07-2014", "%d-%m-%Y")
date_generated = [start + datetime.timedelta(days=x) for x in range(0, (end-start).days)]

for date in date_generated:
    print date.strftime("%d-%m-%Y")

6
प्रारंभिक सुझाव का उपयोग करना है () के बजाय [] के लिए एक date_generator पाने के लिए। इस अर्थ में कुशल कि तारीखों के पूरे सरणी को स्टोर करने और केवल जरूरत पड़ने पर एक उत्पन्न करने की आवश्यकता नहीं होगी।
संदीप

2
नोट end_date जनरेट नहीं हुआ है।
थोरबजोर्न रेवन एंडरसन

8
समाप्ति तिथि प्राप्त करने के लिए उपयोग (एंड-स्टार्ट + 1)।
संदीप

6
ओपी के सवाल का जवाब नहीं देता है, लेकिन यही मैं बाद में था :)
थियरी जे

2
(end-start+1)काम नहीं करता है, आप एक समयसीमा और int नहीं जोड़ सकते हैं। आप (end-start).days + 1हालांकि उपयोग कर सकते हैं ।
स्टीफन पॉलगर

44

आप एक जनरेटर फ़ंक्शन लिख सकते हैं जो आज से शुरू होने वाली तारीख वस्तुओं को लौटाता है:

import datetime

def date_generator():
  from_date = datetime.datetime.today()
  while True:
    yield from_date
    from_date = from_date - datetime.timedelta(days=1)

यह जनरेटर आज से शुरू होने वाली तारीखें और एक दिन में एक दिन पीछे की ओर जा रहा है। यहां बताया गया है कि पहली 3 तारीखें कैसे लें:

>>> import itertools
>>> dates = itertools.islice(date_generator(), 3)
>>> list(dates)
[datetime.datetime(2009, 6, 14, 19, 12, 21, 703890), datetime.datetime(2009, 6, 13, 19, 12, 21, 703890), datetime.datetime(2009, 6, 12, 19, 12, 21, 703890)]

एक लूप या सूची समझ पर इस दृष्टिकोण का लाभ यह है कि आप जितनी बार चाहें उतनी बार वापस जा सकते हैं।

संपादित करें

एक फ़ंक्शन के बजाय एक जनरेटर अभिव्यक्ति का उपयोग करके एक अधिक कॉम्पैक्ट संस्करण:

date_generator = (datetime.datetime.today() - datetime.timedelta(days=i) for i in itertools.count())

उपयोग:

>>> dates = itertools.islice(date_generator, 3)
>>> list(dates)
[datetime.datetime(2009, 6, 15, 1, 32, 37, 286765), datetime.datetime(2009, 6, 14, 1, 32, 37, 286836), datetime.datetime(2009, 6, 13, 1, 32, 37, 286859)]

1
जेनरेटर ऐसा करने का आदर्श तरीका है, यदि दिनों की संख्या मनमानी है।
xssChauhan

32

हाँ, पहिए को फिर से मजबूत करें .... बस मंच खोजें और आपको कुछ इस तरह मिलेगा:

from dateutil import rrule
from datetime import datetime

list(rrule.rrule(rrule.DAILY,count=100,dtstart=datetime.now()))

22
Labix.org/python-dateutil की आवश्यकता है । अच्छा लग रहा है, लेकिन सिर्फ एक लाइन को बचाने के लिए एक बाहरी निर्भरता के लायक है।
बेनी चेर्नियाव्स्की-पास्किन

1
किसी को विश्वास नहीं हो सकता कि अन्य उत्तर बहुत ही आकर्षक हैं। जबकि कर्कश एक भयानक नाम है, यह कम से कम आंखों पर आसान है।
नाविक

7
@ BeniCherniavsky-Paskin: अवधि (कैलेंडर) के अंकगणितीय को लागू करते समय सूक्ष्म कीड़े को पेश करना बहुत आसान है। dateutil.rruleकार्यान्वयन iCalendar RFC - लगभग समान कार्यक्षमता के कई कार्यान्वयनों के बजाय एक अच्छी तरह से परिभाषित व्यवहार के साथ कार्यों का उपयोग करना आसान है जो कभी इतने अलग होते हैं। dateutil.rruleबग फिक्सिंग को एक ही स्थान पर सीमित करने की अनुमति देता है।
jfs

3
@ Mark0978: rruleनाम मनमाना नहीं है; यह से है इसी आरएफसी
JFS

1
हाँ, मैं नामों की दुर्भाग्यपूर्ण पसंद के लिए डेटूटिल को दोषी नहीं ठहरा रहा था :-)
नाविक

32

आप इसे सरल बनाने के लिए दिन के क्रम का भी उपयोग कर सकते हैं:

def date_range(start_date, end_date):
    for ordinal in range(start_date.toordinal(), end_date.toordinal()):
        yield datetime.date.fromordinal(ordinal)

या जैसा कि टिप्पणियों में सुझाया गया है आप इस तरह से एक सूची बना सकते हैं:

date_range = [
    datetime.date.fromordinal(ordinal) 
    for ordinal in range(
        start_date.toordinal(),
        end_date.toordinal(),
    )
]

18

इस प्रश्न के शीर्षक से मैं उम्मीद कर रहा था range()कि मुझे कुछ ऐसा मिलेगा , जो मुझे दो तिथियों को निर्दिष्ट करने और बीच में सभी तिथियों के साथ एक सूची बनाने देगा। इस तरह से किसी को उन दो तिथियों के बीच दिनों की संख्या की गणना करने की आवश्यकता नहीं है, अगर कोई इसे पहले से नहीं जानता है।

इसलिए थोड़ा-सा विषय होने के जोखिम के साथ, यह एक-लाइनर काम करता है:

import datetime
start_date = datetime.date(2011, 01, 01)
end_date   = datetime.date(2014, 01, 01)

dates_2011_2013 = [ start_date + datetime.timedelta(n) for n in range(int ((end_date - start_date).days))]

सभी इस उत्तर का श्रेय देते हैं !


1
यह प्रश्न के अन्य उत्तरों में से कई से अधिक एक एक लाइनर नहीं है।
थॉमस ब्राउन

4
मैंने कभी यह ढोंग नहीं किया कि यह दूसरों के जवाबों की तुलना में अधिक एक-लाइनर था, न ही यह एक बेहतर समाधान था। मैंने एक कोड दिखाया, जो आपके द्वारा मांगे जाने से थोड़ा अलग है, लेकिन मुझे यह जानकर खुशी हुई कि यहां मुझे प्रश्न का शीर्षक दिया गया है।
सर्प_चर।

11

यहाँ S.Lott के जवाब यह है कि दो तिथियों के बीच तिथियों की सूची देता है के बंद का निर्माण एक अलग जवाब startऔर end। नीचे दिए गए उदाहरण में, 2017 की शुरुआत से लेकर आज तक।

start = datetime.datetime(2017,1,1)
end = datetime.datetime.today()
daterange = [start + datetime.timedelta(days=x) for x in range(0, (end-start).days)]

7

थोड़ा सा उत्तर मुझे पता है, लेकिन मुझे बस एक ही समस्या थी और यह तय किया कि पायथन की आंतरिक रेंज फ़ंक्शन इस संबंध में थोड़ी कमी थी, इसलिए मैंने इसे मेरे उपयोग के मॉड्यूल में ओवरराइड कर दिया।

from __builtin__ import range as _range
from datetime import datetime, timedelta

def range(*args):
    if len(args) != 3:
        return _range(*args)
    start, stop, step = args
    if start < stop:
        cmp = lambda a, b: a < b
        inc = lambda a: a + step
    else:
        cmp = lambda a, b: a > b
        inc = lambda a: a - step
    output = [start]
    while cmp(start, stop):
        start = inc(start)
        output.append(start)

    return output

print range(datetime(2011, 5, 1), datetime(2011, 10, 1), timedelta(days=30))

1
मुझे लगता है कि आप चाहते हैं output = []और while cmp(...)लूप में लाइनों को स्वैप करना चाहते हैं । तुलना range(0,10,1)और _range(0,10,1)
सिगफैप

3
मुझे लगता है कि यदि आप फ़ंक्शन का नाम लेते हैं तो यह उत्तर बेहतर होगा date_range
ब्रैंडन ब्रैडले

7

उत्तर के आधार पर मैंने अपने लिए यह लिखा:

import datetime;
print [(datetime.date.today() - datetime.timedelta(days=x)).strftime('%Y-%m-%d') for x in range(-5, 0)]

आउटपुट:

['2017-12-11', '2017-12-10', '2017-12-09', '2017-12-08', '2017-12-07']

अंतर यह है कि मुझे ' date’वस्तु मिलती है, get datetime.datetime’ एक ’ ’ नहीं ।


7

यदि दो तिथियां हैं और आपको रेंज ट्राइ की जरूरत है

from dateutil import rrule, parser
date1 = '1995-01-01'
date2 = '1995-02-28'
datesx = list(rrule.rrule(rrule.DAILY, dtstart=parser.parse(date1), until=parser.parse(date2)))

5

यहाँ मैं अपने खुद के कोड से बनाया गया है, यह मदद कर सकता है। (मुझे पता है कि प्रश्न बहुत पुराना है, लेकिन अन्य इसका उपयोग कर सकते हैं)

https://gist.github.com/2287345

(नीचे एक ही बात)

import datetime
from time import mktime

def convert_date_to_datetime(date_object):
    date_tuple = date_object.timetuple()
    date_timestamp = mktime(date_tuple)
    return datetime.datetime.fromtimestamp(date_timestamp)

def date_range(how_many=7):
    for x in range(0, how_many):
        some_date = datetime.datetime.today() - datetime.timedelta(days=x)
        some_datetime = convert_date_to_datetime(some_date.date())
        yield some_datetime

def pick_two_dates(how_many=7):
    a = b = convert_date_to_datetime(datetime.datetime.now().date())
    for each_date in date_range(how_many):
        b = a
        a = each_date
        if a == b:
            continue
        yield b, a

4

सप्ताह की सूची प्राप्त करने के लिए बैश स्क्रिप्ट के लिए एक लाइनर है, यह अजगर है 3. जो कुछ भी आसानी से संशोधित किया जाता है, अंत में इंट आप चाहते हैं कि अतीत में दिनों की संख्या है।

python -c "import sys,datetime; print('\n'.join([(datetime.datetime.today() - datetime.timedelta(days=x)).strftime(\"%Y/%m/%d\") for x in range(0,int(sys.argv[1])) if (datetime.datetime.today() - datetime.timedelta(days=x)).isoweekday()<6]))" 10

यहां एक शुरुआत (या बल्कि, समाप्ति) तारीख प्रदान करने के लिए एक संस्करण है

python -c "import sys,datetime; print('\n'.join([(datetime.datetime.strptime(sys.argv[1],\"%Y/%m/%d\") - datetime.timedelta(days=x)).strftime(\"%Y/%m/%d \") for x in range(0,int(sys.argv[2])) if (datetime.datetime.today() - datetime.timedelta(days=x)).isoweekday()<6]))" 2015/12/30 10

यहां मनमाना शुरुआत और समाप्ति तिथियों के लिए एक संस्करण है। ऐसा नहीं है कि यह बहुत कुशल नहीं है, लेकिन बैश स्क्रिप्ट में लूप के लिए डालने के लिए अच्छा है:

python -c "import sys,datetime; print('\n'.join([(datetime.datetime.strptime(sys.argv[1],\"%Y/%m/%d\") + datetime.timedelta(days=x)).strftime(\"%Y/%m/%d\") for x in range(0,int((datetime.datetime.strptime(sys.argv[2], \"%Y/%m/%d\") - datetime.datetime.strptime(sys.argv[1], \"%Y/%m/%d\")).days)) if (datetime.datetime.strptime(sys.argv[1], \"%Y/%m/%d\") + datetime.timedelta(days=x)).isoweekday()<6]))" 2015/12/15 2015/12/30

अपनी टिप्पणी में कोड के साथ अपने उत्तर पोस्ट को अपडेट करना चाह सकते हैं। अजगर टिप्पणियों में उलझ जाता है, और थोड़े को प्रारूपण की आवश्यकता होती है।
जेक बाथमैन

3

माटप्लोटलिब संबंधी

from matplotlib.dates import drange
import datetime

base = datetime.date.today()
end  = base + datetime.timedelta(days=100)
delta = datetime.timedelta(days=1)
l = drange(base, end, delta)

3

मुझे पता है कि यह उत्तर दिया गया है, लेकिन मैं ऐतिहासिक उद्देश्यों के लिए अपना जवाब नीचे रखूंगा, और जब से मुझे लगता है कि यह सीधे आगे है।

import numpy as np
import datetime as dt
listOfDates=[date for date in np.arange(firstDate,lastDate,dt.timedelta(days=x))]

यकीन है कि यह कोड-गोल्फ की तरह कुछ भी नहीं जीतेगा, लेकिन मुझे लगता है कि यह सुरुचिपूर्ण है।


arangeचरणों के साथ काफी अच्छा है, लेकिन listOfDatesके होते हैं numpy datetime64 अजगर देशी datetimes के बजाय।
F.Aaab

2
लेकिन अगर आप उपयोग कर सकते हैं np.arange(…).astype(dt.datetime)बनाने के लिए arangeदेशी अजगर datetime लौट numpy datetime64 के बजाय।
F.Raab

2

एक और उदाहरण जो संदीप के जवाब से शुरू होकर आगे या पीछे की ओर गिना जाता है।

from datetime import date, datetime, timedelta
from typing import Sequence
def range_of_dates(start_of_range: date, end_of_range: date) -> Sequence[date]:

    if start_of_range <= end_of_range:
        return [
            start_of_range + timedelta(days=x)
            for x in range(0, (end_of_range - start_of_range).days + 1)
        ]
    return [
        start_of_range - timedelta(days=x)
        for x in range(0, (start_of_range - end_of_range).days + 1)
    ]

start_of_range = datetime.today().date()
end_of_range = start_of_range + timedelta(days=3)
date_range = range_of_dates(start_of_range, end_of_range)
print(date_range)

देता है

[datetime.date(2019, 12, 20), datetime.date(2019, 12, 21), datetime.date(2019, 12, 22), datetime.date(2019, 12, 23)]

तथा

start_of_range = datetime.today().date()
end_of_range = start_of_range - timedelta(days=3)
date_range = range_of_dates(start_of_range, end_of_range)
print(date_range)

देता है

[datetime.date(2019, 12, 20), datetime.date(2019, 12, 19), datetime.date(2019, 12, 18), datetime.date(2019, 12, 17)]

ध्यान दें कि प्रारंभ तिथि रिटर्न में शामिल है, इसलिए यदि आप चार कुल तिथियां चाहते हैं, तो उपयोग करें timedelta(days=3)


1
from datetime import datetime, timedelta
from dateutil import parser
def getDateRange(begin, end):
    """  """
    beginDate = parser.parse(begin)
    endDate =  parser.parse(end)
    delta = endDate-beginDate
    numdays = delta.days + 1
    dayList = [datetime.strftime(beginDate + timedelta(days=x), '%Y%m%d') for x in range(0, numdays)]
    return dayList

1

एक मासिक तिथि सीमा के साथ जनरेटर datetimeऔर dateutil। सरल और समझने में आसान:

import datetime as dt
from dateutil.relativedelta import relativedelta

def month_range(start_date, n_months):
        for m in range(n_months):
            yield start_date + relativedelta(months=+m)

0
import datetime    
def date_generator():
    cur = base = datetime.date.today()
    end  = base + datetime.timedelta(days=100)
    delta = datetime.timedelta(days=1)
    while(end>base):
        base = base+delta
        print base

date_generator()

1
वह वापस जाना चाहता था, आगे नहीं .. तो endहोना चाहिए base - datetime.timedelta। इसके अलावा ... यह समाधान मूल से बेहतर क्यों है?
frarugi87

0

उपरोक्त उत्तरों से मैंने दिनांक जनरेटर के लिए यह उदाहरण बनाया

import datetime
date = datetime.datetime.now()
time = date.time()
def date_generator(date, delta):
  counter =0
  date = date - datetime.timedelta(days=delta)
  while counter <= delta:
    yield date
    date = date + datetime.timedelta(days=1)
    counter +=1

for date in date_generator(date, 30):
   if date.date() != datetime.datetime.now().date():
     start_date = datetime.datetime.combine(date, datetime.time())
     end_date = datetime.datetime.combine(date, datetime.time.max)
   else:
     start_date = datetime.datetime.combine(date, datetime.time())
     end_date = datetime.datetime.combine(date, time)
   print('start_date---->',start_date,'end_date---->',end_date)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.