Timespan: count occurrences at a specific time

Asked

Viewed 69 times

1

How could I assemble this method that counts the occurrences of a specific set of times in a period?

public static int OcorrenciasDeHorarios(
    DateTime Inicio, DateTime Final, params string[] Horarios)
{
    // ??
}

Example: if it is passed OcorrenciasDeHorarios(DateTime.Parse("2017-01-10 01:35:00 PM"), DateTime.Parse("2017-01-12 07:35:00 PM"), "12:50:00 AM", "05:50:00 PM"); must return 5, because it occurs in:

2017-01-10 05:50:00 PM

2017-01-11 12:50:00 AM
2017-01-11 05:50:00 PM

2017-01-12 12:50:00 AM
2017-01-12 05:50:00 PM

1 answer

3


I made a Fiddle, but, before using, it is important to explain some aspects.

First, it is important to note that pass strings of times is not exactly the best practice, especially because you will need to assemble dates within the function. Initially I made an optimistic implementation, then:

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;

public static IEnumerable<DateTime> OcorrenciasDeHorarios(
    DateTime Inicio, DateTime Final, params string[] Horarios)
{
    var cultura = new CultureInfo("en-US");
    for (var dia = Inicio; dia <= Final; dia = dia.AddDays(1)) 
    {
        foreach (var diaHorario in Horarios.Select(h => DateTime.Parse(dia.Date.ToString("MM/dd/yyyy") + " " + h)))
        {
            if (diaHorario >= Inicio && diaHorario <= Final)
                yield return diaHorario;
        }
    }
}

Second, notice I didn’t use TimeSpan. TimeSpan is not a data structure with support for time Zones. I used DateTime same, just joining the schedule list with the dates you want to evaluate.

Notice that I changed int for IEnumerable<DateTime> because it interests me to know what were the obtained results. Done this, I can do the following:

var lista = OcorrenciasDeHorarios(DateTime.Parse("2017-01-10 01:35:00 PM"), DateTime.Parse("2017-01-12 07:35:00 PM"), "12:50:00 AM", "05:50:00 PM");
Console.WriteLine(lista.Count());
foreach (var item in lista) 
    Console.WriteLine(item);

Returns 5 occurrences (lista.Count()) and print the list of hours with the possible times below.

Now, let’s assume that this input depends on a user. We’ll have to make a pessimistic algorithm, which would look like this:

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;

public static IEnumerable<DateTime> OcorrenciasDeHorarios(
    DateTime Inicio, DateTime Final, params string[] Horarios)
{
    var cultura = new CultureInfo("en-US");
    for (var dia = Inicio; dia <= Final; dia = dia.AddDays(1)) 
    {
        foreach (var diaHorario in Horarios)
        {
            DateTime teste = DateTime.MinValue;
            if (!DateTime.TryParse(dia.Date.ToString("MM/dd/yyyy") + " " + diaHorario, out teste))
            {
                Console.WriteLine("Horário " + diaHorario + " está em formato inadequado e não será considerado.");
                continue;
            }

            if (teste >= Inicio && teste <= Final)
                yield return teste;
        }
    }
}

It’s in this other Fiddle here.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.