datetime ও time মডিউল

datetime ও time মডিউল

“সময় ও নদীর স্রোত কারও জন্য অপেক্ষা করে না” - শিশুকাল থেকে এই বাক্য শুনতে শুনতে আমরা ক্লান্ত। কিন্তু তারপরও সময়ের দাম দিতে পেরেছি কজন? যারা পেরেছি তারা এখন উন্নতির চরম শিখরে অবস্থান করছি আর যারা পারিনি তারা তেলাপোকার মতো বেঁচে আছি। “অতিকায় হস্তী লোপ পাইয়াছে, কিন্তু তেলাপোকা টিকিয়া আছে।” টিকিয়া আছে তো থাকুক, আমাদের কী? আমাদের টপিক তেলাপোকার জন্মরহস্যের ওপরে নয়। আমরা শিখব পাইথনে কীভাবে তারিখ ও সময়কে হ্যান্ডেল করা যায় তার উপায়।

datetime মডিউল

তারিখ ও সময় নিয়ে খেলাধুলার যাবতীয় ক্লাসের ভান্ডার হলো ডেটটাইম মডিউল। এই মডিউলে আমরা দুই ধরনের ডেট ও টাইম অবজেক্ট নিয়ে কথা বলব। একটি হলো aware (অ্যাওয়ার) এবং অন্যটি হলো naive (নাইভ)। অ্যাওয়ার অবজেক্টে টাইমজোন ও ডে-লাইট সেভিং সম্পর্কে পর্যাপ্ত তথ্য থাকে। ফলে সহজেই অন্য অ্যাওয়ার অবজেক্টের সাথে সম্পর্কিত করা যায়। কিন্তু নাইভ অবজেক্টকে অন্যান্য ডেট ও টাইস অবজেক্টের সাথে সম্পর্কিত করা যায় না।

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

datetime.date()

এই ক্লাসের প্যারামিটার তিনটি - year, month, day। সবগুলো প্যারামিটার ইন্টিজার টাইপের। সবগুলো প্যারামিটার যথাযথভাবে পাস করলে একটি date অবজেক্ট পাওয়া যায়। date অবজেক্ট তৈরি করার পর, ক্লাসের বিভিন্ন মেথডের সাহায্যে জাতিকে পাইথনিক ম্যাজিক দেখানো যায়।

>>> from datetime import date
>>> date(2018, 2, 9)
datetime.date(2018, 2, 9)

date.today() মেথড আজকের তারিখ (আঞ্চলিক সময়) রিটার্ন করে।

>>> from datetime import date
>>> date.today()
datetime.date(2018, 2, 9)

date.today() মেথড ব্যবহার করে পাওয়া বা যেকোনো date অবজেক্টকে আমরা কয়েকভাবে অ্যাক্সেস করতে পারি।

>>> from datetime import date
>>> a = date.today()
>>> a.year
2018
>>> from datetime import date
>>> my_date = date.today()
>>> print(my_date.year)
2018
>>> print(my_date.month)
2
>>> print(my_date.day)
9

আবার কোনো date অবজেক্টের অ্যাট্রিবিউটের ভ্যালু চেঞ্জ করতে চাইলে date.replace(year=self.year, month=self.month, day=self.day) মেথড ব্যবহার করতে পারি।

>>> from datetime import date
>>> my_date = date.today()
>>> my_date
datetime.date(2018, 2, 9)
>>> my_date.replace(1996, 10, 23)
datetime.date(1996, 10, 23)
>>> my_date
datetime.date(2018, 2, 9)
>>> my_date = my_date.replace(1996, 10, 23)
>>> my_date
datetime.date(1996, 10, 23)

স্ট্রিং ফরম্যাটিংয়ের মতো করে ডেটও ফরম্যাট করা যায়। এ জন্য date.strftime(format) মেথড ব্যবহার করা হয়। এই মেথড ফরম্যাট কোডকে আর্গুমেন্ট হিসেবে নেয়। প্রথমেই আমরা প্রচলিত ফরম্যাট কোডগুলোকে দেখে নেব একনজর।

ফরম্যাট কোড কোডের মানে উদাহরণ
%d শূন্যসংবলিত দিনে 01, 02, …, 31
%b সংক্ষেপে মাসের নাম Jan, Feb, …, Dec
%B সম্পূর্ণ মাসের নাম January, February, …, December
%m শূন্যসংবলিত মাস 01, 02, …, 12
%y শূন্যসংবলিত সংক্ষিপ্ত সাল 00, 01, …, 99
%Y শূন্যসংবলিত পূর্ণাঙ্গ সাল 0001, 0002, …, 2018, 2017, …, 9998, 9999
%H শূন্যসংবলিত ঘণ্টা (২৪ ঘণ্টার ঘড়ি) 00, 01, …, 23
%I শূন্যসংবলিত ঘণ্টা (১২ ঘণ্টার ঘড়ি) 00, 01, …, 12
%M শূন্যসংবলিত মিনিট 00, 01, …, 59
%S শূন্যসংবলিত সেকেন্ড 00, 01, …, 59
%Z টাইমজোনের নাম (naive অবজেক্টের ক্ষেত্রে ফাঁকা স্ট্রিং) (empty), UTC, EST, CST
%c যথাযথভাবে তারিখ ও সময় প্রদর্শন Tue Oct 23 05:15:00 1996
%x যথাযথভাবে তারিখ প্রদর্শন 23/10/1996
%X যথাযথভাবে সময় প্রদর্শন 05:15:00
%p AM বা PM প্রদর্শন AM, PM

এখন আমরা প্রচলিত ফরম্যাট কোডগুলো জানি। তাহলে একটি প্রোগ্রাম লিখে ফেলা যাক!

>>> from datetime import date
>>> my_date = date.today()
>>> my_date
datetime.date(2018, 2, 9)
>>> my_date.strftime('%d %B, %Y')
'09 February, 2018'

কী সুন্দরভাবে ফরম্যাট করে ফেললাম! শুধু একটা জিনিস মনে রাখতে হবে, ফরম্যাট কোডগুলোকে স্ট্রিংয়ের মতো করে পাস করতে হবে।

datetime.time()

এই ক্লাসের কয়েকটি প্যারামিটার আছে - hour=0, minute=0, second=0, microsecond=0, tzinfo=None, *, fold=0। সবগুলো প্যারামিটারই অপশনাল আর ইন্টিজার। ঠিকভাবে প্যারামিটার পাস করলে একটা time অবজেক্ট পাওয়া যায়। অবজেক্ট তো পেলাম কিন্তু সেই অবজেক্ট নিয়ে খেলা করব কীভাবে? এবার সেটাই আমরা শিখব।

>>> from datetime import time
>>> time(5, 15, 00)
datetime.time(5, 15)

এই time অবজেক্টকে আমরা কয়েকভাবে অ্যাক্সেস করতে পারি।

>>> from datetime import time
>>> t = time(5, 15, 00)
>>> t.hour
5
>>> t.minute
15
>>> t.second
0
>>> t.microsecond
0

টাইম অবজেক্টের বিভিন্ন অ্যাট্রিবিউটের ভ্যালু চেঞ্জ করার জন্য আমরা কিছু মেথড ব্যবহার করতে পারি। যেমন:

time.replace(hour=self.hour, minute=self.minute, second=self.second, microsecond=self.microsecond, tzinfo=self.tzinfo, * fold=0)
>>> from datetime import time
>>> t = time(5, 15, 00)
>>> t
datetime.time(5, 15)
>>> t.replace(21, 29, 45)
datetime.time(21, 29, 45)

এবার আসা যাক টাইম অবজেক্ট ফরম্যাটিংয়ের বিষয়ে। এ জন্য আমরা time.strftime(format) মেথড ব্যবহার করব।

>>> from datetime import time
>>> t = time(5, 15, 00)
>>> t
datetime.time(5, 15)
>>> t.strftime('%I:%M:%S')
'05:15:00'
datetime.datetime()

