【问题标题】:Get Day For Previous Month获取上个月的日期
【发布时间】:2012-08-07 01:34:27
【问题描述】:

我有一个看起来很简单的日期问题,但我无法全神贯注地尝试有效地解决它...我基本上需要获取特定日期的前几个月日期。

例如:如果今天是本月的第三个星期四,我想获取上个月的第三个星期四的日期。重要的是它基于当天的数字......即:第一个星期一,第四个星期五,第二个星期三等。

完成这项工作的最佳方法是什么?

顺便说一句...如果前几个月没有相同的日期,那也没关系。我可以处理。另外,目前我正在手动计算数字或天数(“星期一”、“星期二”等)来解决这个问题。我只是希望有一种更优雅的方式来做到这一点。

【问题讨论】:

  • 那么当没有一个时会发生什么?本月可能有第四个星期五,但上个月没有第四个星期五。另外,如果您担心这一天,上个月只有 30 天(或 29/28)的 31 号会发生什么?
  • 到目前为止你尝试过什么?即使您逐一计算,您甚至不会注意到该算法会消耗任何 CPU 时间,因此无需担心效率性能。
  • @DJKraze,是的,我已经与谷歌核实过,但在这种情况下我找不到任何有用的东西。我可以通过计算天数来完成这项工作(即:计算星期一之前的星期一),但我觉得有更好的方法来做到这一点。
  • @Erik 我想你的意思是there might not be a FIFTH day of last month。每个月都会有第四天,因为每个月至少有 28 天 =)
  • @saluce 是的,我就是这个意思!

标签: c# datetime


【解决方案1】:

我会这样做:

static DateTime? GetLastMonthSameNthDayOfWeek(DateTime date)
{
    int nth = (date.Day-1) / 7; // returns 0 if 1st, 1 if 2nd...
    var prevMonthDay = date.AddMonths(-1);

    // find the first date of month having the same day of week
    var d = new DateTime(prevMonthDay.Year, prevMonthDay.Month, 1);
    while(d.Day <= 7)
    {
        if (d.DayOfWeek == date.DayOfWeek)
            break;
        d = d.AddDays(1);
    }
    // go to nth day of week
    d = d.AddDays(7 * nth);
    // if we have passed the current month, there's no nth day of week
    if (d.Month != prevMonthDay.Month)
        return null;
    return d;
}

使用示例:

// 3rd wednesday of August 2012
var a = new DateTime(2012, 8, 15);
var aPrev = GetLastMonthSameNthDayOfWeek(a);
// aPrev = July 18th 2012 (i.e. the 3rd wednesday of July 2012)

// 5th wednesday of August 2012
var b = new DateTime(2012, 8, 15);
var bPrev = GetLastMonthSameNthDayOfWeek(b);
// bPrev = null, because there's no 5th wednesday of July 2012

注意:

在一个月内获得星期几的序数位置真的很容易:

int nth = ((date.Day-1) / 7) + 1; // 1 -> 1st, 2 -> 2nd, 3 -> 3rd ...

【讨论】:

  • 正是我想要的...谢谢。比我做的要干净得多。我希望我能多次接受答案。
  • @AGoodDisplayName:有一个小错误(关于 7 的天数倍数),请检查编辑后的代码;)
【解决方案2】:

由于找不到内置方式,我为DateTime写了这个简单的扩展方法,看看:

public static class DateTimeExtension
{
    public static DateTime GetPositionalDate(this DateTime BaseDate, DayOfWeek WeekDay, int position)
    {
        if (position < 1)
        {
            throw new Exception("Invalid position");
        }
        else
        {
            DateTime ReturnDate = new DateTime(BaseDate.Year, BaseDate.Month, BaseDate.Day);
            int PositionControl = 1;
            bool FoundDate = false;

            while(ReturnDate.DayOfWeek != WeekDay)
            {
                ReturnDate = ReturnDate.AddDays(1);
            }

            while (!FoundDate && PositionControl <= position)
            {
                PositionControl++;

                if (PositionControl == position)
                {
                    FoundDate = true;
                }
                else
                {
                    ReturnDate = ReturnDate.AddDays(7);
                }
            }

            if (FoundDate)
            {
                return ReturnDate;
            }
            else
            {
                throw new Exception("Date not found");
            }
        }
    }
}

用法:

DateTime lastMonth = DateTime.Now.GetPositionalDate(DayOfWeek.Sunday, 2);

问候

【讨论】:

    【解决方案3】:

    默认情况下,.Net 没有一种方式可以理解日期的特定逻辑。因此,使用以下内容,您可以获得所需的内容:

    var now = DateTime.Now.Date;
    

    Use DateTime.AddMonth(-1) to get last month.

    Use DateTime.AddDays(now.Days * -1 + 1) to get the first of the month.

    Use DateTime.DayOfWeek to determine the day and subtract or add days as necessary

    【讨论】:

      【解决方案4】:

      好的,你可以做的是确定上个月第一天的星期几,取你想要的星期几和星期几之间的差,然后加上 7 * the weeks你想要(不到一周)...

      // Let's get the 3rd Friday of last month:
      
      // get starting date
      DateTime date = new DateTime();
      
      // get first day of last month
      DateTime firstOfLastMonth = date.AddMonths(-1).AddDays(-1 * (date.Day + 1));
      
      // subtract out the day of the week (get the previous Sunday, even if it is last month)
      DateTime justBeforeMonth = firstOfLastMonth.AddDays((int)firstOfLastMonth.DayOfWeek);
      
      // Add in the DayOfWeek number we are looking for
      DateTime firstFridayOfMonth = justBeforeMonth.AddDays(DayOfWeek.Friday);
      
      // if we are still in last month, add a week to get into this month
      if (firstFridayOfMonth.Month != date.AddMonth(-1).Month) { firstFridayOfMonth.AddDays(7); }
      
      // add in 2 weeks to get the third week of the month
      DateTime thirdFridayOfMonth = firstFridayOfMonth.AddDays(14);
      

      【讨论】:

        【解决方案5】:

        这是我想出的解决方案。如果这一天不存在(例如第 8 个星期六),GetDate() 将返回 null:

        {
            DateTime lastMonth = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1).AddMonths(-1);
            DateTime? date = GetDate(lastMonth.Month, lastMonth.Year, DayOfWeek.Thursday, 2);
        }
        
        private static DateTime? GetDate(int month, int year, DayOfWeek dayOfWeek, int which)
        {
            DateTime firstOfMonth = new DateTime(year, month, 1);
        
            DateTime date;
            for (date = firstOfMonth; date.DayOfWeek != dayOfWeek; date = date.AddDays(1))
                ;
        
            date = date.AddDays(7 * (which - 1));
        
            return date.Month == month && date.Year == year ? (DateTime?)date : null;
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-06-10
          • 2018-09-17
          • 2018-09-30
          • 1970-01-01
          • 1970-01-01
          • 2017-10-25
          相关资源
          最近更新 更多