Domanda

Sto creando una pianificazione e devono essere in grado di effettuare le seguenti operazioni in C#:

  1. Trovare il 1 ° martedì di giugno 2012
  2. Per trovare l'ultimo venerdì di Marzo 2008
  3. Trovare ogni sabato nel mese di gennaio 2013
  4. Trova il 3 ° venerdì di luglio 2009
  5. Trovare ogni sabato nei prossimi 3 mesi
  6. Trovare ogni giorno nel mese di Marzo 2018

I risultati dovrebbero tornare come DateTime o List<DateTime>.

È stato utile?

Soluzione

Qui ci sono metodi per trovare il primo / ultimo giorno specificato della settimana in un determinato mese:

public DateTime GetFirstDayOfWeekInMonth(int year, int month, DayOfWeek dayOfWeek)
{
    DateTime dt = new DateTime(year, month, 1);
    int first = (int)dt.DayOfWeek;
    int wanted = (int)dayOfWeek;
    if (wanted < first)
        wanted += 7;
    return dt.AddDays(wanted - first);
}

public DateTime GetLastDayOfWeekInMonth(int year, int month, DayOfWeek dayOfWeek)
{
    int daysInMonth = CultureInfo.CurrentCulture.Calendar.GetDaysInMonth(year, month);
    DateTime dt = new DateTime(year, month, daysInMonth);
    int last = (int)dt.DayOfWeek;
    int wanted = (int)dayOfWeek;
    if (wanted > last)
        last += 7;
    return dt.AddDays(wanted - last);
}

Da quelli, si può facilmente trovare le risposte alle altre domande ... basta aggiungere 7 giorni di tempo per trovare la prossima occorrenza del giorno che stai cercando


EDIT: pensare di più a questo proposito, sarebbe abbastanza comodo avere che in forma di metodi di estensione, come ad esempio:

Console.WriteLine("Next monday : {0}", DateTime.Today.Next(DayOfWeek.Monday));
Console.WriteLine("Last saturday : {0}", DateTime.Today.Previous(DayOfWeek.Saturday));

Ecco l'attuazione:

public static class DateExtensions
{
    public static DateTime Next(this DateTime from, DayOfWeek dayOfWeek)
    {
        int start = (int)from.DayOfWeek;
        int wanted = (int)dayOfWeek;
        if (wanted < start)
            wanted += 7;
        return from.AddDays(wanted - start);
    }

    public static DateTime Previous(this DateTime from, DayOfWeek dayOfWeek)
    {
        int end = (int)from.DayOfWeek;
        int wanted = (int)dayOfWeek;
        if (wanted > end)
            end += 7;
        return from.AddDays(wanted - end);
    }
}

E 'probabilmente più flessibile rispetto ai primi metodi ho suggerito ... Con questo, si può facilmente fare cose del genere:

// Print all Sundays between 2009/01/01 and 2009/03/31
DateTime from = new DateTime(2009, 1, 1);
DateTime to = new DateTime(2009, 3, 31);
DateTime sunday = from.Next(DayOfWeek.Sunday);
while(sunday <= to)
{
   Console.WriteLine(sunday);
   sunday = sunday.AddDays(7);
}

Altri suggerimenti

Ispirato da questa domanda mi sembrava una cosa divertente da fare qualcosa che permette di trattare le date come sequenze e le query con LINQ. Ho fatto un semplice progetto che può essere scaricato qui da GitHub. Non so se è stato necessario aggiungerlo al controllo del codice sorgente, come dubito che sarò lavorando su di esso, ma ha dovuto caricarlo da qualche parte e caricarlo su RapidShare sembrava un po 'rischiosa:)

I tuoi prime domande risolte con la mia "Linq to DateTime":

  /*
   *    1. Find the 1st Tuesday of June 2012
        2. Find the last Friday of March 2008
        3. Find every Saturday in January 2013
        4. Find the 3rd Friday in July 2009
        5. Find every Saturday over the next 3 months
        6. Find every day in March 2018
  */

  var firstTuesday = (from d in DateSequence.FromYear(2012).June()
                    where d.DayOfWeek == DayOfWeek.Tuesday
                    select d).First();

  var lastFriday = (from d in DateSequence.FromYear(2008).March()
                    where d.DayOfWeek == DayOfWeek.Friday
                    select d).Last();

  var saturdays = (from d in DateSequence.FromYear(2013).January()
                   where d.DayOfWeek == DayOfWeek.Saturday
                   select d);

  var thirdFriday = (from d in DateSequence.FromYear(2009).July()
                     where d.DayOfWeek == DayOfWeek.Friday
                     select d).Skip(2).First();

  var nextSaturdays = (from d in DateSequence.FromDates(DateTime.Today, DateTime.Today.AddMonths(3))
                       where d.DayOfWeek == DayOfWeek.Saturday
                       select d);

  var allDays = (from d in DateSequence.FromYear(2018).March()
                 select d);

Non mostrato in questo esempio è che si può scegliere la granularità delle query. Il che significa che se si esegue questa:

  var days = (from d in DateSequence.FromYears(2001, 2090).AsYears()
              where d.Year % 2 == 0
              select d.Year).ToList();

Si scorrere le date con un incremento di un anno. L'impostazione predefinita è AsDays () se non si specifica nulla.

Il progetto è abbastanza barebone, nessun test di commento o di unità, ma spero che questo possa ancora aiutare. Se no, allora era la scrittura comunque divertente:)

Ecco un esempio su come fare il primo giorno di un mese.

public enum Month
{
    January = 1,
    Febuary = 2,
    March = 3,
    April = 4,
    May = 5,
    June = 6,
    July = 7,
    August = 8,
    September = 9,
    October = 10,
    November = 11,
    December = 12
}

public static Nullable<DateTime> FindTheFirstDayOfAMonth(DayOfWeek dayOfWeek, Month month, int year)
{
    // Do checking of parameters here, i.e. year being in future not past

    // Create a DateTime object the first day of that month
    DateTime currentDate = new DateTime(year, (int)month, 1);

    while (currentDate.Month == (int)month)
    {
        if (currentDate.DayOfWeek == dayOfWeek)
        {
            return currentDate;
        }

        currentDate = currentDate.AddDays(1);
    }

    return null;
}

Si chiamano come

Nullable<DateTime> date = Program.FindTheFirstDayOfAMonth(DayOfWeek.Monday, Month.September, 2009);

Quindi, si ottiene l'idea. Si dovrà fare varie funzioni di fare quello che si vuole raggiungere.

YO YO YO - Voi ragazzi stanno facendo questo troppo difficile:

int = DaysInMonth DateTime.DaysInMonth (DateTime.Now.Year, DateTime.Now.Month);

Quando ho scritto un programmatore ho praticamente server SQL copiati sysschedules tabella

http://msdn.microsoft.com/en-us/library /ms178644.aspx

Utilizzando le cose come tipo di frequenza, intervallo di frequenze, ecc ... in realtà ha reso facile per calcolare i valori nel codice, ma sto indovinando c'è uno sproc di farlo per voi. Io sto cercando adesso.

Sì, l' .NET Framework sarà di supporto che senza problemi ;)

Ma sul serio - si dovrebbe essere in grado di scrivere codice che non abbastanza facilmente.Se non, chiedere una domanda quando riesci, e ti aiuto.Ma non hai bisogno di alcun assembly esterni - basta andare con un standard di C# class =)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top