এই ক্লাসের প্যারামিটার অনেকগুলো- year, month, day, hour=0, minute=0, second=0, microsecond=0, tzinfo=None, *, fold=0। এর মধ্যে বছর, মাস ও দিন হলো রিকোয়ার্ড প্যারামিটার। tzinfo দিয়ে টাইমজোন ইনফরম্যাশন বোঝায়। এটি নিয়ে এখনই হতাশ হওয়ার কিছু নেই। একটু পরেই আমরা আলোচনা-পর্যালোচনা করব। যাহোক, এই ক্লাসে যথাযথভাবে প্যারামিটার পাস করলে একটা datetime অবজেক্ট পাওয়া যায়, যাতে date অবজেক্ট ও time অবজেক্টের সব ইনফরমেশন থাকে। এবার এই অবজেক্টের ওপর আমরা কয়েকটা মেথড অ্যাপ্লাই করব।

datetime.today()datetime.now(tz=None) বর্তমান তারিখ ও সময় (আঞ্চলিক সময়) রিটার্ন করে, মেথড দুটির মধ্যে কোনো পার্থক্য নেই। তবে datetime.now() মেথডে যদি tzinfo সাবক্লাসের কোনো ইনস্ট্যান্স পাস করা হয়, সে ক্ষেত্রে টাইমজোন অনুসারে সবকিছু বদলে যাবে।

>>> from datetime import datetime
>>> datetime.today()
datetime.datetime(2018, 2, 9, 22, 49, 33, 78253)
>>> datetime.now()
datetime.datetime(2018, 2, 9, 22, 49, 49, 886479)

datetime.utcnow() মেথড বর্তমান UTC (গ্রিনউইচ মানমন্দির সাপেক্ষে) তারিখ ও সময় রিটার্ন করবে।

>>> from datetime import datetime
>>> datetime.utcnow()
datetime.datetime(2018, 2, 9, 16, 50, 6, 309991)

ওপরের তিনটি মেথড ব্যবহার করে পাওয়া বা যেকোনো datetime অবজেক্টকে আমরা চাইলে বিভিন্নভাবে অ্যাক্সেস করতে পারি। যেমন:

>>> from datetime import datetime
>>> temp = datetime.now()
>>> temp
datetime.datetime(2018, 2, 9, 22, 50, 25, 678815)
>>> temp.year
2018
>>> temp.month
2
>>> temp.day
9
>>> temp.hour
22
>>> temp.minute
50
>>> temp.second
25
>>> temp.microsecond
678815

datetime.strptime(date_string, format) মেথডের সাহায্যে একটি ডেট স্ট্রিংকে ফরম্যাট করে datetime অবজেক্টে কনভার্ট করা যায়। আমরা যেহেতু ফরম্যাট কোড শিখেছি। সুতরাং সরাসরি কাজ শুরু করা যাক:

>>> from datetime import datetime
>>> temp = '05:15:00 AM 23 October, 1996'
>>> datetime.strptime(temp, '%I:%M:%S %p %d %B, %Y')
datetime.datetime(1996, 10, 23, 5, 15)

ডেটটাইম অবজেক্টের কোনো অ্যাট্রিবিউটের ভ্যালু চেঞ্জ করতে চাইলে আমাদের কিছু মেথড ব্যবহার করতে হবে। যেমন:

datetime.replace(year=self.year, month=self.month, day=self.day, hour=self.hour, minute=self.minute, second=self.second, microsecond=self.microsecond, tzinfo=self.tzinfo, * fold=0)

একটি উদাহরণ দেখা যাক :

>>> from datetime import datetime
>>> temp = datetime.now()
>>> temp
datetime.datetime(2018, 2, 9, 22, 51, 58, 304110)
>>> temp.replace(year=1996, month=10, day=23, hour=5, minute=15)
datetime.datetime(1996, 10, 23, 5, 15, 58, 304110)

এবার আসা যাক datetime অবজেক্ট ফরম্যাটিংয়ের বিষয়ে। datetime.strftime(format) মেথডের সাহায্যে আমরা খুব চমৎকারভাবে datetime অবজেক্টকে ফরম্যাট করতে পারি। এখানেও আমাদের ফরম্যাট কোড ব্যবহার করতে হবে।

