هو .صافي يعطيني خطأ في الأسبوع عدد من ديسمبر.29 عام 2008 ؟

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

سؤال

وفقا الرسمية (الميلادي) التقويم, الأسبوع رقم 29/12/2008 هو 1 ، لأنه بعد اليوم الأخير من الأسبوع 52 (أي28/12) هناك ثلاثة أو أقل أيام في السنة.غريب, لكن لا بأس, القواعد هي القواعد.

وذلك وفقا لهذا التقويم ، لدينا هذه الحدود قيم 2008/2009

  • 28/12 هو الأسبوع 52
  • 29/12 هو الأسبوع 1
  • 1/1 هو الأسبوع 1
  • 8/1 هو الأسبوع 2

C# يقدم GregorianCalendar الدرجة التي لديه وظيفة GetWeekOfYear(date, rule, firstDayOfWeek).

المعلمة rule وتعداد مع 3 القيم الممكنة: FirstDay, FirstFourWeekDay, FirstFullWeek.من ما فهمته أنا يجب أن تذهب FirstFourWeekDay القاعدة, لكنني حاولت كل منهم فقط في حالة.

المعلمة الأخيرة بإعلام التي الأسبوع اليوم ينبغي اعتبار اليوم الأول من الأسبوع ، حسب هذا التقويم هو يوم الاثنين حتى يوم الاثنين هو.

حيث أطلقت سريعة وقذرة وحدة التحكم التطبيق لاختبار هذا:

using System;
using System.Globalization;

namespace CalendarTest
{
    class Program
    {
        static void Main(string[] args)
        {
            var cal = new GregorianCalendar();
            var firstWeekDay = DayOfWeek.Monday;
            var twentyEighth = new DateTime(2008, 12, 28);
            var twentyNinth = new DateTime(2008, 12, 29);
            var firstJan = new DateTime(2009, 1, 1);
            var eightJan = new DateTime(2009, 1, 8);
            PrintWeekDays(cal, twentyEighth, firstWeekDay);
            PrintWeekDays(cal, twentyNinth, firstWeekDay);
            PrintWeekDays(cal, firstJan, firstWeekDay);
            PrintWeekDays(cal, eightJan, firstWeekDay);
            Console.ReadKey();
        }

        private static void PrintWeekDays(Calendar cal, DateTime dt, DayOfWeek firstWeekDay)
        {
            Console.WriteLine("Testing for " + dt.ToShortDateString());
            Console.WriteLine("--------------------------------------------");
            Console.Write(CalendarWeekRule.FirstDay.ToString() + "\t\t");
            Console.WriteLine(cal.GetWeekOfYear(dt, CalendarWeekRule.FirstDay, firstWeekDay));
            Console.Write(CalendarWeekRule.FirstFourDayWeek.ToString() + "\t");
            Console.WriteLine(cal.GetWeekOfYear(dt, CalendarWeekRule.FirstFourDayWeek, firstWeekDay));
            Console.Write(CalendarWeekRule.FirstFullWeek.ToString() + "\t\t");
            Console.WriteLine(cal.GetWeekOfYear(dt, CalendarWeekRule.FirstFullWeek, firstWeekDay));
            Console.WriteLine("--------------------------------------------");
        }
    }
}

...و هذا ما يحصل

Testing for 28.12.2008
--------------------------------------------
FirstDay                52
FirstFourDayWeek        52
FirstFullWeek           51
--------------------------------------------
Testing for 29.12.2008
--------------------------------------------
FirstDay                53
FirstFourDayWeek        53
FirstFullWeek           52
--------------------------------------------
Testing for 01.01.2009
--------------------------------------------
FirstDay                1
FirstFourDayWeek        1
FirstFullWeek           52
--------------------------------------------
Testing for 08.01.2009
--------------------------------------------
FirstDay                2
FirstFourDayWeek        2
FirstFullWeek           1
--------------------------------------------

لذلك كما نرى أيا من مجموعات أعلاه المباريات الرسمية التقويم (إذا كنت في عجلة من امرنا ، انظر فقط أن 29/12 لم يحصل الأسبوع #1).

ما أنا على خطأ هنا ؟ ربما هناك شيء الصارخة أن أنا في عداد المفقودين ؟ (إنه يوم الجمعة في وقت متأخر من ساعات العمل هنا في بلجيكا ، تتحمل معي ;))

تحرير:ربما ينبغي لي أن أشرح:ما أريده هو أن وظيفة يعمل في أي سنة ، والعودة نفس نتائج التقويم الغريغوري أنا مرتبط.حتى لا الحلول في عام 2008.

هل كانت مفيدة؟

المحلول

هذا المادة يبدو أعمق في هذه المسألة و الحلول الممكنة.محور المسألة هو أن .صافي التقويم التنفيذ لا يبدو أن تنفذ معيار ISO

نصائح أخرى

@كونراد هو الصحيح.على .صافي تنفيذ التاريخ والوقت و GregorianCalendar لا تنفيذ/متابعة كاملة ISO 8601 المواصفات.أن يقال أنهم المواصفات مفصلة للغاية وغير تافهة لتنفيذ بالكامل على الأقل في تحليل الجانب من الأمور.

المزيد من المعلومات متوفرة في المواقع التالية:

ببساطة:

الأسبوع التي حددها رقمه في سنة معينة يبدأ الاثنين.الأسبوع الأول من السنة هو الذي يتضمن الأول الخميس ، أو مكافئ واحد والتي تشمل 4 كانون الثاني / يناير.

