Datetime without the year

2

I need to represent holidays and in my holiday class I need to set the start date and end of the holiday. As the start and end date I need to enter only the month, day, hour and minute . But the datetime class of python requires that the year be reported. Is there any way to create a datetime object without the year? Whereas for holidays the year does not matter. I could create my own datetime class, but since I'm going to need to do date comparisons I would have to overload operators, but I do not want to have to reinvent the wheel.

class Feriado:
    def __init__(self, start, end):
        self.start = start
        self.end = end
    
asked by anonymous 25.05.2018 / 16:21

2 answers

2
  

I could create my own datetime class, but since I'm going to need to do date comparisons I would have to overload operators, but I do not want to have to reinvent the wheel

Unless you compare dates without a year with only other dates without a year, I do not see a simple way to get away from that. It does not have to be complicated, though:

from datetime import datetime

class Feriado(datetime):

    # Na criação de uma nova classe, adicionamos um ano qualquer aos argumentos, para que possamos
    # ser uma classe derivada de datetime.
    def __new__(cls, *args, **kwargs):
        kwargs['year'] = 1970
        return super(Feriado, cls).__new__(Feriado, *args, **kwargs)

    # Fazemos uma cópia do outro datetime ao qual comparamos, mas setamos o ano como o mesmo
    # ano de nosso feriado (assim efetivamente comparamos só dia/mês/hora)
    def __lt__(self, other):
        equivalente = other.replace(year=self.year)
        return super().__lt__(equivalente)

    def __le__(self, other):
        equivalente = other.replace(year=self.year)
        return super().__le__(equivalente)

    def __gt__(self, other):
        equivalente = other.replace(year=self.year)
        return super().__gt__(equivalente)

    def __ge__(self, other):
        equivalente = other.replace(year=self.year)
        return super().__ge__(equivalente)

    def __eq__(self, other):
        equivalente = other.replace(year=self.year)
        return super().__eq__(equivalente)

    def __ne__(self, other):
        equivalente = other.replace(year=self.year)
        return super().__ne__(equivalente)

natal = Feriado(day=25, month=12)
aniversario_florianopolis = Feriado(day=23, month=3)

if natal > datetime.now():
    print('O natal ainda não chegou :(')

if aniversario_florianopolis < datetime.now():
    print('O aniversário de Florianópolis já passou :(')
    
25.05.2018 / 18:10
4

You can use the timedelta() function of the default library datetime to work with a period of time instead of working with specific dates, see:

from datetime import date
from datetime import timedelta

data_inicial = date.today();
data_final = data_inicial + timedelta(days=60);

print( data_inicial )
print( data_final )

Output:

2018-05-25
2018-07-24

Mobile Holidays , such as Easter, Carnival, Good Friday, Ash Wednesday and Corpus Christi depend on the Year to be calculated.

You can use the %%%%%%%%%%%%%% " the Easter holiday, then calculate the others, see how the class Algoritmo de Butcher would look like:

from datetime import date
from datetime import timedelta

class Feriado:

    def __init__( self, ano = date.today().year ):
        a = ano % 19
        b = ano // 100
        c = ano % 100
        d = (19 * a + b - b // 4 - ((b - (b + 8) // 25 + 1) // 3) + 15) % 30
        e = (32 + 2 * (b % 4) + 2 * (c // 4) - d - (c % 4)) % 7
        f = d + e - 7 * ((a + 11 * d + 22 * e) // 451) + 114
        mes = f // 31
        dia = f % 31 + 1
        self.data_pascoa = date( ano, mes, dia )
        self.ano = ano

    def ano_novo( self ):
        return date( self.ano, 1, 1 )

    def sexta_feira_santa( self ):
        return self.data_pascoa - timedelta(days=2)

    def cinzas( self ):
        return self.data_pascoa - timedelta(days=46)

    def carnaval( self ):
        return self.data_pascoa - timedelta(days=47)

    def pascoa( self ):
        return self.data_pascoa

    def tirandentes( self ):
        return date( self.ano, 4, 21 )

    def trabalho( self ):
        return date( self.ano, 5, 1 )

    def corpus_christi( self ):
        return self.data_pascoa + timedelta(days=60)

    def independencia( self ):
        return date( self.ano, 9, 7 )

    def nossa_senhora( self ):
        return date( self.ano, 10, 12 )

    def finados( self ):
        return date( self.ano, 11, 2 )

    def proclamacao_republica( self ):
        return date( self.ano, 11, 15 )

    def natal( self ):
        return date( self.ano, 12, 25 )

    def todos( self ):
        return [
            self.ano_novo(),
            self.carnaval(),
            self.cinzas(),
            self.sexta_feira_santa(),
            self.pascoa(),
            self.tirandentes(),
            self.trabalho(),
            self.corpus_christi(),
            self.independencia() ,
            self.nossa_senhora(),
            self.finados(),
            self.proclamacao_republica(),
            self.natal() ]

Checking if today is a holiday:

f = Feriado()

if( date.today() in f.todos() ):
    print( "Hoje eh um Feriado!" )
else:
    print( "Hoje eh um dia util!" )

Calculated Carnival date for% year of%:

f = Feriado(2018)
print( f.carnaval() )

Listing all year holidays Feriado :

f = Feriado(2000)
print( f.todos() )
    
25.05.2018 / 17:50