كيف يمكنني الحصول على DateTime لبداية الأسبوع؟

StackOverflow https://stackoverflow.com/questions/38039

  •  09-06-2019
  •  | 
  •  

سؤال

كيف يمكنني العثور على بداية الأسبوع (كل من الأحد والاثنين) مع العلم بالوقت الحالي في C#؟

شيء مثل:

DateTime.Now.StartWeek(Monday);
هل كانت مفيدة؟

المحلول

استخدم طريقة التمديد.إنهم الجواب على كل شيء، كما تعلمون!;)

public static class DateTimeExtensions
{
    public static DateTime StartOfWeek(this DateTime dt, DayOfWeek startOfWeek)
    {
        int diff = (7 + (dt.DayOfWeek - startOfWeek)) % 7;
        return dt.AddDays(-1 * diff).Date;
    }
}

والتي يمكن استخدامها على النحو التالي:

DateTime dt = DateTime.Now.StartOfWeek(DayOfWeek.Monday);
DateTime dt = DateTime.Now.StartOfWeek(DayOfWeek.Sunday);

نصائح أخرى

أسرع طريقة يمكنني التوصل إليها هي:

var sunday = DateTime.Today.AddDays(-(int)DateTime.Today.DayOfWeek);

إذا كنت تريد أن يكون أي يوم آخر من أيام الأسبوع هو تاريخ البدء، فكل ما عليك فعله هو إضافة قيمة DayOfWeek إلى النهاية

var monday = DateTime.Today.AddDays(-(int)DateTime.Today.DayOfWeek + (int)DayOfWeek.Monday);

var tuesday = DateTime.Today.AddDays(-(int)DateTime.Today.DayOfWeek + (int)DayOfWeek.Tuesday);

أكثر تفصيلاً ووعيًا بالثقافة:

System.Globalization.CultureInfo ci = 
    System.Threading.Thread.CurrentThread.CurrentCulture;
DayOfWeek fdow = ci.DateTimeFormat.FirstDayOfWeek;
DayOfWeek today = DateTime.Now.DayOfWeek;
DateTime sow = DateTime.Now.AddDays(-(today - fdow)).Date;

استخدام التاريخ والوقت بطلاقة:

var monday = DateTime.Now.Previous(DayOfWeek.Monday);
var sunday = DateTime.Now.Previous(DayOfWeek.Sunday);

قبيح لكنه على الأقل يعطي التواريخ الصحيحة

مع بداية الأسبوع التي حددها النظام:

    public static DateTime FirstDateInWeek(this DateTime dt)
    {
        while (dt.DayOfWeek != System.Threading.Thread.CurrentThread.CurrentCulture.DateTimeFormat.FirstDayOfWeek)
            dt = dt.AddDays(-1);
        return dt;
    }

بدون:

    public static DateTime FirstDateInWeek(this DateTime dt, DayOfWeek weekStartDay)
    {
        while (dt.DayOfWeek != weekStartDay)
            dt = dt.AddDays(-1);
        return dt;
    }

دعونا نجمع بين الإجابة الآمنة للثقافة وإجابة طريقة الامتداد:

public static class DateTimeExtensions
{
    public static DateTime StartOfWeek(this DateTime dt, DayOfWeek startOfWeek)
    {
        System.Globalization.CultureInfo ci = System.Threading.Thread.CurrentThread.CurrentCulture;
        DayOfWeek fdow = ci.DateTimeFormat.FirstDayOfWeek;
        return DateTime.Today.AddDays(-(DateTime.Today.DayOfWeek- fdow));
    }
}

قد يكون هذا بمثابة اختراق إلى حد ما، ولكن يمكنك إرسال خاصية .DayOfWeek إلى int (وهو عبارة عن تعداد وبما أنه لم يتم تغيير نوع البيانات الأساسي الخاص به، فإن الإعدادات الافتراضية هي int) واستخدام ذلك لتحديد البداية السابقة للأسبوع .

يبدو أن الأسبوع المحدد في تعداد DayOfWeek يبدأ يوم الأحد، لذلك إذا طرحنا 1 من هذه القيمة فسيكون ذلك مساويًا لعدد الأيام التي يسبق يوم الاثنين التاريخ الحالي.نحتاج أيضًا إلى تعيين يوم الأحد (0) ليكون مساويًا لـ 7، لذلك نظرًا لأن 1 - 7 = -6، سيتم ربط يوم الأحد بيوم الاثنين السابق: -

