রুবির DateTime
এবং Time
ক্লাসের মধ্যে কী পার্থক্য রয়েছে এবং কোন কারণগুলি আমাকে একটি বা অন্যটি বেছে নিতে বাধ্য করবে?
রুবির DateTime
এবং Time
ক্লাসের মধ্যে কী পার্থক্য রয়েছে এবং কোন কারণগুলি আমাকে একটি বা অন্যটি বেছে নিতে বাধ্য করবে?
উত্তর:
রুবি (২.০+) এর নতুন সংস্করণগুলিতে দুটি শ্রেণীর মধ্যে উল্লেখযোগ্য পার্থক্য নেই। কিছু গ্রন্থাগার oneতিহাসিক কারণে এক বা অন্যটি ব্যবহার করবে তবে নতুন কোডটি উদ্বিগ্ন হওয়ার দরকার নেই। ধারাবাহিকতার জন্য একটি বাছাই করা সম্ভবত সেরা, সুতরাং আপনার লাইব্রেরিগুলি যা প্রত্যাশা করে তার সাথে চেষ্টা করুন এবং জাল করুন। উদাহরণস্বরূপ, অ্যাক্টিভেকর্ড ডেটটাইম পছন্দ করে।
রুবি ১.৯ এর পূর্ববর্তী সংস্করণগুলিতে এবং অনেক সিস্টেমে সময়কে একটি 32-বিট স্বাক্ষরিত মান হিসাবে জানুয়ারী 1, 1970 ইউটিসি থেকে পসিক্স-স্ট্যান্ডার্ড time_t
মানের চারপাশে একটি পাতলা মোড়ক হিসাবে বর্ণনা করা হয় :
Time.at(0x7FFFFFFF)
# => Mon Jan 18 22:14:07 -0500 2038
Time.at(-0x7FFFFFFF)
# => Fri Dec 13 15:45:53 -0500 1901
রুবির নতুন সংস্করণগুলি ত্রুটি তৈরি না করেই বৃহত্তর মানগুলি পরিচালনা করতে সক্ষম।
ডেটটাইম একটি ক্যালেন্ডার ভিত্তিক পদ্ধতির যেখানে বছর, মাস, দিন, ঘন্টা, মিনিট এবং দ্বিতীয়টি পৃথকভাবে সংরক্ষণ করা হয়। এটি রিল অন রেল কনস্ট্রাক্ট যা এসকিউএল-স্ট্যান্ডার্ড DATETIME ক্ষেত্রের চারপাশে মোড়কের কাজ করে। এগুলিতে নির্বিচারে তারিখগুলি থাকে এবং সময়ের যে কোনও বিন্দুতে প্রতিনিধিত্ব করতে পারে কারণ অভিব্যক্তিটির পরিসীমা সাধারণত খুব বড়।
DateTime.new
# => Mon, 01 Jan -4712 00:00:00 +0000
সুতরাং এটি আশ্বাস দেয় যে ডেটটাইম এরিস্টটলের ব্লগ পোস্টগুলি পরিচালনা করতে পারে।
কোনওটি চয়ন করার সময়, পার্থক্যগুলি এখন কিছুটা বিষয়ভিত্তিক। Icallyতিহাসিকভাবে ডেটটাইম এটিকে ক্যালেন্ডার ফ্যাশনে ম্যানিপুলেট করার জন্য আরও ভাল বিকল্প সরবরাহ করেছে, তবে এর মধ্যে অনেকগুলি পদ্ধতি সময়ের সাথে সাথে কমপক্ষে রেলের পরিবেশেও পোর্ট করা হয়েছে।
[জুলাই 2018 সম্পাদনা করুন]
নীচের সমস্তটি এখনও রুবি ২.২.১ এ সত্য হিসাবে রয়েছে। থেকে রেফারেন্স ডকুমেন্টেশন :
ডেটটাইম কোনও লিপ সেকেন্ড বিবেচনা করে না, গ্রীষ্মের সময় সংক্রান্ত কোনও নিয়ম ট্র্যাক করে না।
এর আগে এই থ্রেডে যা উল্লেখ করা হয়নি DateTime
তা হ'ল কয়েকটি সুবিধার মধ্যে একটি : এটি ক্যালেন্ডার সংস্কার সম্পর্কে সচেতন তবে এমনটি Time
নয়:
[…] রুবির টাইম ক্লাস একটি প্রলেপটিক গ্রেগরিয়ান ক্যালেন্ডার প্রয়োগ করে এবং ক্যালেন্ডার সংস্কারের কোনও ধারণা নেই […]।
রেফারেন্স ডকুমেন্টেশনটি সুনির্দিষ্টভাবে Time
নিকট-অতীত, বর্তমান বা ভবিষ্যতের তারিখ / সময়গুলির সাথে ডিল করার সময় ব্যবহার করার সুপারিশের সাথে শেষ হয় এবং কেবলমাত্র DateTime
যখন ব্যবহার করা হয়, উদাহরণস্বরূপ, শেক্সপিয়ারের জন্মদিনকে সঠিকভাবে রূপান্তর করা দরকার: (জোর দেওয়া)
সুতরাং কখন আপনি রুবিতে ডেটটাইম ব্যবহার করবেন এবং কখন আপনার সময় ব্যবহার করা উচিত? আপনার অ্যাপ্লিকেশন সম্ভবত বর্তমান তারিখ এবং সময়গুলি নিয়ে কাজ করছে বলে আপনি অবশ্যই সময়টি ব্যবহার করতে চাইবেন। তবে, যদি আপনার কোনও historicalতিহাসিক প্রসঙ্গে তারিখ এবং সময়গুলির সাথে ডিল করার প্রয়োজন হয় তবে আপনি ডেটটাইম ব্যবহার করতে চাইবেন […]। যদি আপনারও টাইমজোনগুলি মোকাবেলা করতে হয় তবে শুভকামনা - কেবল মনে রাখবেন যে আপনি সম্ভবত স্থানীয় সৌর কাল নিয়ে কাজ করবেন, যেহেতু 19 শতকের আগে রেলপথের প্রবর্তন স্ট্যান্ডার্ড সময়ের প্রয়োজনের প্রয়োজন ছিল না এবং শেষ পর্যন্ত সময় অঞ্চলসমূহ।
[/ জুলাই 2018 সম্পাদনা করুন]
রুবি ২.০ হিসাবে, অন্যান্য উত্তরের বেশিরভাগ তথ্য পুরানো।
বিশেষত, Time
এখন কার্যত আনবাউন্ড। এটি ইপচ থেকে 63৩ বিট দূরেও কম বা কম হতে পারে:
irb(main):001:0> RUBY_VERSION
=> "2.0.0"
irb(main):002:0> Time.at(2**62-1).utc # within Integer range
=> 146138514283-06-19 07:44:38 UTC
irb(main):003:0> Time.at(2**128).utc # outside of Integer range
=> 10783118943836478994022445751222-08-06 08:03:51 UTC
irb(main):004:0> Time.at(-2**128).utc # outside of Integer range
=> -10783118943836478994022445747283-05-28 15:55:44 UTC
বৃহত্তর মানগুলি ব্যবহারের একমাত্র পরিণতি হ'ল পারফরম্যান্স, যা Integer
ব্যবহার করা (বনাম Bignum
গুলি ( Integer
সীমার বাইরে মান ) বা Rational
সেগুলি (যখন ন্যানোসেকেন্ডগুলি ট্র্যাক করা হয়) ব্যবহার করা ভাল):
রুবি ১.৯.২ থেকে সময় প্রয়োগকরণে একটি স্বাক্ষরিত 63৩ বিট পূর্ণসংখ্যা, বিগনাম বা যুক্তি ব্যবহার করা হয়। পূর্ণসংখ্যাটি হ'ল মহাকাশকাল থেকে ন্যানোসেকেন্ডগুলির একটি সংখ্যা যা 1823-11-12 থেকে 2116-02-20 উপস্থাপন করতে পারে। যখন বিগনাম বা যুক্তি ব্যবহার করা হয় (1823 এর আগে, 2116 এর পরে, ন্যানোসেকেন্ডের অধীনে), সময়টি ধীরে ধীরে কাজ করে যখন পূর্ণসংখ্যা ব্যবহৃত হয়। ( http://www.ruby-doc.org/core-2.1.0/Time.html )
অন্য কথায়, যতদূর আমি বুঝতে পেরেছি, এর DateTime
চেয়ে সম্ভাব্য মানগুলির বিস্তৃত পরিসর আর আর কভার করে নাTime
।
তদতিরিক্ত, পূর্বে দুটি অনিরোধিত বিধিনিষেধগুলি DateTime
সম্ভবত উল্লেখ করা উচিত:
ডেটটাইম কোনও লিপসেকেন্ড বিবেচনা করে না, গ্রীষ্মের কোনও সময় নীতি ট্র্যাক করে না। ( http://www.ruby-doc.org/stdlib-2.1.0/libdoc/date/rdoc/Date.html#class-Date-label-DateTime )
প্রথমত, DateTime
লিপ সেকেন্ডের কোনও ধারণা নেই:
irb(main):001:0> RUBY_VERSION
=> "2.0.0"
irb(main):002:0> require "date"
=> true
irb(main):003:0> t = Time.new(2012,6,30,23,59,60,0)
=> 2012-06-30 23:59:60 +0000
irb(main):004:0> dt = t.to_datetime; dt.to_s
=> "2012-06-30T23:59:59+00:00"
irb(main):005:0> t == dt.to_time
=> false
irb(main):006:0> t.to_i
=> 1341100824
irb(main):007:0> dt.to_time.to_i
=> 1341100823
উপরের উদাহরণটির সাথে কাজ করার জন্য Time
, ওএসকে লিপ সেকেন্ড সমর্থন করতে হবে এবং টাইমজোন তথ্য সঠিকভাবে সেট করা দরকার, যেমন TZ=right/UTC irb
(অনেকগুলি ইউনিক্স সিস্টেমে) মাধ্যমে।
দ্বিতীয়ত, DateTime
সময় অঞ্চলগুলি সম্পর্কে খুব সীমিত ধারণা রয়েছে এবং বিশেষত দিবালোক সঞ্চয় সম্পর্কে কোনও ধারণা নেই । এটি বেশিরভাগ সময় অঞ্চলকে সাধারণ ইউটিসি + এক্স অফসেট হিসাবে পরিচালনা করে:
irb(main):001:0> RUBY_VERSION
=> "2.0.0"
irb(main):002:0> require "date"
=> true
irb(main):003:0> t = Time.local(2012,7,1)
=> 2012-07-01 00:00:00 +0200
irb(main):004:0> t.zone
=> "CEST"
irb(main):005:0> t.dst?
=> true
irb(main):006:0> dt = t.to_datetime; dt.to_s
=> "2012-07-01T00:00:00+02:00"
irb(main):007:0> dt.zone
=> "+02:00"
irb(main):008:0> dt.dst?
NoMethodError: undefined method `dst?' for #<DateTime:0x007f34ea6c3cb8>
যখন সময়গুলি ডিএসটি হিসাবে প্রবেশ করা হয় এবং তারপরে DateTime
নিজের বাইরে সঠিক অফসেটগুলি না রেখে-নন-ডিএসটি টাইম জোনে রূপান্তরিত হয় তখন এটি সমস্যার কারণ হতে পারে (অনেক অপারেটিং সিস্টেমগুলি ইতিমধ্যে আপনার জন্য এটি যত্ন নিতে পারে)।
সামগ্রিকভাবে, আমি বলতে পারি যে আজকাল Time
বেশিরভাগ অ্যাপ্লিকেশনগুলির জন্য ভাল পছন্দ।
সংযোজনের ক্ষেত্রে একটি গুরুত্বপূর্ণ পার্থক্যটিও নোট করুন: আপনি যখন কোনও টাইম অবজেক্টে একটি সংখ্যা যুক্ত করেন, তখন এটি সেকেন্ডে গণনা করা হয়, তবে আপনি যখন কোনও ডেটটাইম যুক্ত করেন, তখন এটি কয়েক দিনের মধ্যে গণনা করা হয়।
Time
লিপ সেকেন্ডের কোনও ধারণা নেই, তাই এটি আলাদা নয় DateTime
। আপনি কোথায় আপনার উদাহরণগুলি দৌড়েছিলেন তা আমি জানি না, তবে আমি Time.new(2012,6,30,23,59,60,0)
2.0 থেকে 2.7 পর্যন্ত বিভিন্ন রুবি সংস্করণে চেষ্টা করেছি এবং সর্বদা পেয়েছি 2012-07-01 00:00:00 +0000
।
Time
লিপ সেকেন্ড সমর্থন করে কিনা তা আপনার ওএস এবং টাইমজোন কনফিগারেশনের উপর নির্ভর করে। উদাহরণস্বরূপ: TZ=right/UTC ruby -e 'p Time.new(2012,6,30,23,59,60,0)'
=> 2012-06-30 23:59:60 +0000
যদিও TZ=UTC ruby -e 'p Time.new(2012,6,30,23,59,60,0)'
=> 2012-07-01 00:00:00 +0000
।
আমি মনে করি "কি পার্থক্য" এর উত্তরটি রুবি স্ট্যান্ডার্ড লাইব্রেরিতে এই প্রশ্নের দুর্ভাগ্যজনক সাধারণ উত্তরগুলির মধ্যে: দুটি শ্রেণি / লিবস বিভিন্ন সময়ে বিভিন্ন ব্যক্তি আলাদাভাবে তৈরি করেছিলেন। জাভা জাতীয় কিছু সতর্কতার সাথে পরিকল্পিত বিকাশের তুলনায় রুবির বিবর্তনের সম্প্রদায়ের প্রকৃতির এক দুর্ভাগ্যজনক পরিণতি। বিকাশকারীরা নতুন কার্যকারিতা চায় তবে বিদ্যমান এপিআইগুলিতে পদক্ষেপ নিতে চায় না তাই তারা কেবল একটি নতুন শ্রেণি তৈরি করে - শেষ ব্যবহারকারীর কাছে দু'জনের উপস্থিতির কোনও স্পষ্ট কারণ নেই।
এটি সাধারণভাবে সফ্টওয়্যার লাইব্রেরিগুলির ক্ষেত্রে সত্য: প্রায়শই কিছু কোড বা API এটিকে যুক্তিযুক্ত পরিবর্তে historicalতিহাসিক হিসাবে দেখা যায় to
প্রলোভনটি ডেটটাইম দিয়ে শুরু করা হয় কারণ এটি আরও সাধারণ মনে হয়। তারিখ ... এবং সময়, তাই না? ভুল। সময় এছাড়াও তারিখগুলি আরও ভাল করে, এবং আসলে সময় অঞ্চলগুলিকে পার্স করতে পারে যেখানে ডেটটাইম পারে না ime এছাড়াও এটি আরও ভাল পারফর্ম করে।
আমি সর্বত্রই সময় ব্যবহার করে শেষ করেছি।
যদিও নিরাপদ থাকতে, আমি ডেটটাইম আর্গুমেন্টগুলিকে আমার টাইমী এপিআইগুলিতে পাস করার অনুমতি দেয় এবং হয় রূপান্তর করি। এছাড়াও যদি আমি জানি যে উভয়েরই পদ্ধতিতে আমি আগ্রহী আমি উভয়ই গ্রহণ করি, এই পদ্ধতিটির মতো আমি সময়টি এক্সএমএল রূপান্তর করার জন্য লিখেছি (এক্সএমটিভিটি ফাইলের জন্য)
# Will take a date time as a string or as a Time or DateTime object and
# format it appropriately for xmtlv.
# For example, the 22nd of August, 2006 at 20 past midnight in the British Summertime
# timezone (i.e. GMT plus one hour for DST) gives: "20060822002000 +0100"
def self.format_date_time(date_time)
if (date_time.respond_to?(:rfc822)) then
return format_time(date_time)
else
time = Time.parse(date_time.to_s)
return format_time(time)
end
end
# Note must use a Time, not a String, nor a DateTime, nor Date.
# see format_date_time for the more general version
def self.format_time(time)
# The timezone feature of DateTime doesn't work with parsed times for some reason
# and the timezone of Time is verbose like "GMT Daylight Saving Time", so the only
# way I've discovered of getting the timezone in the form "+0100" is to use
# Time.rfc822 and look at the last five chars
return "#{time.strftime( '%Y%m%d%H%M%S' )} #{time.rfc822[-5..-1]}"
end
Time.new(2011, 11, 1, 10, 30)
উত্পাদন করার 2011-11-01 10:30:00 +0700
সময় DateTime.new(2011, 11, 1, 10, 30)
উত্পাদন করে Tue, 01 Nov 2011 10:30:00 +0000
।
আমি যেমন অ্যাক্টিভসপোর্ট এক্সটেনশানগুলি ব্যবহার করে চলেছি তা ধরে নিয়ে ডেটটাইমটি করা বিভিন্ন টাইমজোনগুলিতে দিনের শুরু / শেষের পার্সিং এবং গণনা করার মতো জিনিসগুলি পেয়েছি ।
আমার ক্ষেত্রে আমার ব্যবহারকারীর স্থানীয় সময় যা আমি স্ট্রিং হিসাবে পেয়েছি তার উপর ভিত্তি করে ব্যবহারকারীর টাইমজোন (স্বেচ্ছাচারী) এ দিনের শেষে গণনা করা দরকার, যেমন "2012-10-10 10:10 +0300"
ডেটটাইম সহ এটি সহজ
irb(main):034:0> DateTime.parse('2012-10-10 10:10 +0300').end_of_day
=> Wed, 10 Oct 2012 23:59:59 +0300
# it preserved the timezone +0300
এখন সময়ের সাথে একইভাবে চেষ্টা করা যাক:
irb(main):035:0> Time.parse('2012-10-10 10:10 +0300').end_of_day
=> 2012-10-10 23:59:59 +0000
# the timezone got changed to the server's default UTC (+0000),
# which is not what we want to see here.
আসলে, সময় (আরো উল্লেখ্য এটা পার্স আগে টাইমজোন জানা প্রয়োজন Time.zone.parse
, না Time.parse
):
irb(main):044:0> Time.zone = 'EET'
=> "EET"
irb(main):045:0> Time.zone.parse('2012-10-10 10:10 +0300').end_of_day
=> Wed, 10 Oct 2012 23:59:59 EEST +03:00
সুতরাং, এক্ষেত্রে ডেটটাইমের সাথে যাওয়া অবশ্যই সহজ।
DateTime.parse('2014-03-30 01:00:00 +0100').end_of_day
উত্পাদন করে Sun, 30 Mar 2014 23:59:59 +0100
তবে Time.zone = 'CET'; Time.zone.parse('2014-03-30 01:00:00').end_of_day
উত্পাদন করে Sun, 30 Mar 2014 23:59:59 CEST +02:00
(সিইটি = + 01: 00, সিইএসটি = + 02: 00 - অফসেট পরিবর্তিত হয়েছে তা লক্ষ্য করুন)। তবে এটি করার জন্য আপনার ব্যবহারকারীর টাইমজোন সম্পর্কে আরও তথ্য প্রয়োজন (কেবল অফসেট নয়, সাশ্রয়ের সময় ব্যবহৃত হয় কিনা)।
Time.zone.parse
এটি খুব কার্যকর - এটি আপনাকে কোন অঞ্চলটি ব্যবহার করা উচিত সে সম্পর্কে ভাবতে বাধ্য করে। কখনও কখনও, টাইম.ফাইন্ড_জোন আরও ভাল কাজ করে।
DateTime
আপনার দেওয়া অফসেটটি পার্স করেছিলেন, যা +0100 ছিল। আপনি Time
অফসেট দেন নি, তবে একটি সময় অঞ্চল ("সিইটি" কোনও অফসেট বর্ণনা করে না, এটি একটি টাইমজোনটির নাম)। টাইমজোনগুলি সারা বছর জুড়ে বিভিন্ন অফসেট থাকতে পারে তবে একটি অফসেট একটি অফসেট এবং এটি সর্বদা একই থাকে।
তারা কীভাবে কাস্টম ইনস্ট্যান্টেশনের মাধ্যমে টাইমজোনগুলি আলাদাভাবে পরিচালনা করে তা বিবেচনা করুন:
irb(main):001:0> Time.new(2016,9,1)
=> 2016-09-01 00:00:00 -0400
irb(main):002:0> DateTime.new(2016,9,1)
=> Thu, 01 Sep 2016 00:00:00 +0000
irb(main):003:0> Time.new(2016,9,1).to_i
=> 1472702400
irb(main):004:0> DateTime.new(2016,9,1).to_i
=> 1472688000
সময় ব্যাপ্তি ইত্যাদি তৈরি করার সময় এটি জটিল হতে পারে etc.
দেখে মনে হয় যে কিছু ক্ষেত্রে আচরণটি খুব আলাদা:
Time.parse("Ends from 28 Jun 2018 12:00 BST").utc.to_s
"2018-06-28 09:00:00 ইউটিসি"
Date.parse("Ends from 28 Jun 2018 12:00 BST").to_time.utc.to_s
"2018-06-27 21:00:00 ইউটিসি"
DateTime.parse("Ends from 28 Jun 2018 12:00 BST").to_time.utc.to_s
"2018-06-28 11:00:00 ইউটিসি"
Date
(আশ্চর্যজনকভাবে) কেবল তারিখগুলি বিশ্লেষণ করে এবং যখন কোনও Date
রূপান্তরিত হয় Time
, এটি সর্বদা স্থানীয় সময় অঞ্চলে মধ্যরাতকে সময় হিসাবে ব্যবহার করে। বিএসটি বুঝতে না পারার মধ্যকার পার্থক্য Time
এবং TimeDate
ডালপালাটি Time
আশ্চর্যজনক যে, সময় অঞ্চলগুলি সাধারণত সঠিকভাবে পরিচালিত হয় Time
(উদাহরণস্বরূপ, দিবালোক সংরক্ষণের সময় সম্পর্কে)। সুতরাং এই ক্ষেত্রে, শুধুমাত্র DateTime
পুরো স্ট্রিংকে সঠিকভাবে পার্স করে।
নীল গ্যানসারের উত্তর ছাড়াও আপনি এই যুক্তিটি বিবেচনা করতে পারেন:
নোট করুন যে রুবি স্টাইল গাইড এতে পরিষ্কারভাবে একটি অবস্থান বর্ণনা করেছে:
ডেটটাইম নেই
Historicalতিহাসিক ক্যালেন্ডার সংস্কারের জন্য আপনার অ্যাকাউন্টিং করার প্রয়োজন না হলে ডেটটাইম ব্যবহার করবেন না - এবং যদি আপনি এটি করেন তবে স্পষ্টভাবে আপনার উদ্দেশ্যগুলি পরিষ্কারভাবে বর্ণনা করতে শুরু করার যুক্তিটি নির্দিষ্ট করুন।
# bad - uses DateTime for current time DateTime.now # good - uses Time for current time Time.now # bad - uses DateTime for modern date DateTime.iso8601('2016-06-29') # good - uses Date for modern date Date.iso8601('2016-06-29') # good - uses DateTime with start argument for historical date DateTime.iso8601('1751-04-23', Date::ENGLAND)