【问题标题】:Get date of first and last day of week knowing week number知道周数,获取一周的第一天和最后一天的日期
【发布时间】:2013-11-22 23:28:24
【问题描述】:

我需要知道一周的编号来获取一周的第一天和最后一天的日期。

我得到一个开始日期和一个结束日期,分别代表给定年份中选定周的第一天和最后一天。那么我需要获取上一年同一周的开始日期和结束日期,对一些数据进行图形比较。

我设法根据给定的开始日期和结束日期获取周数。现在我需要获取上一年同一周的第一天和最后一天的日期。我怎样才能最快地做到这一点?

编辑:这就是我得到周数的方式:

 private int GetWeekNumber(DateTime date)
    {
        GregorianCalendar calendar = new GregorianCalendar(GregorianCalendarTypes.USEnglish);
        return calendar.GetWeekOfYear(date, CalendarWeekRule.FirstDay, DayOfWeek.Sunday);            
    }

【问题讨论】:

    标签: c# date


    【解决方案1】:

    您可以使用以下两种方法根据给定年份计算给定周数的周数和开始日期:

    // this method is borrowed from http://stackoverflow.com/a/11155102/284240
    public static int GetIso8601WeekOfYear(DateTime time)
    {
        DayOfWeek day = CultureInfo.InvariantCulture.Calendar.GetDayOfWeek(time);
        if (day >= DayOfWeek.Monday && day <= DayOfWeek.Wednesday)
        {
            time = time.AddDays(3);
        }
    
        return CultureInfo.InvariantCulture.Calendar.GetWeekOfYear(time, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
    } 
    
    public static DateTime FirstDateOfWeek(int year, int weekOfYear, System.Globalization.CultureInfo ci)
    {
        DateTime jan1 = new DateTime(year, 1, 1);
        int daysOffset = (int)ci.DateTimeFormat.FirstDayOfWeek - (int)jan1.DayOfWeek;
        DateTime firstWeekDay = jan1.AddDays(daysOffset);
        int firstWeek = ci.Calendar.GetWeekOfYear(jan1, ci.DateTimeFormat.CalendarWeekRule, ci.DateTimeFormat.FirstDayOfWeek);
        if ((firstWeek <= 1 || firstWeek >= 52) && daysOffset >= -3)
        {
            weekOfYear -= 1;
        }
        return firstWeekDay.AddDays(weekOfYear * 7);
    }
    

    那么你可以通过以下方式获取两个日期:

    // 46
    int thisWeekNumber = GetIso8601WeekOfYear(DateTime.Today); 
    // 11/11/2013  
    DateTime firstDayOfWeek= FirstDateOfWeek(2013, thisWeekNumber, CultureInfo.CurrentCulture); 
    // 11/12/2012  
    DateTime firstDayOfLastYearWeek = FirstDateOfWeek(2012, thisWeekNumber, CultureInfo.CurrentCulture);   
    

    加上 6 天得到一周的结束。

    【讨论】:

    • 我怎样才能使这项工作适用于美国日历,星期天是一周的第一天?这就像用 DayOfWeek.Sunday 替换所有对 DayOfWeek.Monday 的引用一样简单吗?
    • @OctavianEpure:该方法根据ISO 8601返回星期数。但是,如果您已经有了获取周数的方法,您只需要我的第二种方法,它支持 CultureInfo 作为参数。只需通过CultureInfo.CurentCulture 或CultureInfo.CreateSpecificCulture("en-US")。我刚刚展示了我的方法来检索周数,因为你还没有展示你的。
    • 我已经展示了在我编辑的答案中获取周数的方法。非常感谢你的帖子。我会在开始整体测试后立即试用。
    • 此方法在 2006 年的第一周失败。我已经针对 2012-01 至 2025-52 范围测试了以下更正。 if ((firstWeek &lt;= 1 || firstWeek &gt;= 52) &amp;&amp; daysOffset &gt;= -3)
    • 你好今天给出,如何获得一周的第一个日期
    【解决方案2】:

    这是我的解决方案:

    public static DateTime FirstDayOfWeek(DateTime date)
    {
        DayOfWeek fdow = CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek;
        int offset = fdow - date.DayOfWeek;
        DateTime fdowDate = date.AddDays(offset);
        return fdowDate;
    }
    
    public static DateTime LastDayOfWeek(DateTime date)
    {
        DateTime ldowDate = FirstDayOfWeek(date).AddDays(6);
        return ldowDate;
    }
    

    【讨论】:

    • 迄今为止最好的答案
    • FirstDayOfWeek 给出下周的第一天,如果“日期”是星期日。
    • @MxFragz:请提供一个例子。我无法重现您的问题。
    • 这是正确的偏移量:var offset = -1 * (7 + ((dateTime.DayOfWeek - firstDayOfWeek) % 7))
    • 这并没有直接回答发帖者的原始问题,即当你有周数而不是日期时,如何获得一周的第一天和最后一天。
    【解决方案3】:

    上面的方法计算的第一个日期是 2016 年第一周的错误。

    基于先前答案的固定代码

     public DateTime FirstDateOfWeek(
            int year,
            int weekOfYear)
        {
            var newYear = new DateTime(year, 1, 1);
            var weekNumber = newYear.GetIso8601WeekOfYear(); 
    
            DateTime firstWeekDate;
    
            if (weekNumber != 1)
            {
                var dayNumber = (int) newYear.DayOfWeek;
                firstWeekDate = newYear.AddDays(7 - dayNumber + 1);
            }
            else
            {
                var dayNumber = (int)newYear.DayOfWeek;
                firstWeekDate = newYear.AddDays(-dayNumber + 1);
            }
    
            if (weekOfYear == 1)
            {
                return firstWeekDate;
            }
    
            return firstWeekDate.AddDays(7 * (weekOfYear - 1));
        }
    

    加试

        [TestCase(2016, 1, 2016, 1, 4)]
        [TestCase(2016, 2, 2016, 1, 11)]
        [TestCase(2016, 52, 2016, 12, 26)]
        [TestCase(2014, 1, 2013, 12, 30)]
        public void FirstDateOfWeek_ShouldReturnCorrectDay(int year, int weekNumber, int correctYear, int correctMonth, int correctDay)
        {
            var helper = new DateHelper();
            var result = helper.FirstDateOfWeek(year, weekNumber);
    
            Assert.That(result.Year, Is.EqualTo(correctYear));
            Assert.That(result.Month, Is.EqualTo(correctMonth));
            Assert.That(result.Day, Is.EqualTo(correctDay));
        }
    

    【讨论】:

    • 请更具体。 “上面的方法”是非常相对的。
    【解决方案4】:
        private static DateTime FirstDateOfWeek(int year, int weekOfYear)
        {
            var firstDate = new DateTime(year, 1, 4);
            //first thursday of the week defines the first week (https://en.wikipedia.org/wiki/ISO_8601)
            //Wiki: the 4th of january is always in the first week
            while (firstDate.DayOfWeek != DayOfWeek.Monday)
                firstDate = firstDate.AddDays(-1);
    
            return firstDate.AddDays((weekOfYear - 1)*7);
        }
    

    更简单、更高效的解决方案!

    【讨论】:

      【解决方案5】:

      从原始 DateTime 中减去 1 年,然后再次调用 GetWeekNumber 方法。

      TimeSpan oneYear = dateTime.AddYears(1) - dateTime;
      var lastYearWeekNumber = GetWeekNumber(dateTime.Subtract(oneYear));
      

      【讨论】:

        【解决方案6】:

        您可以找到有关如何获取当前或最后的first和last日期的解决方案星期根据传递的参数日期,现在您还可以获得上一年同一周的第一天和最后一天的日期>.

        您还可以更改一些设置以更改您的第一个工作日以获得您需要的结果。

        假设您的工作日从星期一开始,星期日除外,那么您需要做的就是改变开关盒并继续获得您想要的结果。

        public DateTime GetFirstDateOfCurrentWeek(DateTime dtDate)
        {
         //In this function we assumed that week start from sunday and end on saturday
            int no = 0;
            switch (dtDate.DayOfWeek.ToString())
            {
                case "Sunday":
                    no = 0;
                    break;
                case "Monday":
                    no = 1;
                    break;
                case "Tuesday":
                    no = 2;
                    break;
                case "Wednesday":
                    no = 3;
                    break;
                case "Thursday":
                    no = 4;
                    break;
                case "Friday":
                    no = 5;
                    break;
                case "Saturday":
                    no = 6;
                    break;
                default:
                    no = 0;
                    break;
            }
            return dtDate.AddDays(-no);
         }
        
        public DateTime GetLastDateOfCurrentWeek(DateTime dtDate)
        {
            int no = 0;
            switch (dtDate.DayOfWeek.ToString())
            {
                case "Saturday":
                    no = 0;
                    break;
                case "Friday":
                    no = 1;
                    break;
                case "Thursday":
                    no = 2;
                    break;
                case "Wednesday":
                    no = 3;
                    break;
                case "Tuesday":
                    no = 4;
                    break;
                case "Monday":
                    no = 5;
                    break;
                case "Sunday":
                    no = 6;
                    break;
                default:
                    no = 0;
                    break;
            }
            return dtDate.AddDays(no);
        }
        
        public DateTime GetFirstDateOfLastWeek(DateTime dtDate)
        {
            return GetFirstDateOfCurrentWeek(dtDate).AddDays(-7);
        }
        
        public DateTime GetLastDateOfLastWeek(DateTime dtDate)
        {
            return GetLastDateOfCurrentWeek(dtDate).AddDays(-7);
        }
        
        public DateTime GetFirstDateOfCurrentWeekOfPrvYear(DateTime dtDate)
        {
            int dayOfYear = dtDate.DayOfYear;
            DateTime firstDateOfThisYear = (Convert.ToDateTime("01/01/" + dtDate.Year.ToString()));
            DateTime firstDateofPrvYear = (firstDateOfThisYear.AddYears(-1));
            DateTime dateOfPrvYear = (firstDateofPrvYear.AddDays(dayOfYear));
        
            return GetFirstDateOfCurrentWeek(dateOfPrvYear);
        }
        
        public DateTime GetLastDateOfCurrentWeekOfPrvYear(DateTime dtDate)
        {
            int dayOfYear = dtDate.DayOfYear;
            DateTime firstDateOfThisYear = Convert.ToDateTime("01/01/" + dtDate.Year.ToString());
            DateTime firstDateofPrvYear = (firstDateOfThisYear.AddYears(-1));
            DateTime dateOfPrvYear = (firstDateofPrvYear.AddDays(dayOfYear));
        
            return GetLastDateOfCurrentWeek(dateOfPrvYear);
        }
        

        DateTime dt = Convert.ToDateTime("12/12/2019");

        int dayOfYear = dt.DayOfYear;
        string weekOfYear = (dt.DayOfYear / 7).ToString();
        string firstDateOfThisYear = (Convert.ToDateTime("01/01/" + dt.Year.ToString())).ToShortDateString();
        string firstDateofPrvYear = (Convert.ToDateTime(firstDateOfThisYear).AddYears(-1)).ToShortDateString();
        string dateOfPrvYear = (Convert.ToDateTime(firstDateofPrvYear).AddDays(dayOfYear)).ToShortDateString();
        string firstDateofWeekPrvYear = GetFirstDateOfCurrentWeek(Convert.ToDateTime(dateOfPrvYear)).ToShortDateString();
        string lastDateofWeekPrvYear = GetLastDateOfCurrentWeek(Convert.ToDateTime(dateOfPrvYear)).ToShortDateString();
        string weekOfPrvYear = (Convert.ToDateTime(dateOfPrvYear).DayOfYear / 7).ToString();
        
        MessageBox.Show("Day of Year: " + dayOfYear.ToString());
        MessageBox.Show("Week of Year: " + weekOfYear);
        MessageBox.Show("First day of this year: " + firstDateOfThisYear);
        MessageBox.Show("First day of prv year: " + firstDateofPrvYear);
        MessageBox.Show("Date of Prv Year: " + dateOfPrvYear);
        MessageBox.Show("First Date of Week Prv Year: " + firstDateofWeekPrvYear);
        MessageBox.Show("Last Date of Week Prv Year: " + lastDateofWeekPrvYear);
        MessageBox.Show("Day of Prv Year: " + weekOfPrvYear.ToString());
        

        【讨论】:

          【解决方案7】:

          由于每周有 7 天,因此您将知道第 10 周与第 71 - 77 天相同。您知道每月的天数(不要忘记闰年)。构建确切的日期,然后,您可以获得有关这些日期的信息。

          【讨论】:

          • 你确定吗?如果 1 月 1 日是星期五会怎样?
          • 大概,OP 知道这一点,因为他说他可以得到周数。为了能够做到这一点,我认为他必须知道第一周是什么时候开始的。另一方面,您可以找出任何给定年份的 1 月 1 日的星期几。然后,您需要设置规则:这是您的第一周,还是您需要到下周一开始第一周?
          • 有人愿意解释否决票吗?如果 OP 知道他在第 43 周,那么显然,他需要知道 1 月 1 日星期五是一年中的第一周还是第二周,这取决于他希望建立和遵循的任何规则。剩下的只是数学。
          【解决方案8】:

          Tim Schmelter 的方法不适用于每周从星期一开始的瑞典 (sv-SE) 文化。 这已通过 en-US 和 sv-SE 进行了测试。

              public static DateTime GetFirstDateOfWeek(int year, int weekOfYear, CultureInfo cultureInfo)
              {
                  DateTime jan1 = new DateTime(year, 1, 1);
                  int daysOffset = (int)cultureInfo.DateTimeFormat.FirstDayOfWeek - (int)jan1.DayOfWeek;
                  DateTime firstWeekDay = jan1.AddDays(daysOffset);
                  int firstWeek = cultureInfo.Calendar.GetWeekOfYear(jan1, cultureInfo.DateTimeFormat.CalendarWeekRule, cultureInfo.DateTimeFormat.FirstDayOfWeek);
                  if (firstWeek == 1)
                  {
                      weekOfYear -= 1;
                  }
                  return firstWeekDay.AddDays(weekOfYear * 7);
              }
          

          【讨论】:

            猜你喜欢
            • 2021-07-21
            • 1970-01-01
            • 2016-07-18
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-08-26
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多