DateTime now = DateTime.Now;
int dayOfWeek = (int)now.DayOfWeek;
dayOfWeek = dayOfWeek == 0 ? 7 : dayOfWeek;
DateTime startOfWeek = now.AddDays(1 - (int)now.DayOfWeek);

يعد رمز يوم الأحد السابق أبسط حيث لا يتعين علينا إجراء هذا التعديل: -

DateTime now = DateTime.Now;
int dayOfWeek = (int)now.DayOfWeek;
DateTime startOfWeek = now.AddDays(-(int)now.DayOfWeek);

سيعطيك هذا يوم الأحد السابق (على ما أعتقد):

DateTime t = DateTime.Now;
t -= new TimeSpan ((int) t.DayOfWeek, 0, 0, 0);

للاثنين

DateTime startAtMonday = DateTime.Now.AddDays(DayOfWeek.Monday - DateTime.Now.DayOfWeek);

ليوم الأحد

DateTime startAtSunday = DateTime.Now.AddDays(DayOfWeek.Sunday- DateTime.Now.DayOfWeek);
using System;
using System.Globalization;

namespace MySpace
{
    public static class DateTimeExtention
    {
        // ToDo: Need to provide culturaly neutral versions.

        public static DateTime GetStartOfWeek(this DateTime dt)
        {
            DateTime ndt = dt.Subtract(TimeSpan.FromDays((int)dt.DayOfWeek));
            return new DateTime(ndt.Year, ndt.Month, ndt.Day, 0, 0, 0, 0);
        }

        public static DateTime GetEndOfWeek(this DateTime dt)
        {
            DateTime ndt = dt.GetStartOfWeek().AddDays(6);
            return new DateTime(ndt.Year, ndt.Month, ndt.Day, 23, 59, 59, 999);
        }

        public static DateTime GetStartOfWeek(this DateTime dt, int year, int week)
        {
            DateTime dayInWeek = new DateTime(year, 1, 1).AddDays((week - 1) * 7);
            return dayInWeek.GetStartOfWeek();
        }

        public static DateTime GetEndOfWeek(this DateTime dt, int year, int week)
        {
            DateTime dayInWeek = new DateTime(year, 1, 1).AddDays((week - 1) * 7);
            return dayInWeek.GetEndOfWeek();
        }
    }
}

تجميع كل ذلك معًا، مع العولمة والسماح بتحديد اليوم الأول من الأسبوع كجزء من المكالمة التي لدينا

public static DateTime StartOfWeek ( this DateTime dt, DayOfWeek? firstDayOfWeek )
{
    DayOfWeek fdow;

    if ( firstDayOfWeek.HasValue  )
    {
        fdow = firstDayOfWeek.Value;
    }
    else
    {
        System.Globalization.CultureInfo ci = System.Threading.Thread.CurrentThread.CurrentCulture;
        fdow = ci.DateTimeFormat.FirstDayOfWeek;
    }

    int diff = dt.DayOfWeek - fdow;

    if ( diff < 0 )
    {
        diff += 7;
    }

    return dt.AddDays( -1 * diff ).Date;

}
var now = System.DateTime.Now;

var result = now.AddDays(-((now.DayOfWeek - System.Threading.Thread.CurrentThread.CurrentCulture.DateTimeFormat.FirstDayOfWeek + 7) % 7)).Date;

سيعطيك هذا منتصف ليل الأحد الأول من الأسبوع:

DateTime t = DateTime.Now;
t -= new TimeSpan ((int) t.DayOfWeek, t.Hour, t.Minute, t.Second);

يمنحك هذا أول يوم اثنين عند منتصف الليل:

DateTime t = DateTime.Now;
t -= new TimeSpan ((int) t.DayOfWeek - 1, t.Hour, t.Minute, t.Second);

جرب هذا في c#. باستخدام هذا الرمز، يمكنك الحصول على التاريخ الأول وآخر تاريخ لأسبوع معين. هنا الأحد هو اليوم الأول والسبت هو اليوم الأخير ولكن يمكنك تعيين كلا اليومين وفقًا لثقافتك

