¿Cómo puedo determinar si una determinada fecha es el Enésimo día de la semana de mes?

Aquí es lo que estoy tratando de hacer:
Dada una fecha, un día de la semana, y un entero n, determinar si la fecha es el nº día del mes.

Por ejemplo:

  • entrada de 1/1/2009,Monday,2
    sería falso, porque 1/1/2009 no es el segundo lunes

  • de entrada de
    11/13/2008,Thursday,2
    devolverá true porque es el segundo jueves

¿Cómo puedo mejorar esta aplicación?

private bool NthDayOfMonth(DateTime date, DayOfWeek dow, int n)
{
    int d = date.Day;
    return date.DayOfWeek == dow && (d/ 7 == n || (d/ 7 == (n - 1) && d % 7 > 0));
}
InformationsquelleAutor Kevin | 2008-11-13

8 Kommentare

  1. 12

    Podría cambiar el cheque de la semana, así que la función sería la siguiente:

    private bool NthDayOfMonth(DateTime date, DayOfWeek dow, int n){
      int d = date.Day;
      return date.DayOfWeek == dow && (d-1)/7 == (n-1);
    }

    Aparte de eso, se ve bastante buena y eficiente.

  2. 8

    La respuesta es de este sitio web. Copia/pega aquí en caso de que el sitio se ha perdido.

    public static DateTime FindTheNthSpecificWeekday(int year, int month,int nth, System.DayOfWeek day_of_the_week)
    {
        //validate month value
        if(month < 1 || month > 12)
        {
            throw new ArgumentOutOfRangeException("Invalid month value.");
        }
    
        //validate the nth value
        if(nth < 0 || nth > 5)
        {
            throw new ArgumentOutOfRangeException("Invalid nth value.");
        }
    
        //start from the first day of the month
        DateTime dt = new DateTime(year, month, 1);
    
        //loop until we find our first match day of the week
        while(dt.DayOfWeek != day_of_the_week)
        {
            dt = dt.AddDays(1);
        }
    
        if(dt.Month != month)
        {
            //we skip to the next month, we throw an exception
            throw new ArgumentOutOfRangeException(string.Format("The given month has less than {0} {1}s", nth, day_of_the_week));
        }
    
        //Complete the gap to the nth week
        dt = dt.AddDays((nth - 1) * 7);
    
        return dt;
    }
    • esto también hace lo contrario de lo que quiero
    • Si era exactamente lo que Kevin sea necesario, esta muy parecido a lo que yo necesitaba. Gracias por publicar esto.
    • el cheque para la válida mes se debe hacer después de los días se agregan. si(dt.Mes != mes) es siempre verdadera después de la primera semana del mes se encuentra
  3. 1

    Parece que el lenguaje de los suministros de fecha/día de los métodos para una fecha dada. Si alguien estaba interesado puede leer acerca de Zeller de la congruencia.

    No creo que eso es lo que quería hacer, pero se puede encontrar el día de la semana de el día primero de un mes a partir de eso. Ahora que pensaba en ello, usted podría encontrar el día de la semana para el día como N y conseguir que el modulo 7.

    Oh, espera, es que la Enésima ocurrencia de un día de la semana (como la del domingo) o como la Enésima día de la semana del mes! Bueno me vea los ejemplos.

    Quizás podría hacer una diferencia si usted podría construir una fecha como el día 1 de un mes..

    Dado que es Enésima ocurrencia de un día de la semana, y que no se puede jugar con cualquier tipo de datos datetime, y que tienen acceso a un get día de la semana y obtener el día de mes de las funciones. Sería el domingo ser un cero?

    1) en Primer lugar, el día de la semana tendría que coincidir con el día de la semana dada.

    2) N tendría que ser mínimo de 1 y máximo de 4.

    3) El día del mes en que se encontrarían entre n*7*dayOfWeek + 1 y n*7*dayOfWeek + 6 para el mismo n.

    – Déjame pensarlo. Si el domingo fue la primera.. 0*7*0+1 = 1 y el sábado 6 sería 0*7*0+6.

    Creo que el 1 y el 3 de arriba son suficientes, ya que un get día de mes de la función no debe violar 2.

    (* first try, this code sucks *)
    
    function isNthGivenDayInMonth(date : dateTime;
                                  dow : dayOfWeek;
                                  N : integer) : boolean;
        var B, A : integer (* on or before and after day of month *)
        var Day : integer (* day of month *)
        begin
        B := (N-1)*7 + 1; A := (N-1)*7 + 6;
        D := getDayOfMonth(date);
        if (dow <> getDayOfWeek(date) 
            then return(false)
            else return( (B <= Day) and (A >= Day) );
        end; (* function *)

    Esperanza no hay un error en el lol!

    [editar: sábado habría sido el 7, y el límite superior por encima de (N-1)*7 + 7.]

    La solución parece que podría coincidir 2 semanas? Parece que siempre iba a devolver cero para los domingos? Debería haber hecho pseudocódigo en C#.. corto circuito && es como a mi si..
    hey no debería domingo el primer partido para N = 1 en los meses que empiezan en domingo?

     d/ 7 == n

    Que resultaría en (either 0 or 1)/7 == 1, que no puede ser cierto! Su || capturas de la (n-1) también, Robert tiene que. Ir con Robert Wagner respuesta! Es sólo 2 líneas, corto es bueno! Tener (Day-1) mod 7

    [editar: (Day-1) div 7]
    elimina mi innecesarios variables y 2 líneas de la instalación.

    Para el registro de este debe ser revisado por límite de los casos y así sucesivamente como lo que si el 31 de agosto fue un día domingo o el sábado.

    [editar: Debe de haber comprobado el fin de semana también. Lo siento!]

  4. 0

    En esta respuesta, el código siguiente debe ser de vuelta:

    //Complete the gap to the nth week
    dt = dt.AddDays((nth - 1) * 7);
    
    if(dt.Month != month)
    {
    //we skip to the next month, we throw an exception
    throw new ArgumentOutOfRangeException(”The given month has less than  nth.ToString()  
    day_of_the_week.ToString() s”);
    }
  5. 0

    La mayoría de las respuestas anteriores son parcialmente correctos o innecesariamente complejo.
    Puedes hacer esto más simple de la función, que también comprueba si la fecha dada es el penúltimo día N de cada mes.

        public static bool IsNthDayofMonth(this DateTime date, DayOfWeek weekday, int N)
        {
            if (N > 0)
            {
                var first = new DateTime(date.Year, date.Month, 1);
                return (date.Day - first.Day)/ 7 == N - 1 && date.DayOfWeek == weekday;
            }
            else
            {
    
                var last = new DateTime(date.Year, date.Month, 1).AddMonths(1).AddDays(-1);
                return (last.Day - date.Day) / 7 == (Math.Abs(N) - 1) && date.DayOfWeek == weekday;
            }
  6. 0

    En caso de que desea una lista de fechas para un lapso de tiempo (no solo uno) para el Enésimo DayOfWeek de un Mes, usted puede utilizar esta:

    internal static List<DateTime> GetDatesForNthDOWOfMonth(int weekNum, DayOfWeek DOW, DateTime beginDate, DateTime endDate)
    {
        List<DateTime> datesForNthDOWOfMonth = new List<DateTime>();
        int earliestDayOfMonth = 1;
        int latestDayOfMonth = 7;
        DateTime currentDate = beginDate;
    
        switch (weekNum)
        {
            case 1:
                earliestDayOfMonth = 1;
                latestDayOfMonth = 7;
                break;
            case 2:
                earliestDayOfMonth = 8;
                latestDayOfMonth = 14;
                break;
            case 3:
                earliestDayOfMonth = 15;
                latestDayOfMonth = 21;
                break;
            case 4:
                earliestDayOfMonth = 22;
                latestDayOfMonth = 28;
                break;
        }
    
        while (currentDate < endDate)
        {
            DateTime dateToInc = currentDate;
            DateTime endOfMonth = new DateTime(dateToInc.Year, dateToInc.Month, DateTime.DaysInMonth(dateToInc.Year, dateToInc.Month));
            bool dateFound = false;
            while (!dateFound)
            {
                dateFound = dateToInc.DayOfWeek.Equals(DOW);
                if (dateFound)
                {
                    if ((dateToInc.Day >= earliestDayOfMonth) && 
                        (dateToInc.Day <= latestDayOfMonth))
                    {
                        datesForNthDOWOfMonth.Add(dateToInc);
                    }
                }
                if (dateToInc.Date.Equals(endOfMonth.Date)) continue;
                dateToInc = dateToInc.AddDays(1);
            }
            currentDate = new DateTime(currentDate.Year, currentDate.Month, 1);
            currentDate = currentDate.AddMonths(1);
        }
        return datesForNthDOWOfMonth;
    }

    …y la llamada de esta manera:

    //This is to get the 1st Monday in each month from today through one year from today
    DateTime beg = DateTime.Now;
    DateTime end = DateTime.Now.AddYears(1);
    List<DateTime> dates = GetDatesForNthDOWOfMonth(1, DayOfWeek.Monday, beg, end);
    //To see the list of dateTimes, for verification
    foreach (DateTime d in dates)
    {
        MessageBox.Show(string.Format("Found {0}", d.ToString()));
    }

    Usted podría conseguir el 2º viernes de cada mes, así:

    List<DateTime> dates = GetDatesForNthDOWOfMonth(2, DayOfWeek.Friday, beg, end);

    …etc.

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Recent Articles

Python «set» con duplicados/elementos repetidos

Hay una forma estándar de representar un "conjunto" que puede contener elementos duplicados. Como yo lo entiendo, un conjunto tiene exactamente un cero o...

Python: generador de expresión vs rendimiento

En Python, ¿hay alguna diferencia entre la creación de un generador de objetos a través de un generador de expresión versus el uso de...

Cómo exportar/importar la Masilla lista de sesiones?

Hay una manera de hacer esto? O tengo que tomar manualmente cada archivo de Registro? InformationsquelleAutor s.webbandit | 2012-10-23

no distingue mayúsculas de minúsculas coincidentes en xpath?

Por ejemplo, para el xml a continuación <CATALOG> <CD title="Empire Burlesque"/> <CD title="empire burlesque"/> <CD...