Pergunta

Estou criando um programador e necessidade de ser capaz de fazer o seguinte em C #:

  1. Encontre o terça-feira 1 de junho de 2012
  2. Encontre última sexta-feira Março de 2008
  3. Encontre todos os sábados em janeiro de 2013
  4. Encontre a 3ª sexta-feira em julho de 2009
  5. Encontre todos os sábados ao longo dos próximos 3 meses
  6. Encontre todos os dias março 2018

Os resultados devem voltar como DateTime ou List<DateTime>.

Foi útil?

Solução

Aqui estão os métodos para encontrar o primeiro último dia / especificado de semana em um determinado mês:

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

A partir desses, você pode facilmente encontrar as respostas para as outras perguntas ... basta adicionar 7 dias para encontrar a próxima ocorrência do dia que você está procurando


EDIT: pensar mais sobre isso, seria muito útil para ter que sob a forma de métodos de extensão, tais como:

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

Aqui está a implementação:

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

É provavelmente mais flexíveis do que os primeiros métodos que eu sugeri ... Com isso, você pode facilmente fazer as coisas assim:

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

Outras dicas

Inspirado por esta pergunta pareceu uma coisa divertida para fazer algo que lhe permite datas tratar como seqüências e consulta-los com LINQ. Eu fiz um projeto simples que pode ser baixado aqui do GitHub. Não sei se era necessário adicioná-lo ao controle de origem como eu duvido que vou estar trabalhando nisso, mas teve que carregá-lo em algum lugar e enviá-lo para RapidShare parecia um pouco duvidoso:)

As suas primeiras perguntas resolvido com a minha "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);

Não é mostrado neste exemplo é que você pode escolher a granularidade de suas consultas. O que significa que se você fizer isso:

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

Você vai percorrer os encontros com um incremento de um ano. O padrão é AsDays () se você não especificar nada.

O projeto é bastante barebone, há testes comentário ou unidade, mas espero que isso ainda pode ajudá-lo. Se não, então foi divertido escrever de qualquer maneira:)

Aqui está um exemplo de como fazer o primeiro dia de um mês.

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

Você chamá-lo como

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

Assim que você começa a idéia. Você terá que fazer várias funções se o que você deseja alcançar.

YO YO YO - Vocês estão fazendo isso muito difícil:

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

Quando eu escrevi um programador eu praticamente servidores SQL copiados sysschedules tabela

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

Usando coisas como Tipo Frequência, Frequência Intervalo, etc ... realmente tornou fácil para calcular os valores no código, mas eu estou supondo que há um sproc para fazer isso por você. Estou à procura de que agora.

Sim, o .NET Framework apoiará que sem problemas;)

Mas a sério - você deve ser capaz de escrever código que faz isso com bastante facilidade. Se não, faça uma pergunta quando você ficar preso, e nós vamos ajudar. Mas você não precisa de nenhum montagens externas - basta ir com uma classe padrão C # =)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top