Skip to content

Instantly share code, notes, and snippets.

@alexyslozada
Last active December 16, 2019 23:00
Show Gist options
  • Save alexyslozada/2912596d535bfa5f8faed84c1435e19c to your computer and use it in GitHub Desktop.
Save alexyslozada/2912596d535bfa5f8faed84c1435e19c to your computer and use it in GitHub Desktop.
Genera los días festivos de colombia dado un año
// Genera los días festivos de colombia dado un año
// Basado en los artículos:
// https://www.festivos.com.co/calculo y https://elpais.com/elpais/2017/04/12/el_aleph/1492008750_544261.html
package main
import (
"fmt"
"time"
)
const (
// Formato de fecha
dateFormat = "2006-01-02"
)
const (
static typeHoliday = iota + 1
easter
nextMonday
)
type typeHoliday byte
type holiday struct {
name string
month int
day int
typeHoliday typeHoliday
}
func (h *holiday) time(year int) time.Time {
return shortDate(year, h.month, h.day)
}
func (h *holiday) celebration(year int) time.Time {
if h.typeHoliday != nextMonday || h.time(year).Weekday() == time.Monday {
return h.time(year)
}
r := time.Monday - h.time(year).Weekday()
if r < 0 {
r += 7
}
return addDays(h.time(year), int(r))
}
type dayFromEaster struct {
name string
addDays int8
}
func main() {
var year int = 2019
fmt.Println(easterDay(year))
days := append(holidays(), easterDaysToHoliday(year)...)
show(year, days)
}
func holidays() []holiday {
return []holiday{
{"Año nuevo", 1, 1, static},
{"Día del trabajo", 5, 1, static},
{"Día de la independencia", 7, 20, static},
{"Batalla de Boyacá", 8, 7, static},
{"Inmaculada concepción", 12, 8, static},
{"Navidad", 12, 25, static},
{"Reyes Magos", 1, 6, nextMonday},
{"Día de San José", 3, 19, nextMonday},
{"San Pedro y San Pablo", 6, 29, nextMonday},
{"Asunción de la virgen", 8, 15, nextMonday},
{"Día de la raza", 10, 12, nextMonday},
{"Todos los santos", 11, 1, nextMonday},
{"Independencia de Cartagena", 11, 11, nextMonday},
}
}
func easterDays() []dayFromEaster {
return []dayFromEaster{
{"Jueves santo", -3},
{"Viernes santo", -2},
{"Ascención de Jesús", 43},
{"Corpus Christi", 64},
{"Sagrado corazón de Jesús", 71},
}
}
func easterDay(year int) time.Time {
a := year % 19
b := year % 4
c := year % 7
k := year / 100
p := (13 + 8*k) / 25
q := k / 4
M := (15 - p + k - q) % 30
N := (4 + k - q) % 7
d := (19*a + M) % 30
e := (2*b + 4*c + 6*d + N) % 7
easterDay := time.Now()
if d+e < 10 {
easterDay = addDays(shortDate(year, 3, 22), d+e)
} else {
easterDay = addDays(shortDate(year, 4, d+e), -9)
}
if easterDay.Equal(shortDate(year, 4, 26)) {
easterDay = shortDate(year, 4, 19)
}
if d == 28 && e == 6 && a > 10 && easterDay.Equal(shortDate(year, 4, 25)) {
easterDay = shortDate(year, 4, 18)
}
return easterDay
}
func shortDate(year, month, day int) time.Time {
return time.Date(year, time.Month(month), day, 0, 0, 0, 0, time.UTC)
}
func addDays(date time.Time, days int) time.Time {
return date.Add(time.Hour * 24 * time.Duration(days))
}
func show(year int, hs []holiday) {
for _, v := range hs {
fmt.Print(v.name)
fmt.Print(" - ")
fmt.Print(v.time(year).Format(dateFormat))
fmt.Print(" - ")
fmt.Print(v.celebration(year).Format(dateFormat))
fmt.Println()
}
}
func easterDaysToHoliday(year int) []holiday {
r := []holiday{}
ed := easterDay(year)
for _, v := range easterDays() {
day := addDays(ed, int(v.addDays))
r = append(r, holiday{v.name, int(day.Month()), day.Day(), easter})
}
return r
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment