সি ++ 20 ক্রোনো ব্যবহার করে, কীভাবে কোনও তারিখ সম্পর্কে বিভিন্ন তথ্য গণনা করা যায়


19

https://www.timeanddate.com/date/weekday.html বছরের একটি দিন সম্পর্কে বিভিন্ন তথ্য গণনা করে, উদাহরণস্বরূপ:

https://i.stack.imgur.com/WPWuO.png

একটি স্বেচ্ছাসেবী তারিখ দেওয়া, এই নম্বরগুলি কিভাবে সি ++ 20 ক্রোনো নির্দিষ্টকরণের সাথে গণনা করা যেতে পারে ?


2
"... এবং আমরা সবাই জানি যে আইএসও সপ্তাহ 1 কখন, ঠিক? ..." - "না, তবে আমি একটি গ্রন্থাগার পেয়েছি" ... :-) - ব্র্যাভো হাওয়ার্ড!
টেড লিংগমো

স্ট্যাকওভারফ্লো.com / q / 59391132 / 560648 থেকে তোলা চিত্র (এখন মুছে ফেলা হয়েছে)। লজ্জাজনক এটি মুছে ফেলা হয়েছে কারণ এই প্রশ্নের উত্তর হওয়া উচিত ছিল।
হালকা ঘোড়দৌড়

সঠিক। আমি এটি আবার খুলতে ভোট দিয়েছি।
হাওয়ার্ড হিনান্ট

উত্তর:


22

এটি C ++ 20 ক্রোনো নির্দিষ্টকরণের সাথে উল্লেখযোগ্যভাবে সহজ । নীচে আমি একটি ফাংশন দেখাব যা একটি স্বেচ্ছাসেবী তারিখ অন্তর্ভুক্ত করে এবং এতে এই তথ্যটি প্রিন্ট করে cout। যদিও এই লেখার সময়, সি ++ 20 ক্রোনো স্পেসিফিকেশনটি এখনও শিপিং করা হয়নি, এটি একটি নিখরচায়, মুক্ত-উত্স লাইব্রেরি দ্বারা আনুমানিক । সুতরাং আপনি আজই এটি নিয়ে পরীক্ষা করতে পারেন এবং আপনি সি ++ 11 বা পরবর্তী অবধি গ্রহণ না করা পর্যন্ত শিপিং অ্যাপ্লিকেশনগুলিতে এটি অন্তর্ভুক্ত করতে পারেন।

এই উত্তরটি একটি ফাংশনের রূপ নেবে:

void info(std::chrono::sys_days sd);

sys_daysএকটি দিন-স্পষ্টতা হয় time_pointমধ্যে system_clockপরিবার। এর অর্থ এটি 1970-01-01 00:00:00 ইউটিসি থেকে কেবল কয়েক দিনের গণনা। প্রকারের উপন্যাসটি sys_daysC ++ 20 এর সাথে নতুন তবে অন্তর্নিহিত টাইপটি সি ++ 11 ( time_point<system_clock, duration<int, ratio<86400>>>) থেকে পাওয়া যায় । আপনি ব্যবহার করেন তাহলে ওপেন সোর্স সি ++ 20 প্রিভিউ গ্রন্থাগার , sys_daysহয় namespace date

নীচের কোডটি স্থানীয়ভাবে ফাংশন ধরেছে:

using namespace std;
using namespace std::chrono;

ভার্বোসটি হ্রাস করতে। আপনি যদি ওপেন-সোর্স সি ++ 20 পূর্বরূপ লাইব্রেরি নিয়ে পরীক্ষা - নিরীক্ষা করছেন তবে ধরেও নিন:

using namespace date;

শিরোনাম

প্রথম দুটি লাইন আউটপুট করা সহজ:

cout << format("{:%d %B %Y is a %A}\n", sd)
     << "\nAdditional facts\n";

শুধু তারিখ নেওয়া sdএবং ব্যবহারের formatপরিচিত সঙ্গে strftime/ put_timeতারিখ এবং টেক্সট প্রিন্ট আউট করতে পতাকা। ওপেন সোর্স সি ++ 20 প্রিভিউ গ্রন্থাগার এখনো একত্রিত করেননি FMT গ্রন্থাগার , এবং তাই সামান্য রদবদল ফরম্যাট স্ট্রিং ব্যবহার "%d %B %Y is a %A\n"

এটি আউটপুট (উদাহরণস্বরূপ):

26 December 2019 is a Thursday

Additional facts

সাধারণ মধ্যবর্তী ফলাফল একবার গণনা করা

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

year_month_day ymd = sd;
auto y = ymd.year();
auto m = ymd.month();
weekday wd{sd};
sys_days NewYears = y/1/1;
sys_days LastDayOfYear = y/12/31;

