"তারিখ আর সময় এমন একটা বিষয় যা আমরা ছোট শিশুদের শেখাই। এটা আবার কতটা কঠিন হতে পারে?"
অনেক প্রোগ্রামারই ওই ভুলটি করেছেন, আর তার পরের অভিজ্ঞতা সাধারণত তাদের স্বাস্থ্য ও সুখের ওপর খারাপ প্রভাব ফেলে।
তারিখ ও সময় নিয়ে একটু জটিল প্রোগ্রামিং করছেন এমন যে কেউ অন্তত সম্ভাব্য সমস্যাগুলো বোঝার ও সেগুলো কমিয়ে আনার জন্য প্রস্তুত থাকা উচিত।
এই ডকুমেন্টে Julia কীভাবে তারিখ ও সময় সামলায় তার একটা সংক্ষিপ্ত ধারণা দেওয়ার চেষ্টা করা হয়েছে, তবে বিস্তারিত জানতে ম্যানুয়াল দেখা জরুরি। এছাড়া একটি Wikibook আছে, যার ব্যাখ্যা কিছু পাঠকের কাছে আরও পরিষ্কার লাগতে পারে, আর সেখানে টাইপ হায়ারার্কির একটি সহায়ক ডায়াগ্রাম দেওয়া আছে।
Dates মডিউলবেশিরভাগ মৌলিক সুবিধা আছে Dates-এ, এটি এমন একটি মডিউল যা ডিফল্ট ইনস্টলেশনের সঙ্গে আসে কিন্তু স্ট্যান্ডার্ড লাইব্রেরির অংশ নয়।
মডিউলটি ব্যবহার করার দুটি উপায় আছে:
import Dates যোগ করুন, তারপর সব ফাংশন কলের আগে Dates. বসানusing Dates যোগ করুন, যা পুরো মডিউলটিকে বর্তমান নেমস্পেসে নিয়ে আসে (কয়েকটি সমস্যাযুক্ত নাম বাদে)।# option 1
julia> import Dates
julia> Dates.now()
2025-06-21T16:02:39.080
julia> now() # wrong: need to include `Dates.` after an import
ERROR: UndefVarError: `now` not defined in `Main`
# option 2
julia> using Dates
julia> now() # functions are now in the namespace
2025-06-21T16:03:04.161
Dates মডিউলটি বড় ও জটিল, তবে এটি প্রধানত চার ধরনের সুবিধা দেয়:
Dates.Date, যাতে দিন-মাস-বছর থাকে কিন্তু দিনের সময় থাকে না।Dates.Time, যাতে দিনের সময় থাকে, কিন্তু তারিখ থাকে না।Dates.DateTime, যা তারিখ ও সময় একসঙ্গে ধরে।Dates.Period, যা সময়/তারিখের ইন্টারভাল সামলায়।খেয়াল রাখবেন, একটি DateTime সাধারণত টাইমজোনের তথ্য ধরে না (Python এটাকে "নেইভ" ডেটটাইম বলবে)।
এর একটি ব্যতিক্রম হলো now(), যা আপনার সিস্টেম ক্লক থেকে লোকাল সময় নেয়, আর প্রয়োজনে এটিকে UTC-তে রূপান্তর করতে পারে।
সম্ভবত সবচেয়ে বেশি দরকার হয়:
Dates টাইপ তৈরি করতে উপযুক্ত কোনো ইনপুট ফরম্যাট পার্স করা।Dates টাইপ থেকে দরকারি সংখ্যাসূচক বা স্ট্রিং ফরম্যাট বের করা।Date, Time বা DateTime মানে একটি অফসেট প্রয়োগ করা।today() দিয়ে) এবং/অথবা সময় (now() দিয়ে) পাওয়া।চোখে কম বিভ্রান্তি লাগার জন্য, এই ডকুমেন্টের বাকি অংশের বেশিরভাগ উদাহরণ কোড ধরে নেয় using Dates করা আছে, আর ফাংশন কলে Dates. মডিউল-নাম লেখা এড়িয়ে যায়।
তারিখ ও সময় লেখার অনেক রকম উপায় আছে, আর সেগুলো প্রায়ই সংস্কৃতিভেদে আলাদা হয়। "7/6/23" এর মতো সব-সংখ্যার তারিখ অস্পষ্ট ও বিভ্রান্তিকর, আর এগুলো বহুজাতিক প্রতিষ্ঠানে অনেক ব্যয়বহুল ভুলের কারণ হয়েছে (লেখক এটি তিক্ত ব্যক্তিগত অভিজ্ঞতা থেকে বলছেন)।
আন্তর্জাতিক মানদণ্ডটি ISO 8601-এ নির্ধারিত, যার দুটি প্রধান সুবিধা আছে:
আগের একটি উদাহরণে দেখেছি, Date.now() রিটার্ন করেছিল 2025-06-21T16:03:04.161।
এটি বিভিন্ন অংশ দিয়ে গঠিত:
YYYY-MM-DD।hh:mm:ss।অন্য স্ট্রিং ফরম্যাট নিয়ে পরে একটি অংশে আলোচনা করা হবে।
Dates.Date তুলনামূলকভাবে সরল, শুধু তারিখের টাইপ, যার সময় বা টাইমজোন বোঝার ক্ষমতা নেই।
# constructor with year, month, day arguments
julia> date1 = Date(2025, 06, 23)
2025-06-23
# constructor with ISO 8601 string
julia> date2 = Date("2025-06-23")
2025-06-23
julia> date1 == date2
true
julia> typeof(date1)
Date
তারিখের আলাদা আলাদা অংশ বের করার জন্য অ্যাকসেসর ফাংশন আছে, আর এগুলো ছোট-বড় হাতের অক্ষরের পার্থক্যে জোড়া জোড়া থাকে।
# lowercase returns an integer
julia> month(date1)
6
julia> typeof(month(date1))
Int64
# Propercase returns a Period type
julia> Month(date1)
6 months
julia> typeof(Month(date1))
Month
ক্যালেন্ডার সম্পর্কে কিছুটা ধারণা রাখে এমন নানা ফাংশন আছে। পরের উদাহরণে অল্প কয়েকটি দেখানো হলো।
julia> date1
2025-06-23
julia> dayofweek(date1) # 1 = Monday, 7 = Sunday
1
julia> dayname(date1)
"Monday"
julia> daysinmonth(date1)
30
julia> isleapyear(date1)
false
julia> lastdayofmonth(date1)
2025-06-30
Dates.Time হলো মৌলিক, শুধু সময়ের টাইপ।
এর তারিখ বোঝার ক্ষমতা নেই: মধ্যরাতে সময় স্বয়ংক্রিয়ভাবে Time(0, 0, 0)-এ গিয়ে ঠেকে।
পূর্ণ কনস্ট্রাক্টর ফরম্যাট হলো Time(hour, min, sec, millisec, microsec) অথবা তার ISO 8601 সমতুল্য।
সব প্যারামিটার ঐচ্ছিক এবং ডিফল্টভাবে 0 ধরে নেওয়া হয়।
julia> Time(14, 57, 25, 142)
14:57:25.142
julia> Time("14:57:25.142")
14:57:25.142
julia> Time(14, 57, 25, 142, 32)
14:57:25.142032
Date-এর মতোই, আলাদা আলাদা অংশ অ্যাকসেসর ফাংশন দিয়ে পাওয়া যায়:
julia> minute(t) # => integer
57
julia> Minute(t) # => Period
57 minutes
Dates.DateTime Date ও Time টাইপের বেশিরভাগ বৈশিষ্ট্য একসঙ্গে ধরে।
julia> dt1 = DateTime(2025, 6, 23, 14, 57, 25, 142)
2025-06-23T14:57:25.142
# date1 and t were defined in previous examples
julia> dt2 = DateTime(date1, t)
2025-06-23T14:57:25.142
বছর, মাস ও দিন প্যারামিটার ডিফল্টভাবে 1, আর সময়ের সব প্যারামিটার ডিফল্টভাবে 0।
এই সব প্যারামিটার ঠিকঠাক মনে রাখা কঠিন হতে পারে, তাই ইনপুটের জন্য ISO ফরম্যাট পছন্দনীয় হতে পারে।
অথবা, উপরের উদাহরণের মতো একটি Date ও একটি Time থেকে DateTime তৈরি করা যায়।
তারিখ/সময়ের প্রতিটি উপাদানের নিজস্ব Period টাইপ আছে, Year থেকে Nanosecond পর্যন্ত, যা সময়ের একটি ইন্টারভাল বোঝায়।
এগুলো বিশেষভাবে পাটিগণিতে কাজে লাগে।
julia> dt1
2025-06-23T14:57:25.142
julia> Year(21)
21 years
julia> Second(61)
61 seconds
julia> dt1 + Year(21) - Second(61)
2046-06-23T14:56:24.142
julia> Date(2025, 07, 03) - Date(2025, 04, 25)
69 days
Period টাইপ নিয়ে কাজ করার সময়, Julia মাসের দৈর্ঘ্যের মতো ক্যালেন্ডারের অসামঞ্জস্য নিয়ে বুদ্ধিমানের মতো কাজ করার চেষ্টা করে, প্রয়োজনে রাউন্ডিং করে।
# February has fewer days than January
julia> Date(2025, 1, 31) + Month(1)
2025-02-28
আগে আমরা ISO 8601 মানদণ্ডের কথা বলেছি, যা স্ট্রিং ফরম্যাট বা পার্স করার সময় Julia-র ডিফল্ট তারিখ/সময় উপস্থাপনা।
স্পষ্টতই, আরও অনেক ফরম্যাট নিয়মিত ব্যবহৃত হয়, প্রায়ই সংস্কৃতিভেদে আলাদা ভাবে।
এসব সামলানোর জন্য Julia-র আছে DateFormat টাইপ, যা ইচ্ছামতো জটিল একটি ফরম্যাট স্ট্রিং থেকে তৈরি করা যায়।
# dateformat"" string syntax
julia> dtfmt = dateformat"d/m/y"
dateformat"d/m/y"
julia> typeof(dtfmt)
DateFormat{Symbol("d/m/y"), Tuple{Dates.DatePart{'d'}, Dates.Delim{Char, 1}, Dates.DatePart{'m'}, Dates.Delim{Char, 1}, Dates.DatePart{'y'}}}
# DateFormat constructor
julia> DateFormat("d/m/y")
dateformat"d/m/y"
উপরের উদাহরণটি খুবই সরল, ইউরোপে প্রচলিত দিন/মাস/বছর ফরম্যাটে লেখা একটি তারিখ মাত্র। সিনট্যাক্সের দুটি রূপ দেখানো হয়েছে, তবে ফলাফল অভিন্ন।
এরপর উপযুক্ত যেকোনো স্ট্রিং পার্স করতে একটি DateFormat ব্যবহার করা যায়:
julia> DateTime("14/7/2023", dtfmt)
2023-07-14T00:00:00
একটি DateFormat তৈরি করতে যথেষ্ট ওভারহেড লাগে, তাই এই কাজটি মাত্র একবার করা (এখানে dtfmt দিয়ে যেমন) অনেক তারিখ/সময়ের স্ট্রিংয়ের ওপর লুপ চালানোর সময় পারফরম্যান্সের জন্য সহায়ক।
ফরম্যাট এটার চেয়ে অনেক বেশি জটিল হতে পারে, তাই বিস্তারিত জানতে ম্যানুয়াল দেখুন।
একই DateFormat Dates.format() ফাংশন ব্যবহার করে যেকোনো কাঙ্ক্ষিত স্ট্রিং ফরম্যাটে একটি তারিখ/সময় আউটপুট করতেও ব্যবহার করা যায়।
দুর্ভাগ্যবশত, format-এর সঙ্গে একটি নেমস্পেস সংঘাত আছে বলে মনে হয় (অন্তত Julia 1.11.5 পর্যন্ত), তাই using Dates করার পরেও Dates. প্রিফিক্স লেখাই ভালো।
julia> dt1
2025-06-23T14:57:25.142
julia> Dates.format(dt1, dateformat"e, u d")
"Mon, Jun 23"
ডকুমেন্টেশন অনুযায়ী, "e, u d" সপ্তাহের দিন ও মাসের সংক্ষিপ্ত টেক্সট উপস্থাপনা দেয়।
টেক্সট উপস্থাপনা ডিফল্টভাবে ইংরেজিতে হয়। অন্য ভাষাও যোগ করা যায়, যদিও এর সাপোর্ট বর্তমানে তেমন ভালো নয়।
এই অনুশীলনীতে আপনি নিউ ইয়র্কের একটি বিউটি সেলুনের জন্য অ্যাপয়েন্টমেন্ট শিডিউলার নিয়ে কাজ করবেন। সেলুনটি ২০১২ সালের ১৫ সেপ্টেম্বর চালু হয়েছিল।
আপনার পাঁচটি কাজ আছে, যার প্রতিটিতেই অ্যাপয়েন্টমেন্টের তারিখ জড়িত থাকবে। সময় ২৪-ঘণ্টার ফরম্যাটে দেখানো হয় (AM/PM ছাড়া)।
একটি অ্যাপয়েন্টমেন্টের তারিখের টেক্সট রূপকে সংশ্লিষ্ট DateTime ফরম্যাটে পার্স করতে schedule_appointment() ফাংশনটি ইমপ্লিমেন্ট করুন।
লক্ষ্য করুন, ইনপুটটি মার্কিন ধাঁচের মাস/দিন/বছর ক্রমে দেওয়া।
julia> schedule_appointment("07/25/2023 13:45:00")
2023-07-25T13:45:00
has_passed() ফাংশনটি ইমপ্লিমেন্ট করুন, যা একটি অ্যাপয়েন্টমেন্টের তারিখ নেয় এবং অ্যাপয়েন্টমেন্টটি অতীতে কোনো এক সময়ে ছিল কি না তা যাচাই করে:
julia> has_passed(DateTime(1999, 12, 31, 9, 0, 0))
true
is_afternoon_appointment() ফাংশনটি ইমপ্লিমেন্ট করুন, যা একটি অ্যাপয়েন্টমেন্টের তারিখ নেয় এবং অ্যাপয়েন্টমেন্টটি দুপুরের পরে কি না (>= 12:00 এবং < 18:00) তা যাচাই করে:
julia> is_afternoon_appointment(DateTime(2023, 3, 29, 15, 0, 0))
true
description() ফাংশনটি ইমপ্লিমেন্ট করুন, যা একটি অ্যাপয়েন্টমেন্টের তারিখ নেয় এবং সেই তারিখ ও সময়ের একটি বর্ণনা রিটার্ন করে:
julia> describe(DateTime(2023, 3, 29, 15, 0, 0))
"You have an appointment on Wednesday, March 29, 2023 at 15:00"
anniversary_date() ফাংশনটি ইমপ্লিমেন্ট করুন, যা এ বছরের অ্যানিভার্সারি তারিখ রিটার্ন করে, অর্থাৎ ১৫ সেপ্টেম্বর:
julia> anniversary_date() # run during 2025
2025-09-15
Exercism-এ সাইন আপ করুন, Julia ট্র্যাকের 35টি কনসেপ্ট128টি অনুশীলনী আর সত্যিকারের মানুষের মেন্টরিং দিয়ে শিখুন ও দক্ষ হয়ে উঠুন, সম্পূর্ণ বিনামূল্যে।