c# - একটি প্রদত্ত DateTime বস্তু ব্যবহার করে, একটি মাসের প্রথম এবং শেষ দিন পেয়ে




.net winforms (12)

আমি সেই দিনটির প্রথম দিন এবং শেষ দিনটি পেতে চাই যেখানে একটি নির্দিষ্ট তারিখ থাকে। তারিখটি UI ক্ষেত্রের একটি মান থেকে আসে।

আমি একটি সময় পিকচার ব্যবহার করছি আমি বলতে পারে

var maxDay = dtpAttendance.MaxDate.Day;

কিন্তু আমি একটি DateTime বস্তু থেকে এটি পেতে চেষ্টা করছি। তাই যদি আমি এই আছে ...

DateTime dt = DateTime.today;

কিভাবে প্রথম দিন এবং dt থেকে মাসের শেষ দিন পেতে?


Answers

আপনি শুধুমাত্র তারিখ সম্পর্কে যত্ন যদি

var firstDay = new DateTime(date.Year, date.Month, 1, 0, 0, 0, date.Kind);
var lastDay = new DateTime(date.Year, date.Month, 1, 0, 0, 0, date.Kind).AddMonths(1).AddDays(-1);

আপনি সময় সংরক্ষণ করতে চান

var firstDay = new DateTime(date.Year, date.Month, 1, date.Hour, date.Minute, date.Second, date.Kind);
var lastDay = new DateTime(date.Year, date.Month, 1, date.Hour, date.Minute, date.Second, date.Kind).AddMonths(1).AddDays(-1);

এখানে গ্রহণযোগ্য উত্তর অ্যাকাউন্ট টাইম উদাহরণ ধরনের বিবেচনা করে না। উদাহরণস্বরূপ, যদি আপনার মূল তারিখটাইম উদাহরণটি একটি ইউটিসি ধরনের হয় তবে একটি নতুন তারিখের উদাহরণ তৈরি করে আপনি একটি অজানা ধরনের উদাহরণ তৈরি করবেন যা সার্ভার সেটিংসের উপর ভিত্তি করে স্থানীয় সময় হিসাবে বিবেচিত হবে। অতএব, মাসের প্রথম এবং শেষ তারিখটি পেতে আরো সঠিক উপায় এই হবে:

var now = DateTime.UtcNow;
var first = now.Date.AddDays(-(now.Date.Day - 1));
var last = first.AddMonths(1).AddTicks(-1);

এইভাবে তারিখ টাইম ইনস্ট্যান্সের মূল ধরনের সংরক্ষণ করা হয়।


@ সের্জি এবং @ স্টেফেনের উত্তরগুলিতে এটি আরও দীর্ঘ মন্তব্য। অতীতেও একই রকম কোড লিখতে গিয়ে আমি স্বচ্ছতার কথা মনে রাখার সময় সর্বাধিক performant পরীক্ষা করার সিদ্ধান্ত নিলাম।

ফল

এখানে উদাহরণস্বরূপ 10 মিলিয়ন পুনরাবৃত্তি পরীক্ষার ফলাফল রয়েছে:

2257 ms for FirstDayOfMonth_AddMethod()
2406 ms for FirstDayOfMonth_NewMethod()
6342 ms for LastDayOfMonth_AddMethod()
4037 ms for LastDayOfMonth_AddMethodWithDaysInMonth()
4160 ms for LastDayOfMonth_NewMethod()
4212 ms for LastDayOfMonth_NewMethodWithReuseOfExtMethod()
2491 ms for LastDayOfMonth_SpecialCase()

কোড

কম্পাইলার অপ্টিমাইজেশান চালু করে পরীক্ষা চালানোর জন্য আমি LINQPad 4 (সি # প্রোগ্রাম মোডে) ব্যবহার করেছি । এখানে স্বচ্ছতা এবং সুবিধার জন্য এক্সটেনশন পদ্ধতি হিসাবে পরীক্ষিত কোডটি যাচাই করা হয়েছে:

public static class DateTimeDayOfMonthExtensions
{
    public static DateTime FirstDayOfMonth_AddMethod(this DateTime value)
    {
        return value.Date.AddDays(1 - value.Day);
    }

    public static DateTime FirstDayOfMonth_NewMethod(this DateTime value)
    {
        return new DateTime(value.Year, value.Month, 1);
    }

    public static DateTime LastDayOfMonth_AddMethod(this DateTime value)
    {
        return value.FirstDayOfMonth_AddMethod().AddMonths(1).AddDays(-1);
    }

    public static DateTime LastDayOfMonth_AddMethodWithDaysInMonth(this DateTime value)
    {
        return value.Date.AddDays(DateTime.DaysInMonth(value.Year, value.Month) - value.Day);
    }

    public static DateTime LastDayOfMonth_SpecialCase(this DateTime value)
    {
        return value.AddDays(DateTime.DaysInMonth(value.Year, value.Month) - 1);
    }

    public static int DaysInMonth(this DateTime value)
    {
        return DateTime.DaysInMonth(value.Year, value.Month);
    }

    public static DateTime LastDayOfMonth_NewMethod(this DateTime value)
    {
        return new DateTime(value.Year, value.Month, DateTime.DaysInMonth(value.Year, value.Month));
    }

    public static DateTime LastDayOfMonth_NewMethodWithReuseOfExtMethod(this DateTime value)
    {
        return new DateTime(value.Year, value.Month, value.DaysInMonth());
    }
}

void Main()
{
    Random rnd = new Random();
    DateTime[] sampleData = new DateTime[10000000];

    for(int i = 0; i < sampleData.Length; i++) {
        sampleData[i] = new DateTime(1970, 1, 1).AddDays(rnd.Next(0, 365 * 50));
    }

    GC.Collect();
    System.Diagnostics.Stopwatch sw = System.Diagnostics.Stopwatch.StartNew();
    for(int i = 0; i < sampleData.Length; i++) {
        DateTime test = sampleData[i].FirstDayOfMonth_AddMethod();
    }
    string.Format("{0} ms for FirstDayOfMonth_AddMethod()", sw.ElapsedMilliseconds).Dump();

    GC.Collect();
    sw.Restart();
    for(int i = 0; i < sampleData.Length; i++) {
        DateTime test = sampleData[i].FirstDayOfMonth_NewMethod();
    }
    string.Format("{0} ms for FirstDayOfMonth_NewMethod()", sw.ElapsedMilliseconds).Dump();

    GC.Collect();
    sw.Restart();
    for(int i = 0; i < sampleData.Length; i++) {
        DateTime test = sampleData[i].LastDayOfMonth_AddMethod();
    }
    string.Format("{0} ms for LastDayOfMonth_AddMethod()", sw.ElapsedMilliseconds).Dump();

    GC.Collect();
    sw.Restart();
    for(int i = 0; i < sampleData.Length; i++) {
        DateTime test = sampleData[i].LastDayOfMonth_AddMethodWithDaysInMonth();
    }
    string.Format("{0} ms for LastDayOfMonth_AddMethodWithDaysInMonth()", sw.ElapsedMilliseconds).Dump();

    GC.Collect();
    sw.Restart();
    for(int i = 0; i < sampleData.Length; i++) {
        DateTime test = sampleData[i].LastDayOfMonth_NewMethod();
    }
    string.Format("{0} ms for LastDayOfMonth_NewMethod()", sw.ElapsedMilliseconds).Dump();

    GC.Collect();
    sw.Restart();
    for(int i = 0; i < sampleData.Length; i++) {
        DateTime test = sampleData[i].LastDayOfMonth_NewMethodWithReuseOfExtMethod();
    }
    string.Format("{0} ms for LastDayOfMonth_NewMethodWithReuseOfExtMethod()", sw.ElapsedMilliseconds).Dump();

    for(int i = 0; i < sampleData.Length; i++) {
        sampleData[i] = sampleData[i].FirstDayOfMonth_AddMethod();
    }

    GC.Collect();
    sw.Restart();
    for(int i = 0; i < sampleData.Length; i++) {
        DateTime test = sampleData[i].LastDayOfMonth_SpecialCase();
    }
    string.Format("{0} ms for LastDayOfMonth_SpecialCase()", sw.ElapsedMilliseconds).Dump();

}

বিশ্লেষণ

আমি এই ফলাফল কিছু বিস্মিত ছিল।

যদিও এটিতে অনেক কিছু নেই তবে প্রথম FirstDayOfMonth_AddMethod FirstDayOfMonth_NewMethod পরীক্ষার সর্বাধিক FirstDayOfMonth_NewMethod মধ্যে FirstDayOfMonth_NewMethod চেয়ে সামান্য দ্রুত ছিল। যাইহোক, আমি মনে করি পরেরটির সামান্য স্পষ্ট উদ্দেশ্য রয়েছে এবং তাই আমার কাছে এটির অগ্রাধিকার রয়েছে।

LastDayOfMonth_AddMethod LastDayOfMonth_AddMethodWithDaysInMonth , LastDayOfMonth_NewMethod এবং LastDayOfMonth_NewMethodWithReuseOfExtMethod বিরুদ্ধে একটি পরিষ্কার LastDayOfMonth_AddMethod ছিল। দ্রুততম তিনের মধ্যে এর মধ্যে অনেক কিছুই নেই এবং তাই এটি আপনার ব্যক্তিগত পছন্দে আসে। আমি অন্য দরকারী এক্সটেনশান পদ্ধতির পুনঃব্যবহারের সাথে LastDayOfMonth_NewMethodWithReuseOfExtMethod এর স্বচ্ছতা চয়ন করি। IMHO এর উদ্দেশ্য স্পষ্ট এবং আমি ছোট কর্মক্ষমতা খরচ গ্রহণ করতে ইচ্ছুক।

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

উপসংহার

এখানে আমার পছন্দগুলির সাথে একটি এক্সটেনশান পদ্ধতি ক্লাস এবং @ স্টেফেন আমি সাধারণ চুক্তিতে বিশ্বাস করি:

public static class DateTimeDayOfMonthExtensions
{
    public static DateTime FirstDayOfMonth(this DateTime value)
    {
        return new DateTime(value.Year, value.Month, 1);
    }

    public static int DaysInMonth(this DateTime value)
    {
        return DateTime.DaysInMonth(value.Year, value.Month);
    }

    public static DateTime LastDayOfMonth(this DateTime value)
    {
        return new DateTime(value.Year, value.Month, value.DaysInMonth());
    }
}

যদি আপনি এই পর্যন্ত পেয়েছেন, সময় জন্য আপনাকে ধন্যবাদ! এটা মজা হয়েছে: ¬)। আপনি এই অ্যালগরিদম জন্য অন্য কোন পরামর্শ আছে যদি মন্তব্য করুন।