هنا هو جزء من قانون تستخدم بشكل صحيح التعامل مع ISO 8601 التواريخ:

    #region FirstWeekOfYear
    /// <summary>
    /// Gets the first week of the year.
    /// </summary>
    /// <param name="year">The year to retrieve the first week of.</param>
    /// <returns>A <see cref="DateTime"/>representing the start of the first
    /// week of the year.</returns>
    /// <remarks>
    /// Week 01 of a year is per definition the first week that has the Thursday 
    /// in this year, which is equivalent to the week that contains the fourth
    /// day of January. In other words, the first week of a new year is the week
    /// that has the majority of its days in the new year. Week 01 might also 
    /// contain days from the previous year and the week before week 01 of a year
    /// is the last week (52 or 53) of the previous year even if it contains days 
    /// from the new year.
    /// A week starts with Monday (day 1) and ends with Sunday (day 7). 
    /// </remarks>
    private static DateTime FirstWeekOfYear(int year)
    {
        int dayNumber;

        // Get the date that represents the fourth day of January for the given year.
        DateTime date = new DateTime(year, 1, 4, 0, 0, 0, DateTimeKind.Utc);

        // A week starts with Monday (day 1) and ends with Sunday (day 7).
        // Since DayOfWeek.Sunday = 0, translate it to 7. All of the other values
        // are correct since DayOfWeek.Monday = 1.
        if (date.DayOfWeek == DayOfWeek.Sunday)
        {
            dayNumber = 7;
        }
        else
        {
            dayNumber = (int)date.DayOfWeek;
        }

        // Since the week starts with Monday, figure out what day that 
        // Monday falls on.
        return date.AddDays(1 - dayNumber);
    }

    #endregion

    #region GetIsoDate
    /// <summary>
    /// Gets the ISO date for the specified <see cref="DateTime"/>.
    /// </summary>
    /// <param name="date">The <see cref="DateTime"/> for which the ISO date
    /// should be calculated.</param>
    /// <returns>An <see cref="Int32"/> representing the ISO date.</returns>
    private static int GetIsoDate(DateTime date)
    {
        DateTime firstWeek;
        int year = date.Year;

        // If we are near the end of the year, then we need to calculate
        // what next year's first week should be.
        if (date >= new DateTime(year, 12, 29))
        {
            if (date == DateTime.MaxValue)
            {
                firstWeek = FirstWeekOfYear(year);
            }
            else
            {
                firstWeek = FirstWeekOfYear(year + 1);
            }

            // If the current date is less than next years first week, then
            // we are still in the last month of the current year; otherwise
            // change to next year.
            if (date < firstWeek)
            {
                firstWeek = FirstWeekOfYear(year);
            }
            else
            {
                year++;
            }
        }
        else
        {
            // We aren't near the end of the year, so make sure
            // we're not near the beginning.
            firstWeek = FirstWeekOfYear(year);

            // If the current date is less than the current years
            // first week, then we are in the last month of the
            // previous year.
            if (date < firstWeek)
            {
                if (date == DateTime.MinValue)
                {
                    firstWeek = FirstWeekOfYear(year);
                }
                else
                {
                    firstWeek = FirstWeekOfYear(--year);
                }
            }
        }

        // return the ISO date as a numeric value, so it makes it
        // easier to get the year and the week.
        return (year * 100) + ((date - firstWeek).Days / 7 + 1);
    }

    #endregion

    #region Week
    /// <summary>
    /// Gets the week component of the date represented by this instance.
    /// </summary>
    /// <value>The week, between 1 and 53.</value>
    public int Week
    {
        get
        {
            return this.isoDate % 100;
        }
    }
    #endregion

    #region Year
    /// <summary>
    /// Gets the year component of the date represented by this instance.
    /// </summary>
    /// <value>The year, between 1 and 9999.</value>
    public int Year
    {
        get
        {
            return this.isoDate / 100;
        }
    }
    #endregion

أرقام الأسبوع تختلف من بلد إلى آخر و يجب أن تعتمد على الإعدادات المحلية الخاصة بك/إعدادات إقليمية إذا أنا لست مخطئا تماما.

تحرير:ويكيبيديا يدعم بلدي اميز أن هذه الأرقام تختلف استنادا إلى البلاد: http://en.wikipedia.org/wiki/Week_number#Week_number

أتوقع محترمة إطار طاعة البلد المحدد في وقت التشغيل.

في تجربتي أثبتت السلوك هو السلوك النموذجي ، مشيرا إلى جزئية النهائي الأسبوع الأسبوع 53.قد يكون هذا لأن كل مواطن تعرض علي أن أرقام الأسبوع قد المحاسبة نهاية السنة التقويمية لأغراض إعداد التقارير و مصلحة الضرائب (ضريبة أو وكالة من اختيارك) تعتبر السنة التقويمية أن تنتهي في 31 كانون الأول / ديسمبر ، وليس الأسبوع الأخير من السنة.

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

كما عمل حول, هل يمكن أن نقول الأسبوع رقم WeekNumber وزارة الدفاع 52.وأعتقد أن هذا من شأنه أن يعمل على الحالات تصفون.

كحل, لماذا لا تستخدم FirstFourDayWeek ولكن إضافة:

  if ( weekNumber > 52 )
    weekNumber = 1;
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top