Find time within a range of hours

Asked

Viewed 306 times

-1

I am trying to develop a logic where there will be any schedule I need to find within a range of hours (Start time and End time)

But I can’t make the correct comparison and/or I’m not treating it right.

In the tests I used the comparison time: 03:37:33 to find in the ranges

Follows code:

    class Program
    {
        static void Main(string[] args)
        {
        DateTime dtImportacao = new DateTime(2019,07,01,03,33,37);

        TimeSpan[] datasInicias = new TimeSpan[]
        {

        new TimeSpan(06,00,00),
        new TimeSpan(00,00,00),
        new TimeSpan(23,00,00),
        new TimeSpan(06,00,00),
        new TimeSpan(19,00,01),
        new TimeSpan(06,00,00),
        new TimeSpan(23,00,00),
        new TimeSpan(08,00,00),
        new TimeSpan(19,00,00),
        new TimeSpan(19,00,00),
        new TimeSpan(06,00,00),
        new TimeSpan(22,00,00),
        new TimeSpan(23,00,00),
        new TimeSpan(06,00,01)
    };
        TimeSpan[] datasFinais = new TimeSpan[]
        {
        new TimeSpan(23,00,00),
        new TimeSpan(23,59,59),
        new TimeSpan(06,00,00),
        new TimeSpan(19,00,00),
        new TimeSpan(05,59,59),
        new TimeSpan(23,00,00),
        new TimeSpan(06,00,00),
        new TimeSpan(20,00,00),
        new TimeSpan(06,00,00),
        new TimeSpan(05,45,59),
        new TimeSpan(22,00,00),
        new TimeSpan(06,00,00),
        new TimeSpan(06,00,00),
        new TimeSpan(22,59,59)
        };



        for (int i = 0; i < datasInicias.Length; i++)
        {


            if (TimeSpan.Compare(dtImportacao.TimeOfDay, datasInicias[i]) == -1 || TimeSpan.Compare(dtImportacao.TimeOfDay, datasFinais[i]) == 1)
            {
                Console.WriteLine("Parametro de Comparação: {0}   | {1}  Até {2} Fora", dtImportacao.TimeOfDay, datasInicias[i], datasFinais[i]);
            }
            else
            {
                Console.WriteLine("Parametro de Comparação: {0}   | {1}  Até {2} Dentro", dtImportacao.TimeOfDay, datasInicias[i], datasFinais[i]);
            }


        }

        Console.ReadKey();
    }
}

Console return:

//Parametro de Comparação: 03:33:37 | 06:00:00  Até 23:00:00 Fora
//Parametro de Comparação: 03:33:37 | 00:00:00  Até 23:59:59 Dentro
//Parametro de Comparação: 03:33:37 | 23:00:00  Até 06:00:00 Fora
//Parametro de Comparação: 03:33:37 | 06:00:00  Até 19:00:00 Fora
//Parametro de Comparação: 03:33:37 | 19:00:01  Até 05:59:59 Fora
//Parametro de Comparação: 03:33:37 | 06:00:00  Até 23:00:00 Fora
//Parametro de Comparação: 03:33:37 | 23:00:00  Até 06:00:00 Fora
//Parametro de Comparação: 03:33:37 | 08:00:00  Até 20:00:00 Fora
//Parametro de Comparação: 03:33:37 | 19:00:00  Até 06:00:00 Fora
//Parametro de Comparação: 03:33:37 | 19:00:00  Até 05:45:59 Fora
//Parametro de Comparação: 03:33:37 | 06:00:00  Até 22:00:00 Fora
//Parametro de Comparação: 03:33:37 | 22:00:00  Até 06:00:00 Fora
//Parametro de Comparação: 03:33:37 | 23:00:00  Até 06:00:00 Fora
//Parametro de Comparação: 03:33:37 | 06:00:01  Até 22:59:59 Fora

How should I get out:

inserir a descrição da imagem aqui

  • 1

    'Cause you’re comparing TimeSpan with DateTime?

  • Timespan are time intervals, not dates as you indicate in your variables.

2 answers

3


The expression is checking if the time is within the specific period, but you are not counting if the period is another day, so if it is past 24 hours, the result will not be within the field of the previous day.

The expression you need is:

bool dentroDoPeriodo = !(min <= max ? (val >= min && val <= max) : (val >= min || val <= max));

Explanation of the expression:

var min = datasInicias[i];
var max = datasFinais[i];
var val = dtImportacao;