এটা সহজ উপায়

Begin = new DateTime(DateTime.Now.Year, DateTime.Now.Month,1).ToShortDateString();
End = new DataFim.Text = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.DaysInMonth(DateTime.Now.Year, DateTime.Now.Month)).ToShortDateString();

ন্যেট API (কেবল অন্য উপায়) সহ মাস পরিসীমা পান:

DateTime date = ...
var firstDayOfMonth = new DateTime(date.Year, date.Month, 1);
var lastDayOfMonth = new DateTime(date.Year, date.Month, DateTime.DaysInMonth(date.Year, date.Month));

DateTime dCalcDate = DateTime.Now;
dtpFromEffDate.Value = new DateTime(dCalcDate.Year, dCalcDate.Month, 1);
dptToEffDate.Value = new DateTime(dCalcDate.Year, dCalcDate.Month, DateTime.DaysInMonth(dCalcDate.Year, dCalcDate.Month));

আর একবার চেষ্টা কর:

string strDate = DateTime.Now.ToString("MM/01/yyyy");

" Last day of month " আসলে " First day of *next* month, minus 1 "। তাই এখানে যা আমি ব্যবহার করি, "DaysInMonth" পদ্ধতির কোন প্রয়োজন নেই:

public static DateTime FirstDayOfMonth(this DateTime value)
{
    return new DateTime(value.Year, value.Month, 1);
}

public static DateTime LastDayOfMonth(this DateTime value)
{
    return value.FirstDayOfMonth()
        .AddMonths(1)
        .AddMinutes(-1);
}

দ্রষ্টব্য: আমি AddMinutes(-1) ব্যবহার করি, কারণ AddDays(-1) এখানে নয় কারণ সাধারণত তারিখের সময়কালের জন্য রিপোর্ট করার জন্য আপনাকে এই তারিখের ফাংশনগুলি দরকার এবং যখন আপনি কোনও সময়ের জন্য একটি প্রতিবেদন তৈরি করেন তখন "শেষ তারিখ" আসলে Oct 31 2015 23:59:59 মত কিছু হওয়া উচিত যাতে আপনার প্রতিবেদনটি সঠিকভাবে কাজ করে - মাসের শেষ দিন থেকে সমস্ত তথ্য সহ।

আপনি আসলে এখানে "মাসের শেষ মুহূর্ত " পাবেন। শেষ দিন না।

ঠিক আছে, আমি এখন চুপ করে যাচ্ছি।


এখানে আপনি সেই মাসের 1 দিন মুছে ফেলার পরিবর্তে বর্তমান মাসের প্রথম দিনের জন্য এক মাস যোগ করতে পারেন।

DateTime now = DateTime.Now;
var startDate = new DateTime(now.Year, now.Month, 1);
var endDate = startDate.AddMonths(1).AddDays(-1);

আমি আমার স্ক্রিপ্টে এটি ব্যবহার করেছি (আমার জন্য কাজ করে) তবে আমার তারিখ এবং কোনও সময় সেরে ফেলার প্রয়োজন নেই তবে আমার সম্পূর্ণ তারিখ প্রয়োজন।

public DateTime GetLastDayOfTheMonth()
{
    int daysFromNow = DateTime.DaysInMonth(DateTime.Now.Year, DateTime.Now.Month) - (int)DateTime.Now.Day;
    return DateTime.Now.AddDays(daysFromNow);
}

DateTime dCalcDate = DateTime.Now;
var startDate = new DateTime(Convert.ToInt32(Year), Convert.ToInt32(Month), 1);
var endDate = new DateTime(Convert.ToInt32(Year), Convert.ToInt32(Month), DateTime.DaysInMonth((Convert.ToInt32(Year)), Convert.ToInt32(Month)));

আমি এই ব্যবহার (আবার অঞ্চল স্বাধীন (ইউকে))

set bklog=%date:~6,4%-%date:~3,2%-%date:~0,2%_%time:~0,2%%time:~3,2%






c# .net winforms datetime