DateTime firstDate = GetFirstDateOfWeek(DateTime.Parse("05/09/2012").Date,DayOfWeek.Sunday);
DateTime lastDate = GetLastDateOfWeek(DateTime.Parse("05/09/2012").Date, DayOfWeek.Saturday);

public static DateTime GetFirstDateOfWeek(DateTime dayInWeek, DayOfWeek firstDay)
{
    DateTime firstDayInWeek = dayInWeek.Date;
    while (firstDayInWeek.DayOfWeek != firstDay)
        firstDayInWeek = firstDayInWeek.AddDays(-1);

    return firstDayInWeek;
}
public static DateTime GetLastDateOfWeek(DateTime dayInWeek, DayOfWeek firstDay)
{
    DateTime lastDayInWeek = dayInWeek.Date;
    while (lastDayInWeek.DayOfWeek != firstDay)
        lastDayInWeek = lastDayInWeek.AddDays(1);

    return lastDayInWeek;
}

حاولت عدة مرات ولكن لم تحل المشكلة مع بدء أسبوع من يوم الاثنين، مما أدى إلى إعطائي يوم الاثنين القادم يوم الأحد.لذلك قمت بتعديله قليلاً وجعلته يعمل بهذا الكود:

int delta = DayOfWeek.Monday - DateTime.Now.DayOfWeek;
DateTime monday = DateTime.Now.AddDays(delta == 1 ? -6 : delta);
return monday;

يجب أن تقوم الطريقة التالية بإرجاع التاريخ والوقت الذي تريده.ضع علامة صح على أن يوم الأحد هو أول يوم في الأسبوع، وخطأ على يوم الاثنين:

private DateTime getStartOfWeek(bool useSunday)
{
    DateTime now = DateTime.Now;
    int dayOfWeek = (int)now.DayOfWeek;

    if(!useSunday)
        dayOfWeek--;

    if(dayOfWeek < 0)
    {// day of week is Sunday and we want to use Monday as the start of the week
    // Sunday is now the seventh day of the week
        dayOfWeek = 6;
    }

    return now.AddDays(-1 * (double)dayOfWeek);
}

شكرا على الأمثلة.كنت بحاجة دائمًا إلى استخدام "CurrentCulture" في اليوم الأول من الأسبوع وبالنسبة للمصفوفة كنت بحاجة إلى معرفة رقم اليوم الدقيق..إذن هذه هي ملحقاتي الأولى:

public static class DateTimeExtensions
{
    //http://stackoverflow.com/questions/38039/how-can-i-get-the-datetime-for-the-start-of-the-week
    //http://stackoverflow.com/questions/1788508/calculate-date-with-monday-as-dayofweek1
    public static DateTime StartOfWeek(this DateTime dt)
    {
        //difference in days
        int diff = (int)dt.DayOfWeek - (int)CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek; //sunday=always0, monday=always1, etc.

        //As a result we need to have day 0,1,2,3,4,5,6 
        if (diff < 0)
        {
            diff += 7;
        }
        return dt.AddDays(-1 * diff).Date;
    }

    public static int DayNoOfWeek(this DateTime dt)
    {
        //difference in days
        int diff = (int)dt.DayOfWeek - (int)CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek; //sunday=always0, monday=always1, etc.

        //As a result we need to have day 0,1,2,3,4,5,6 
        if (diff < 0)
        {
            diff += 7;
        }
        return diff + 1; //Make it 1..7
    }
}

يبدو أن لا أحد قد أجاب على هذا بشكل صحيح حتى الآن.سألصق الحل الخاص بي هنا في حالة احتياج أي شخص إليه.يعمل الكود التالي بغض النظر عما إذا كان اليوم الأول من الأسبوع هو يوم الاثنين أو الأحد أو أي شيء آخر.

public static class DateTimeExtension
{
  public static DateTime GetFirstDayOfThisWeek(this DateTime d)
  {
    CultureInfo ci = System.Threading.Thread.CurrentThread.CurrentCulture;
    var first = (int)ci.DateTimeFormat.FirstDayOfWeek;
    var current = (int)d.DayOfWeek;

    var result = first <= current ?
      d.AddDays(-1 * (current - first)) :
      d.AddDays(first - current - 7);

    return result;
  }
}