আমাদের বছর এবং মাসের ক্ষেত্র sdএবং weekdayসপ্তাহের দিন প্রয়োজন হবে। এই পদ্ধতিতে একবার এবং সকলের জন্য এটি গণনা করা দক্ষ। আমাদের চলতি বছরের প্রথম এবং শেষ দিনগুলিও (একাধিকবার) প্রয়োজন হবে। এটা এই সময়ে বলা কঠিন, কিন্তু এটা প্রকার এই মান সংরক্ষণ করতে কার্যকরী sys_daysহিসেবে তাদের পরবর্তী ব্যবহারের জন্য শুধুমাত্র দিনের ওরিয়েন্টেড গাণিতিক যা দিয়ে হয় sys_daysহয় খুব (উপ-ন্যানোসেকেন্ড গতি) এ দক্ষ।

ঘটনা 1: বছরের দিন সংখ্যা এবং বছরে কত দিন বাকি

auto dn = sd - NewYears + days{1};
auto dl = LastDayOfYear - sd;
cout << "* It is day number " << dn/days{1} << " of the year, "
     << dl/days{1} << " days left.\n";

জানুয়ারী 1 দিন 1 হচ্ছে, এবং তারপর সাথে বাইরে বছরের দিন সংখ্যা এই কপি করে প্রিন্ট, এছাড়াও দিন বছরের মধ্যে অবশিষ্ট সহ না সংখ্যা ছাপে আউট sd। এটি করার গণনা তুচ্ছ। দ্বারা প্রতিটি ফলাফল ডিভাইডিং days{1}ভাবে দিনের সংখ্যা বের করে আনতে হয় dnএবং dlউদ্দেশ্য বিন্যাসের জন্য একটি অবিচ্ছেদ্য টাইপ করুন।

ঘটনা 2: এই সপ্তাহের দিন সংখ্যা এবং বছরে সপ্তাহের দিন সংখ্যা

sys_days first_wd = y/1/wd[1];
sys_days last_wd = y/12/wd[last];
auto total_wd = (last_wd - first_wd)/weeks{1} + 1;
auto n_wd = (sd - first_wd)/weeks{1} + 1;
cout << format("* It is {:%A} number ", wd) << n_wd << " out of "
     << total_wd << format(" in {:%Y}.\n}", y);

wdএই নিবন্ধের শীর্ষে গণনা করা সপ্তাহের দিন (সোমবার থেকে রবিবার)। এই গণনার কর্ম সঞ্চালন করার জন্য আমরা প্রথমে প্রথম ও শেষ তারিখ প্রয়োজন wdবছরের মধ্যে এর y। জানুয়ারীতে y/1/wd[1]এটি প্রথম এবং ডিসেম্বরে এটি সর্বশেষ ।wdy/12/wd[last]wd

wdবছরে মোট মোট সংখ্যা এই দুটি তারিখের (সপ্তাহের 1) মধ্যে সপ্তাহের সংখ্যা মাত্র। উপ-প্রকাশটি last_wd - first_wdদুটি তারিখের মধ্যে দিনের সংখ্যা। এই ফলাফলকে 1 সপ্তাহের সাথে ভাগ করে নেওয়ার ফলে দুটি তারিখের মধ্যে সপ্তাহের সংখ্যা হ'ল একটি অবিচ্ছেদ্য ধরণের ফলাফল হয়।

সপ্তাহ সংখ্যা গত পরিবর্তে বর্তমান দিনের সঙ্গে এক শুরু ব্যতীত সপ্তাহ মোট সংখ্যা হিসাবে একই ভাবে সম্পন্ন করা হয় wdবছরের: sd - first_wd

ঘটনা 3: এই সপ্তাহের দিন সংখ্যা এবং মাসে সপ্তাহের দিন সংখ্যা

first_wd = y/m/wd[1];
last_wd = y/m/wd[last];
total_wd = (last_wd - first_wd)/weeks{1} + 1;
n_wd = (sd - first_wd)/weeks{1} + 1;
cout << format("* It is {:%A} number }", wd) << n_wd << " out of "
     << total_wd << format(" in {:%B %Y}.\n", y/m);

এটি ঠিক ফ্যাক্ট 2 এর মতো কাজ করে, আমরা wdবছরের বছরের y/mপরিবর্তে বছরের প্রথম মাসের প্রথম এবং শেষের জুটি দিয়ে শুরু করি ।

ঘটনা 4: বছরে দিনের সংখ্যা

auto total_days = LastDayOfYear - NewYears + days{1};
cout << format("* Year {:%Y} has ", y) << total_days/days{1} << " days.\n";