bool dentroDoPeriodo =
! (                       // Inverte o resultado lógico da expressão
    min <= max            // Se o horário inicial for < que o final       [1]
    ?                     // Início da condição em-linha
    (                     // (Condição Verdadeira de [1]) Se [1] == True
        val >= min        // Se o horário de importação for maior ou igual ao inicial
        &&                // E também se
        val <= max        // o mesmo for menor ou igual ao horário final
    ) : (                 // (Condição Falsa de [1]) Se [1] == False
        val >= min        // Se o horário de importação for maior ou igual ao inicial
        ||                // Ou também se
        val <= max        // o mesmo for menor ou igual ao horário final
    )                     // Retorna o sub-circuíto de [1].
);                        // Retorna o circuíto [1]

In addition, the comparison of DateTime and TimeSpan makes no sense in this situation. You’re comparing hours with hours, nay dates with times. Change in your code:

of DateTime dtImportacao = new DateTime(2019,07,01,03,33,37);

for: TimeSpan dtImportacao = new TimeSpan(03, 37, 33);


See working on .NET Fiddle.

  • I’m adapting your code to javascript, very good.

1

You are not considering that the hours may cross the day.

Basically, what you need is to change the validation to something like:

Inicio > Fim
 ? data <= Inicio && data <= Fim
 : data >= Inicio && data <= Fim

What can be simplified to:

(Inicio > Fim && data <= Inicio || data >= Inicio) && data <= Fim;  

See the full code. Try to improve the structure of the code to be more readable.

using System;
using static System.Console;

struct Intervalo
{
    public Intervalo(TimeSpan inicio, TimeSpan fim) 
    {
        Inicio = inicio;
        Fim = fim;
    }

    public TimeSpan Inicio { get; set; }
    public TimeSpan Fim { get; set; }
    public bool AtravessaDia => Inicio > Fim;

    public bool EstáNoIntervalo(TimeSpan data)
    {
        return AtravessaDia 
            ? data <= Inicio && data <= Fim
            : data >= Inicio && data <= Fim;
    }
}

class Program
{
    static void Main(string[] args)
    {
        DateTime dtImportacao = new DateTime(2019, 07, 01, 03, 33, 37);

        var intervalos = new []
        {
            new Intervalo(new TimeSpan(06, 00, 00), new TimeSpan(23, 59, 00)),
            new Intervalo(new TimeSpan(23, 00, 00), new TimeSpan(02, 00, 00)),
            new Intervalo(new TimeSpan(00, 00, 00), new TimeSpan(23, 59, 59)),          
            new Intervalo(new TimeSpan(23, 00, 00), new TimeSpan(06, 00, 00)),
            new Intervalo(new TimeSpan(06, 00, 00), new TimeSpan(19, 00, 00)),          
            new Intervalo(new TimeSpan(19, 00, 01), new TimeSpan(05, 59, 59)),          
            new Intervalo(new TimeSpan(06, 00, 00), new TimeSpan(23, 00, 00)),
            new Intervalo(new TimeSpan(23, 00, 00), new TimeSpan(06, 00, 00)),
            new Intervalo(new TimeSpan(08, 00, 00), new TimeSpan(20, 00, 00)),
            new Intervalo(new TimeSpan(19, 00, 00), new TimeSpan(06, 00, 00)),
            new Intervalo(new TimeSpan(19, 00, 00), new TimeSpan(06, 00, 00)),
            new Intervalo(new TimeSpan(02, 00, 00), new TimeSpan(04, 00, 00)),          
            new Intervalo(new TimeSpan(02, 59, 00), new TimeSpan(03, 00, 00)),      
            new Intervalo(new TimeSpan(03, 34, 00), new TimeSpan(03, 40, 00)),      
            new Intervalo(new TimeSpan(03, 32, 00), new TimeSpan(03, 40, 00)),   
            new Intervalo(new TimeSpan(03, 40, 00), new TimeSpan(03, 34, 00)),   
            new Intervalo(new TimeSpan(03, 40, 00), new TimeSpan(03, 32, 00)),               
        };

        WriteLine($"Parâmetro de Comparação: {dtImportacao.TimeOfDay}\n");
        foreach(var intervalo in intervalos)
            WriteLine($"{intervalo.Inicio} - {intervalo.Fim} = {(intervalo.EstáNoIntervalo(dtImportacao.TimeOfDay) ? "Dentro" : "Fora")} ");      
    }
}   

See working on Repl.it

  • I didn’t know you were @jfbueno until I saw this link.

  • @Cypherpotato What do you mean? I didn’t know I was the jfbueno of where?

  • I’ve seen that nickname somewhere, probably here, repl.it/@jfbueno

Browser other questions tagged

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