class Program
{
  static void Main()
  {
    System.Threading.Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo("en-US");
    Console.WriteLine("Current culture set to en-US");
    RunTests();
    Console.WriteLine();
    System.Threading.Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo("da-DK");
    Console.WriteLine("Current culture set to da-DK");
    RunTests();
    Console.ReadLine();
  }

  static void RunTests()
  {
    Console.WriteLine("Today {1}: {0}", DateTime.Today.Date.GetFirstDayOfThisWeek(), DateTime.Today.Date.ToString("yyyy-MM-dd"));
    Console.WriteLine("Saturday 2013-03-02: {0}", new DateTime(2013, 3, 2).GetFirstDayOfThisWeek());
    Console.WriteLine("Sunday 2013-03-03: {0}", new DateTime(2013, 3, 3).GetFirstDayOfThisWeek());
    Console.WriteLine("Monday 2013-03-04: {0}", new DateTime(2013, 3, 4).GetFirstDayOfThisWeek());
  }
}

يعمل Modulo in C# سيئًا لـ -1mod7 (يجب أن يكون 6 ، C# إرجاع -1) لذلك ...سيبدو حل "oneliner" لهذا :)

private static DateTime GetFirstDayOfWeek(DateTime date)
    {
        return date.AddDays(-(((int)date.DayOfWeek - 1) - (int)Math.Floor((double)((int)date.DayOfWeek - 1) / 7) * 7));
    }

نفس الشيء في نهاية الأسبوع (بأسلوب @Compile هذه الإجابة):

    public static DateTime EndOfWeek(this DateTime dt)
    {
        int diff = 7 - (int)dt.DayOfWeek;

        diff = diff == 7 ? 0 : diff;

        DateTime eow = dt.AddDays(diff).Date;

        return new DateTime(eow.Year, eow.Month, eow.Day, 23, 59, 59, 999) { };
    }

الخطوة 1:إنشاء فئة ثابتة

  public static class TIMEE
{
    public static DateTime StartOfWeek(this DateTime dt, DayOfWeek startOfWeek)
    {
        int diff = (7 + (dt.DayOfWeek - startOfWeek)) % 7;
        return dt.AddDays(-1 * diff).Date;
    }
    public static DateTime EndOfWeek(this DateTime dt, DayOfWeek startOfWeek)
    {
        int diff = (7 - (dt.DayOfWeek - startOfWeek)) % 7;
        return dt.AddDays(1 * diff).Date;
    }
}

الخطوة 2:استخدم هذا الفصل للحصول على يوم بداية ونهاية الأسبوع

 DateTime dt =TIMEE.StartOfWeek(DateTime.Now ,DayOfWeek.Monday);
        DateTime dt1 = TIMEE.EndOfWeek(DateTime.Now, DayOfWeek.Sunday);

يمكنك استخدام الممتاز مكتبة المظلة:

using nVentive.Umbrella.Extensions.Calendar;
DateTime beginning = DateTime.Now.BeginningOfWeek();

ومع ذلك، فإنهم يفعل يبدو أنه تم تخزين يوم الاثنين باعتباره اليوم الأول من الأسبوع (راجع مكان الإقامة nVentive.Umbrella.Extensions.Calendar.DefaultDateTimeCalendarExtensions.WeekBeginsOn)، بحيث يكون الحل المترجم السابق أفضل قليلاً.مؤسف.

يحرر:وبالنظر إلى السؤال عن كثب، يبدو أن Umbrella قد تعمل بالفعل على حل هذه المشكلة أيضًا:

// Or DateTime.Now.PreviousDay(DayOfWeek.Monday)
DateTime monday = DateTime.Now.PreviousMonday(); 
DateTime sunday = DateTime.Now.PreviousSunday();