কোডটি বেশ নিজের পক্ষে কথা বলে।

ঘটনা 5 মাসে মাসে সংখ্যা

total_days = sys_days{y/m/last} - sys_days{y/m/1} + days{1};
cout << format("* {:%B %Y} has ", y/m) << total_days/days{1} << " days.\n";

প্রকাশটি y/m/lastবছরের-মাসের জুটির শেষ দিন y/mএবং অবশ্যই y/m/1মাসের প্রথম দিন। উভয়ই রূপান্তরিত হয়েছে sys_daysযাতে তাদের মধ্যে দিনের সংখ্যা পেতে তাদের বিয়োগ করা যায়। 1-ভিত্তিক গণনার জন্য 1 যুক্ত করুন।

ব্যবহার

info এটি ব্যবহার করা যেতে পারে:

info(December/26/2019);

বা এই মত:

info(floor<days>(system_clock::now()));

এখানে উদাহরণ আউটপুট:

26 December 2019 is a Thursday

Additional facts
* It is day number 360 of the year, 5 days left.
* It is Thursday number 52 out of 52 in 2019.
* It is Thursday number 4 out of 4 in December 2019.
* Year 2019 has 365 days.
* December 2019 has 31 days.

সম্পাদন করা

যারা "প্রচলিত সিনট্যাক্স" পছন্দ করেন না তাদের জন্য একটি সম্পূর্ণ "কনস্ট্রাক্টর সিনট্যাক্স" রয়েছে যা পরিবর্তে ব্যবহার করা যেতে পারে।

উদাহরণ স্বরূপ:

sys_days NewYears = y/1/1;
sys_days first_wd = y/1/wd[1];
sys_days last_wd = y/12/wd[last];

দ্বারা প্রতিস্থাপন করা যেতে পারে:

sys_days NewYears = year_month_day{y, month{1}, day{1}};
sys_days first_wd = year_month_weekday{y, month{1}, weekday_indexed{wd, 1}};
sys_days last_wd = year_month_weekday_last{y, month{12}, weekday_last{wd}};

5
বিভাজন অপারেটরদের পুরানো অপব্যবহারের চেয়ে বিভাগ অপারেটরের এই নতুন আপত্তি আরও খারাপ। এটি আমাকে দু: খিত করে তোলে :(
ডেভ

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

1
সম্পূর্ণ অসমত। এটি দেখতে দুর্দান্ত লাগছে, এটি বোঝা সহজ এবং উল্লেখযোগ্যভাবে আরও ভার্জোজ ভার্সনের চেয়ে এটি পড়া সহজ।
ক্যাসিও রেনান

@ ক্যাসিওরেনান হতে পারে তবে মনে রাখবেন সিন্টেক্সের অপব্যবহারটি প্রায়শই অপ্রত্যাশিত আচরণের সাথে আসে। পূর্বোক্ত বিট শিফটগুলির সাথে, উদাহরণস্বরূপ, আচরণটি নোট করুন std::cout << "a*b = " << a*b << "; a^b = " << a^b << '\n';(যা ভাগ্যক্রমে, প্রায় সবসময় সংকলনের সময় ধরা পড়ে, তবে এখনও বিরক্তি হয়)। সুতরাং আমি এই নতুন বিভাগ অপারেটর অপব্যবহার ব্যবহার করার সময় সতর্ক হতে হবে।
রুস্লান

@ রাস্লান সাবধানতা যে কোনও নতুন লাইব্রেরির সাথে সর্বদা সতর্ক থাকে। এই কারণেই এটি ২০১৫ সাল থেকে নিখরচায় এবং প্রকাশ্যে পরীক্ষা করা হয়েছে clients ক্লায়েন্টদের কাছ থেকে প্রাপ্ত প্রতিক্রিয়াগুলি আবার ডিজাইনে অন্তর্ভুক্ত করা হয়েছে। এটি ইতিবাচক ক্ষেত্রের অভিজ্ঞতার বছরগুলির দৃ it় ভিত্তি না হওয়া পর্যন্ত এটি প্রমিতকরণের জন্য প্রস্তাব করা হয়নি। বিশেষত, অপারেটরগুলির ব্যবহার অপারেটর অগ্রাধিকার বিবেচনা করে ডিজাইন করা হয়েছে, ক্ষেত্রটি ব্যাপকভাবে পরীক্ষা করা হয়েছে এবং এটি একটি সমতুল্য "কনস্ট্রাক্টর এপিআই" নিয়ে আসে। দেখুন star-history.t9t.io/#HowardHinnant/date&google/cctz এবং youtube.com/watch?v=tzyGjOm8AKo
হাওয়ার্ড হিন্যান্ট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.