Forked from alexyslozada/Go - Genera los días festivos de Colombia
Last active
January 26, 2020 19:30
-
-
Save ThomRoman/d03c2d01bd4ec7625111ce16f5e2c562 to your computer and use it in GitHub Desktop.
Genera los días festivos de colombia dado un año
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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