على الرغم من أنه من الجدير بالذكر أنه إذا طلبت يوم الاثنين السابق يوم الاثنين، فسوف يعيدك سبعة أيام.ولكن هذا صحيح أيضًا إذا كنت تستخدمه BeginningOfWeek, ، والذي يبدو وكأنه خطأ :(.

سيعيد هذا تواريخ بداية الأسبوع ونهايته:

    private string[] GetWeekRange(DateTime dateToCheck)
    {
        string[] result = new string[2];
        TimeSpan duration = new TimeSpan(0, 0, 0, 0); //One day 
        DateTime dateRangeBegin = dateToCheck;
        DateTime dateRangeEnd = DateTime.Today.Add(duration);

        dateRangeBegin = dateToCheck.AddDays(-(int)dateToCheck.DayOfWeek);
        dateRangeEnd = dateToCheck.AddDays(6 - (int)dateToCheck.DayOfWeek);

        result[0] = dateRangeBegin.Date.ToString();
        result[1] = dateRangeEnd.Date.ToString();
        return result;

    }

لقد قمت بنشر الكود الكامل لحساب بداية/نهاية الأسبوع والشهر والربع والسنة على مدونتيمدونة زاميرس

    namespace DateTimeExample
    {
        using System;

        public static class DateTimeExtension
        {
            public static DateTime GetMonday(this DateTime time)
            {
                if (time.DayOfWeek != DayOfWeek.Monday)
                    return GetMonday(time.AddDays(-1)); //Recursive call

                return time;
            }
        }

        internal class Program
        {
            private static void Main()
            {
                Console.WriteLine(DateTime.Now.GetMonday());
                Console.ReadLine();
            }
        }
    } 

هنا مزيج من عدد قليل من الإجابات.يستخدم طريقة تمديد تسمح بتمرير الثقافة، إذا لم يتم تمريرها، يتم استخدام الثقافة الحالية.وهذا سيمنحه أقصى قدر من المرونة وإعادة الاستخدام.

/// <summary>
/// Gets the date of the first day of the week for the date.
/// </summary>
/// <param name="date">The date to be used</param>
/// <param name="cultureInfo">If none is provided, the current culture is used</param>
/// <returns>The date of the beggining of the week based on the culture specifed</returns>
public static DateTime StartOfWeek(this DateTime date, CultureInfo cultureInfo=null) =>         
             date.AddDays(-1 * (7 + (date.DayOfWeek - (cultureInfo??CultureInfo.CurrentCulture).DateTimeFormat.FirstDayOfWeek)) % 7).Date;

مثال للاستخدام:

public static void TestFirstDayOfWeekExtension() {          
        DateTime date = DateTime.Now;
        foreach(System.Globalization.CultureInfo culture in CultureInfo.GetCultures(CultureTypes.UserCustomCulture | CultureTypes.SpecificCultures)) {
            Console.WriteLine($"{culture.EnglishName}: {date.ToShortDateString()} First Day of week: {date.StartOfWeek(culture).ToShortDateString()}");
        }
    }

إذا كنت تريد السبت أو الأحد أو أي يوم من أيام الأسبوع ولكن لا يتجاوز الأسبوع الحالي (السبت-الأحد) فقد قمت بتغطية هذا الجزء من التعليمات البرمجية.

public static DateTime GetDateInCurrentWeek(this DateTime date, DayOfWeek day)
{
    var temp = date;
    var limit = (int)date.DayOfWeek;
    var returnDate = DateTime.MinValue;

    if (date.DayOfWeek == day) return date;

    for (int i = limit; i < 6; i++)
    {
        temp = temp.AddDays(1);

        if (day == temp.DayOfWeek)
        {
            returnDate = temp;
            break;
        }
    }
    if (returnDate == DateTime.MinValue)
    {
        for (int i = limit; i > -1; i++)
        {
            date = date.AddDays(-1);

            if (day == date.DayOfWeek)
            {
                returnDate = date;
                break;
            }
        }
    }
    return returnDate;
}

نحن نحب الخطوط الواحدة:احصل على الفرق بين اليوم الأول من الأسبوع للثقافة الحالية واليوم الحالي ثم اطرح عدد الأيام من اليوم الحالي

var weekStartDate = DateTime.Now.AddDays(-((int)now.DayOfWeek - (int)DateTimeFormatInfo.CurrentInfo.FirstDayOfWeek));
   d = DateTime.Now;
            int dayofweek =(int) d.DayOfWeek;
            if (dayofweek != 0)
            {
                d = d.AddDays(1 - dayofweek);
            }
            else { d = d.AddDays(-6); }
public static System.DateTime getstartweek()
{
    System.DateTime dt = System.DateTime.Now;
    System.DayOfWeek dmon = System.DayOfWeek.Monday;
    int span = dt.DayOfWeek - dmon;
    dt = dt.AddDays(-span);
    return dt;
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top