Created
August 24, 2011 15:00
-
-
Save marvi/1168255 to your computer and use it in GitHub Desktop.
Uträkning av kyrkoåret
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
package lectio.cal; | |
import java.io.Serializable; | |
import java.util.Date; | |
import java.util.Map; | |
import java.util.Set; | |
import java.util.SortedMap; | |
import java.util.TreeMap; | |
import org.joda.time.DateTimeConstants; | |
import org.joda.time.LocalDate; | |
/** | |
* Represents a Liturgical year in the Church of Sweden tradition.<br> | |
* | |
* Note that calendar year and liturgical year doesn't align. The liturgical | |
* year starts first Sunday of Advent the previous calendar year. <br> | |
* The year used in this class is the year of the Easter Sunday of this liturgical year. | |
* I.e. the liturgical year 2013 starts 2012-12-02.<br> | |
* | |
* Inspiration from http://www.lysator.liu.se/alma/alma.cgi | |
* | |
* http://www.svenskakyrkan.se/tcrot/kyrkoordningen/filer/KO-kap-28.pdf | |
* | |
* @author marvi | |
*/ | |
public class LiturgicalYear implements Serializable { | |
/** | |
* The year this liturgical years Easter Sunday occurs. | |
*/ | |
private final int year; | |
private LocalDate easterDay; | |
private int readingCycle; | |
private SortedMap<LocalDate, Day> daysOfYear = new TreeMap<LocalDate, Day>(); | |
private final String[] swedishCounting = new String[] {"Första", "Andra", "Tredje", "Fjärde", "Femte", | |
"Sjätte", "Sjunde", "Åttonde", "Nionde", "Tionde", "Elfte", "Tolfte", "Trettonde", | |
"Fjortonde", "Femtonde", "Sextonde", "Sjuttonde", "Artonde", "Nittonde", "Tjugonde", | |
"Tjugoförsta", "Tjugoandra", "Tjugotredje", "Tjugofjärde", "Tjugofemte", "Tjugosjätte", | |
"Tjugosjunde"}; | |
/** | |
* | |
* @param year The year to use. | |
*/ | |
public LiturgicalYear(int year) { | |
this.year = year; | |
this.readingCycle = this.getReadingCycle(); | |
easterDay = CalculateEaster.forYear(year); | |
populateDaysOfYear(); | |
} | |
/** | |
* Default constructor. Uses current year. | |
*/ | |
public LiturgicalYear() { | |
this.year = new LocalDate(new Date()).getYear(); | |
easterDay = CalculateEaster.forYear(year); | |
populateDaysOfYear(); | |
} | |
/** | |
* @return the year | |
*/ | |
public int getYear() { | |
return year; | |
} | |
/** | |
* | |
* @return the reading cycle for this liturgical year (1-3) | |
*/ | |
public final int getReadingCycle() { | |
return getReadingCycle(year); | |
} | |
public final int getEasterSeries() { | |
return getEasterSeries(year); | |
} | |
public static int getReadingCycle(int year) { | |
if (year < 1986) { | |
return 0; | |
} else if (year < 2003) { | |
return (year - 1986) % 3 + 1; | |
} | |
return (year - 2003) % 3 + 1; | |
} | |
public static int getEasterSeries(int year) { | |
if (year < 2004) { | |
return 0; | |
} | |
return (year - 2002) % 4 + 1; | |
} | |
/** | |
* Maps the holidays to actual dates for this year. | |
*/ | |
private void populateDaysOfYear() { | |
// Fixed days | |
daysOfYear.put(new LocalDate(year - 1, 12, 24), new Day("Julnatten", new LocalDate(year - 1, 12, 24), readingCycle)); | |
daysOfYear.put(new LocalDate(year - 1, 12, 25), new Day("Juldagen", new LocalDate(year - 1, 12, 25), readingCycle)); | |
daysOfYear.put(new LocalDate(year - 1, 12, 26), new Day("Annandag jul", new LocalDate(year - 1, 12, 26), readingCycle)); | |
daysOfYear.put(new LocalDate(year - 1, 12, 31), new Day("Nyårsafton", new LocalDate(year - 1, 12, 31), readingCycle)); | |
daysOfYear.put(new LocalDate(year, 1, 1), new Day("Nyårsdagen", new LocalDate(year, 1, 1), readingCycle)); | |
daysOfYear.put(new LocalDate(year, 1, 5), new Day("Trettondagsafton", new LocalDate(year, 1, 5), readingCycle)); | |
daysOfYear.put(new LocalDate(year, 1, 6), new Day("Trettondedag jul", new LocalDate(year, 1, 6), readingCycle)); | |
// Söndagen efter jul infaller inte varje år. | |
LocalDate sej = nextWeekdayOfType(DateTimeConstants.SUNDAY, new LocalDate((year - 1), 12, 26)); | |
if (sej.isBefore(new LocalDate(year, 1, 1))) { | |
daysOfYear.put(sej, new Day("Söndagen efter jul", sej, readingCycle)); | |
} | |
// "Söndagen efter nyår" infaller inte varje år. | |
if (sundayAfterNewYear() != null) { | |
daysOfYear.put(sundayAfterNewYear(), new Day("Söndagen efter nyår", sundayAfterNewYear(), readingCycle)); | |
} | |
// Kyndelsmässodagen (flyttas tillbaka en vecka om den infaller på fastlagssöndagen | |
LocalDate kynd = nextWeekdayOfType(DateTimeConstants.SUNDAY, new LocalDate(year, 2, 1)); | |
if (kynd.equals(easterDay.minusDays(49))) { | |
kynd = kynd.minusDays(7); | |
} | |
daysOfYear.put(kynd, new Day("Kyndelsmässodagen", kynd, readingCycle)); | |
// Söndagar efter trettondedagen | |
int add = 0; | |
int i = 0; | |
while (i < 8) { | |
LocalDate d = firstAfterEpifania().plusDays(add); | |
if (!d.isEqual(kynd) && d.isBefore(easterDay.minusDays(63))) { | |
String prefix = swedishCounting[i]; | |
daysOfYear.put(d, new Day(prefix + " söndagen efter trettondedagen", d, readingCycle)); | |
} else if (d.isEqual(easterDay.minusDays(63)) | |
|| d.isAfter(easterDay.minusDays(63))) { | |
i = 8; | |
} | |
add = add + 7; | |
i++; | |
} | |
// Jungfru Marie bebådelsedag | |
LocalDate jmb = nextWeekdayOfType(DateTimeConstants.SUNDAY, new LocalDate(year, 3, 21)); | |
if (jmb.isAfter(easterDay.minusDays(8))) { | |
jmb = easterDay.minusDays(14); | |
} | |
daysOfYear.put(jmb, new Day("Jungfru Marie bebådelsedag", jmb, readingCycle)); | |
//System.out.println(daysOfYear.get(jmb) + " " + easterDay.minusDays(42)); | |
if (!kynd.isEqual(easterDay.minusDays(63))) { | |
daysOfYear.put(easterDay.minusDays(63), new Day("Septuagesima", easterDay.minusDays(63), readingCycle)); | |
} | |
if (!kynd.isEqual(easterDay.minusDays(56))) { | |
daysOfYear.put(easterDay.minusDays(56), new Day("Sexagesima", easterDay.minusDays(56), readingCycle)); | |
} | |
daysOfYear.put(easterDay.minusDays(49), new Day("Fastlagssöndagen", easterDay.minusDays(49), readingCycle)); | |
daysOfYear.put(easterDay.minusDays(46), new Day("Askonsdagen", easterDay.minusDays(46), readingCycle)); | |
if (!jmb.isEqual(easterDay.minusDays(42))) { | |
daysOfYear.put(easterDay.minusDays(42), new Day("Första söndagen i fastan", easterDay.minusDays(42), readingCycle)); | |
} | |
if (!jmb.isEqual(easterDay.minusDays(35))) { | |
daysOfYear.put(easterDay.minusDays(35), new Day("Andra söndagen i fastan", easterDay.minusDays(35), readingCycle)); | |
} | |
if (!jmb.isEqual(easterDay.minusDays(28))) { | |
daysOfYear.put(easterDay.minusDays(28), new Day("Tredje söndagen i fastan", easterDay.minusDays(28), readingCycle)); | |
} | |
if (!jmb.isEqual(easterDay.minusDays(21))) { | |
daysOfYear.put(easterDay.minusDays(21), new Day("Midfastosöndagen", easterDay.minusDays(21), readingCycle)); | |
} | |
if (!jmb.isEqual(easterDay.minusDays(14))) { | |
daysOfYear.put(easterDay.minusDays(14), new Day("Femte söndagen i fastan", easterDay.minusDays(14), readingCycle)); | |
} | |
// Utgår från påsken | |
daysOfYear.put(easterDay, new Day("Påskdagen", easterDay, readingCycle)); | |
daysOfYear.put(easterDay.minusDays(1), new Day("Påsknatten", easterDay.minusDays(1), readingCycle)); | |
daysOfYear.put(easterDay.minusDays(2), new Day("Långfredagen", easterDay.minusDays(2), readingCycle)); | |
daysOfYear.put(easterDay.minusDays(3), new Day("Skärtorsdagen", easterDay.minusDays(3), readingCycle)); | |
daysOfYear.put(easterDay.minusDays(4), new Day("Onsdag i Stilla veckan", easterDay.minusDays(4), readingCycle)); | |
daysOfYear.put(easterDay.minusDays(5), new Day("Tisdag i Stilla veckan", easterDay.minusDays(5), readingCycle)); | |
daysOfYear.put(easterDay.minusDays(6), new Day("Måndag i Stilla veckan", easterDay.minusDays(6), readingCycle)); | |
daysOfYear.put(easterDay.minusDays(7), new Day("Palmsöndagen", easterDay.minusDays(7), readingCycle)); | |
daysOfYear.put(easterDay.plusDays(1), new Day("Annandag påsk", easterDay.plusDays(1), readingCycle)); | |
daysOfYear.put(easterDay.plusDays(7), new Day("Andra söndagen i påsktiden", easterDay.plusDays(7), readingCycle)); | |
daysOfYear.put(easterDay.plusDays(14), new Day("Tredje söndagen i påsktiden", easterDay.plusDays(14), readingCycle)); | |
daysOfYear.put(easterDay.plusDays(21), new Day("Fjärde söndagen i påsktiden", easterDay.plusDays(21), readingCycle)); | |
daysOfYear.put(easterDay.plusDays(28), new Day("Femte söndagen i påsktiden", easterDay.plusDays(28), readingCycle)); | |
daysOfYear.put(easterDay.plusDays(35), new Day("Bönsöndagen", easterDay.plusDays(35), readingCycle)); | |
daysOfYear.put(easterDay.plusDays(39), new Day("Kristi himmelsfärds dag", easterDay.plusDays(39), readingCycle)); | |
daysOfYear.put(easterDay.plusDays(42), new Day("Söndagen före pingst", easterDay.plusDays(42), readingCycle)); | |
daysOfYear.put(easterDay.plusDays(49), new Day("Pingstdagen", easterDay.plusDays(49), readingCycle)); | |
daysOfYear.put(easterDay.plusDays(50), new Day("Annandag pingst", easterDay.plusDays(50), readingCycle)); | |
daysOfYear.put(easterDay.plusDays(56), new Day("Heliga trefaldighets dag", easterDay.plusDays(56), readingCycle)); | |
// Midsommardagen | |
LocalDate msd = nextWeekdayOfType(DateTimeConstants.SATURDAY, new LocalDate(year, 6, 19)); | |
daysOfYear.put(msd, new Day("Midsommardagen", msd, readingCycle)); | |
// Alla helons dag (behövs för att lägga ut trefaldighetstiden) | |
LocalDate ahd = nextWeekdayOfType(DateTimeConstants.SATURDAY, new LocalDate(year, 10, 30)); | |
daysOfYear.put(ahd, new Day("Alla helgons dag", ahd, readingCycle)); | |
daysOfYear.put(ahd.plusDays(1), new Day("Söndagen efter alla helgons dag", ahd.plusDays(1), readingCycle)); | |
// Advent och kyrkoårets slut | |
LocalDate firstAdv = nextWeekdayOfType(DateTimeConstants.SUNDAY, new LocalDate((year - 1), 11, 26)); | |
daysOfYear.put(firstAdv, new Day("Första söndagen i advent", firstAdv, readingCycle)); | |
daysOfYear.put(firstAdv.plusDays(7), new Day("Andra söndagen i advent", firstAdv.plusDays(7), readingCycle)); | |
daysOfYear.put(firstAdv.plusDays(14), new Day("Tredje söndagen i advent", firstAdv.plusDays(14), readingCycle)); | |
daysOfYear.put(firstAdv.plusDays(21), new Day("Fjärde söndagen i advent", firstAdv.plusDays(21), readingCycle)); | |
// Kalenderårsadvent (för att räkna ut Domsöndag | |
LocalDate calFirstAdv = nextWeekdayOfType(DateTimeConstants.SUNDAY, new LocalDate((year), 11, 26)); | |
daysOfYear.put(calFirstAdv.minusDays(7), new Day("Domsöndagen", calFirstAdv.minusDays(7), readingCycle)); | |
daysOfYear.put(calFirstAdv.minusDays(14), new Day("Söndagen före domsöndagen", calFirstAdv.minusDays(7), readingCycle)); | |
// Trefaldighetssöndagarna | |
// Söndagar efter trettondedagen | |
LocalDate firstAfterTre = easterDay.plusDays(63); | |
add = 0; | |
i = 0; | |
while (i < 27) { | |
LocalDate setre = firstAfterTre.plusDays(add); | |
add = add + 7; | |
if (setre.isEqual(ahd.plusDays(1))) { | |
i++; | |
continue; | |
} | |
if (setre.isAfter(calFirstAdv.minusDays(15))) { | |
break; | |
} | |
String etreName = swedishCounting[i]; | |
switch (i) { | |
case 4: | |
daysOfYear.put(setre, new Day("Apostladagen", setre, readingCycle)); | |
break; | |
case 6: | |
daysOfYear.put(setre, new Day("Kristi förklarings dag", setre, readingCycle)); | |
break; | |
default: | |
daysOfYear.put(setre, new Day(etreName + " söndagen efter trefaldighet", setre, readingCycle)); | |
break; | |
} | |
i++; | |
} | |
// Johannes döparens dag | |
daysOfYear.put(msd.plusDays(1), new Day("Den helige Johannes Döparens dag", msd.plusDays(1), readingCycle)); | |
// Den helige Mikaels dag | |
LocalDate hmd = nextWeekdayOfType(DateTimeConstants.SUNDAY, new LocalDate(year, 9, 28)); | |
daysOfYear.put(hmd, new Day("Den helige Mikaels dag", hmd, readingCycle)); | |
// Tacksägelsedagen | |
LocalDate tsd = nextWeekdayOfType(DateTimeConstants.SUNDAY, new LocalDate(year, 9, 30)); | |
tsd = nextWeekdayOfType(DateTimeConstants.SUNDAY, tsd); | |
daysOfYear.put(tsd, new Day("Tacksägelsedagen", tsd, readingCycle)); | |
} | |
private LocalDate sundayAfterNewYear() { | |
LocalDate candidate = nextWeekdayOfType(DateTimeConstants.SUNDAY, new LocalDate(year, 1, 1)); | |
if (candidate.getDayOfMonth() < 6) { | |
return candidate; | |
} | |
return null; | |
} | |
private LocalDate firstAfterEpifania() { | |
LocalDate ep = new LocalDate(year, 1, 6); | |
return nextWeekdayOfType(DateTimeConstants.SUNDAY, ep); | |
} | |
/** | |
* | |
* @param wd The day of week | |
* @param date The date to start from | |
* @return The next date with this weekday | |
*/ | |
protected static LocalDate nextWeekdayOfType(int wd, LocalDate date) { | |
if (date.getDayOfWeek() < wd) { | |
date = date.withDayOfWeek(wd); | |
} else { | |
date = date.plusWeeks(1).withDayOfWeek(wd); | |
} | |
return date; | |
} | |
/** | |
* @return a map with a date as key and the Day as value. | |
*/ | |
public Map<LocalDate, Day> getDaysOfYear() { | |
return daysOfYear; | |
} | |
@Override | |
public String toString() { | |
StringBuilder sb = new StringBuilder(); | |
sb.append("LiturgicalYear{ year="); | |
sb.append(year); | |
sb.append(" "); | |
Set<LocalDate> days = daysOfYear.keySet(); | |
for (LocalDate ld : days) { | |
sb.append(daysOfYear.get(ld).toString()); | |
sb.append(" \n "); | |
} | |
sb.append(" }"); | |
return sb.toString(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment