Question

Je crée un planificateur et ont besoin d'être en mesure de faire ce qui suit en C #:

  1. Trouvez le 1er mardi de Juin 2012
  2. Trouvez le dernier vendredi de Mars 2008
  3. Trouvez tous les samedis en Janvier 2013
  4. Trouvez le 3ème vendredi en Juillet 2009
  5. Trouvez tous les samedis au cours des 3 prochains mois
  6. Trouvez tous les jours en Mars 2018

Les résultats devraient revenir comme DateTime ou List<DateTime>.

Était-ce utile?

La solution

Voici les méthodes pour trouver le premier / dernier jour spécifié de la semaine dans un mois donné:

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);
}

De ceux-ci, vous pouvez facilement trouver les réponses aux autres questions ... il suffit d'ajouter 7 jours pour trouver la prochaine occurence de la journée, vous êtes à la recherche


EDIT: penser plus à ce sujet, il serait très pratique d'avoir ce sous la forme de méthodes d'extension, tels que:

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

Voici la mise en œuvre:

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);
    }
}

Il est probablement plus souple que les premières méthodes que je ... Avec cela a suggéré, vous pouvez facilement faire des choses comme ça:

// 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);
}

Autres conseils

Inspiré par cette question, il semblait être une chose amusante à faire quelque chose qui vous permet de traiter les dates que les séquences et les interroger avec LINQ. J'ai fait un projet simple qui peut être téléchargé href="http://github.com/JulianR/LinqToDateTime" de GitHub. Je ne sais pas s'il était nécessaire d'ajouter au contrôle de source que je doute que je vais travailler là-dessus, mais a dû le télécharger quelque part et le télécharger sur rapidshare semblait un peu douteux:)

Vos premières questions résolues avec mon "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 montré dans cet exemple est que vous pouvez choisir la granularité de vos requêtes. Ce qui signifie que si vous faites ceci:

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

Vous itérer les dates avec une augmentation d'une année. La valeur par défaut est AsDays () si vous ne spécifiez rien.

Le projet est assez barebone, aucun test de commentaires ou de l'unité, mais j'espère que cela peut encore vous aider. Dans le cas contraire, il était écrit amusant de toute façon:)

Voici un exemple sur la façon de faire le premier jour d'un mois.

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;
}

Vous l'appelez comme

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

Vous avez l'idée. Vous devrez faire différentes fonctions obtenez ce que vous voulez atteindre.

YO YO YO - les gars que vous faites cela trop dur:

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

Quand j'ai écrit un ordonnanceur à peu près la table sysschedules copiés serveurs SQL

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

Utilisation des choses comme la fréquence de type, intervalle de fréquence, etc ... vraiment rendu facile de calculer les valeurs dans le code, mais je devine il y a un sproc de le faire pour vous. Je recherche maintenant.

Oui, le .NET Framework soutiendra que, sans aucun problème;)

Mais sérieusement - vous devriez être en mesure d'écrire du code qui fait cela assez facilement. Sinon, poser une question quand vous êtes coincé, et nous aider. Mais vous aurez pas besoin d'assemblées externes - juste aller avec une classe standard C # =)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top