>>> from datetime import datetime
>>> temp = datetime.now()
>>> temp
datetime.datetime(2018, 2, 9, 22, 51, 58, 304110)
>>> temp.strftime('%I:%M:%S %p %d %B, %Y')
'10:51:58 PM 09 February, 2018'

এবার আমরা একটা জোড়াতালির পদ্ধতি দেখব:

>>> from datetime import datetime, date, time
>>> my_date = date(1994, 10, 23)
>>> my_time = time(5, 15, 00)
>>> datetime.combine(my_date, my_time)
datetime.datetime(1994, 10, 23, 5, 15)

এখানে আমরা একটি date অবজেক্ট ও একটি time অবজেক্টকে সমন্বিত করে একটি datetime অবজেক্ট তৈরি করেছি।

time মডিউল

এই মডিউলের সহায়তায় আমরা সময়কে আরও বেশি নিয়ন্ত্রণ করতে পারব। আসলে datetime.time() ক্লাসের চেয়ে time মডিউল আরও বিস্তর এবং ব্যাপক।

time.gmtime()

time.struct_time ক্লাসের অবজেক্ট হিসেবে UTC (গ্রিনউইচ মান মন্দির) সময় রিটার্ন করে। যেমন:

>>> import time
>>> time.gmtime()
time.struct_time(tm_year=2018, tm_mon=2, tm_mday=9, tm_hour=16, tm_min=53, tm_sec=20, tm_wday=4, tm_yday=40, tm_isdst=0)

time.localtime()

time.struct_time ক্লাসের অবজেক্ট হিসেবে লোকাল টাইম (বাংলাদেশের ক্ষেত্রে UTC+6) রিটার্ন করে। যেমন:

>>> import time
>>> time.localtime()
time.struct_time(tm_year=2018, tm_mon=2, tm_mday=9, tm_hour=22, tm_min=53, tm_sec=40, tm_wday=4, tm_yday=40, tm_isdst=0)

time.strptime(string[, format])

টাইম স্ট্রিংকে ফরম্যাট অনুসারে time.struct_time ক্লাসের অবজেক্টে কনভার্ট করে। ফরম্যাট কিন্তু আমরা আগেই শিখেছি। ওই এক গানই সব সময় গাইতে হবে। অফিশিয়াল ডক থেকে একটা উদাহরণ দেখা যাক:

>>> import time
>>> time.strptime("30 Nov 00", "%d %b %y")
time.struct_time(tm_year=2000, tm_mon=11, tm_mday=30, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=335, tm_isdst=-1)

time.struct_time

এই ক্লাসের কথা ইতিমধ্যে আলোচনা হয়েছে। gmtime(), localtime()strptime() ফাংশন এই ক্লাসের অবজেক্ট রিটার্ন করে যা আসলে একটা টাপল; মূলত TimeTuple হিসেবে সুপরিচিত। অবজেক্টের ভ্যালুগুলো ইনডেক্স বা অ্যাট্রিবিউটের নাম অনুসারে অ্যাক্সেস করা যায়।

ইনডেক্স অ্যাট্রিবিউট ভ্যালু
0 tm_year যেমন 2018
1 tm_mon range [1, 12]
2 tm_mday range [1, 31]
3 tm_hour range [0, 23]
4 tm_min range [0, 59]
5 tm_sec range [0, 61]
6 tm_wday range [0, 6], 0 দিয়ে সোমবার বোঝায়
7 tm_yday range [1, 366]
8 tm_isdst 1 যখন ডে-লাইট সেভিংস টাইম চালু থাকে, 0 যখন চালু থাকে না এবং -1 যখন চালু আছে কি না, সেটা জানা যায় না।

একটি উদাহরণ দেখা যাক :

>>> import time
>>> t = time.localtime()
>>> t
time.struct_time(tm_year=2018, tm_mon=2, tm_mday=9, tm_hour=22, tm_min=54, tm_sec=37, tm_wday=4, tm_yday=40, tm_isdst=0)
>>> t.tm_year
2018
>>> t[0]
2018
>>> t.tm_mon
2
>>> t[1]
2
>>> t.tm_mday
9
>>> t[2]
9

time.time()

সেকেন্ডের স্কেলে (যেমন 2s, 4.1s) কারেন্ট টাইম রিটার্ন করে (ফ্লোটিং পয়েন্ট নম্বর হিসেবে)। ডেকোরেটর চ্যাপ্টারে কম্পিউটেশনাল কস্ট হিসাব করতে ব্যবহার করেছিলাম আমরা।

import time

start = time.time()
count = 0
while count <= 1000:
    count += 1
stop = time.time()
print('Computational cost:', stop-start)

আউটপুট

Computational cost: 0.00016188621520996094

time.clock()

এটি খুব দরকারি একটি ফাংশন। সেকেন্ডের স্কেলে (যেমন 2s, 4.1s) বর্তমান সিপিইউ টাইম রিটার্ন করে (ফ্লোটিং পয়েন্ট নম্বর হিসেবে)। বিভিন্ন কম্পিউটেশনাল কস্ট হিসাব করতে time.time()-এর চেয়ে বেশি কার্যকরী। যেমন:

import time

start = time.clock()
count = 0
while count <= 1000:
    count += 1
stop = time.clock()
print('Computational cost:', stop-start)

আউটপুট

Computational cost: 0.0001735687255859375

time.sleep(secs)

ঝিমাইন্না মুরগি। থুরি, ঝিমাইন্না প্রোগ্রাম বানানোর ক্ষেত্রে এই ফাংশন প্রয়োগ করা হয়। কখন‌ো কখনো কোনো প্রোগ্রামের মধ্যে কলিং থ্রেডকে কিছুক্ষণের জন্য ঝিম ধরিয়ে রাখার দরকার পড়ে। অর্থাৎ ওই সময় ওই ব্লকে এসে প্রোগ্রামটি এক্সিকিউট হবে না। এ কাজের জন্য time.sleep() ফাংশন ব্যবহার করা হয়।

import time

start = time.time()
time.sleep(3)
stop = time.time()
print('Computational cost:', stop-start)

আউটপুট

Computational cost: 3.003114938735962

আউটপুট দেখেই বোঝা যাচ্ছে যে প্রোগ্রামটা ৩ সেকেন্ড ঝিমাইছে, উমাইন্না মুরগির মতো!

time.strftime(format[, t])

টাইম টাপলকে স্ট্রিংয়ে ফরম্যাট করার জন্য আমরা এই ফাংশন ব্যবহার করব। ফরম্যাট ওই আগেরগুলোই। একটি উদাহরণ দেখা যাক:

>>> import time
>>> t = time.gmtime()
>>> t
time.struct_time(tm_year=2018, tm_mon=2, tm_mday=9, tm_hour=16, tm_min=57, tm_sec=21, tm_wday=4, tm_yday=40, tm_isdst=0)
>>> time.strftime('%I:%M:%S %p %d %B, %Y', t)
'04:57:21 PM 09 February, 2018'
time.strptime(string[, format])

এ ফাংশনটি হলো time.strftime() ফাংশনের উল্টা। একটি ডেট-টাইম স্ট্রিংকে টাইমটাপলে কনভার্ট করার জন্য এ ফাংশনটি ব্যবহার করা হয়।

>>> import time
>>> time.strptime('04:57:21 PM 09 February, 2018', '%I:%M:%S %p %d %B, %Y')
time.struct_time(tm_year=2018, tm_mon=2, tm_mday=9, tm_hour=16, tm_min=57, tm_sec=21, tm_wday=4, tm_yday=40, tm_isdst=-1)

এই হলো মোটামুটি কাহিনি। টাইমজোন জটিলতায় আমরা গেলাম না। আপাতত এই চ্যাপ্টারের অংশটুকু জানলেই আমাদের কাজ চলবে। তবে পাইথনের অফিশিয়াল ডকুমেন্ট থেকে datetime নিয়ে আরও জানতে https://docs.python.org/3/library/datetime.html এই লিংকে এবং time নিয়ে আরও জানতে এই লিংকে - https://docs.python.org/3/library/time.html ঘুরে আসতে পারেন।

comments powered by Disqus