Pen Settings

HTML

CSS

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URL's added here will be added as <link>s in order, and before the CSS in the editor. If you link to another Pen, it will include the CSS from that Pen. If the preprocessor matches, it will attempt to combine them before processing.

+ add another resource

JavaScript

Babel includes JSX processing.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Packages

Add Packages

Search for and use JavaScript packages from npm here. By selecting a package, an import statement will be added to the top of the JavaScript editor for this package.

Behavior

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

Format on Save

If enabled, your code will be formatted when you actively save your Pen. Note: your code becomes un-folded during formatting.

Editor Settings

Code Indentation

Want to change your Syntax Highlighting theme, Fonts and more?

Visit your global Editor Settings.

HTML

              
                <!-- https://euromind.com/dansk-evighedskalender/ -->

<div class="panel" >
  <span class="inputyear">Indtast år: <input type="number"  id="yearinput" onfocus = 'this.value = ""' onkeyup="panelChanged()"><span>
  <span class="inputmoon"><input type="checkbox" checked id="moonCheck" onclick="panelChanged()"><span><label for="moonCheck">&nbsp; &nbsp;Månefase</label></span></span>
  <span class="inputevents"><input type="checkbox" checked id="eventCheck" onclick="panelChanged()"><span ><label for="eventCheck">&nbsp; &nbsp;Kirkeår</label></span></span>
  <span class="inputlatin" ><input type="checkbox" id="latinCheck" onclick="panelChanged()"><span ><label for="latinCheck">&nbsp; &nbsp;Latin</label></span></span>
</div>
<div class="container">
  <div id="firsthalf" class="sixmonthcontainer">
    <div id="firstquarter" class="threemonthcontainer"></div>
    <div id="secondquarter" class="threemonthcontainer"></div>
  </div>
  <div id="secondhalf" class="sixmonthcontainer">
    <div id="thirdquarter" class="threemonthcontainer"></div>
    <div id="fourthquarter" class="threemonthcontainer"></div>
  </div>
</div>

              
            
!

CSS

              
                body {
  font-family: Trebuchet MS, Franklin Gothic Medium, sans-serif;
  height: 100%;
  width: 99%;
  margin: 0;
}


.panel {
  min-width: 450px;
  background-color: #555;
  font-size: 14px;
  color: white;
  padding: 10px;
  padding-left: 10px;

}

.panel span {
  padding-left: 1px;
  margin-left: -5px;
}

.yearheader {
  height: 70px;
  background-color: cornflowerblue;
  color: white !important;
  font-size: 62px;
  padding: 10px;
  padding-left: 10px;
}



input[type=number] {
  -webkit-border-radius: 20px;
  -moz-border-radius: 20px;
  border-radius: 20px;
  border: 1px solid #2d9fd9;
  color: slategray;

  width: 250px;
  height: 30px;
  padding-left: 10px;
}

input[type=text]:focus {
  outline: none;
  border: 1px solid #a0d18c;
  color: slategray;
}

input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}


input[type=checkbox] {
  margin-left: 20px;
  transform: scale(2);
  -ms-transform: scale(2);
  -webkit-transform: scale(2);

}


#yearinput {
  margin-right: 20px;
  font-size: 18px;
  width: 60px;
  border: 0;
}

.header {
  background-color: cornflowerblue;
  font-size: 18px;
  padding: 5px;
  margin: 0;
  color: cornsilk;
  text-align: center;
}



.container {
  width: 100%;
  display: flex;
  flex-wrap: wrap;
  font-family: Arial, Helvetica, sans-serif;
  font-size: 13px;
  margin: 0;
  border-width: 1px;
  border-style: solid;
  border-color: lightblue;
  border-right: 0;
}

.sixmonthcontainer {
  display: flex;
  padding: 0px !important;
  flex: 50%;
}

.threemonthcontainer {
  display: flex;
  padding: 0px !important;
  flex: 25%;
}

.month {
  flex: 8.5%;
}


.day {
  min-width: 130px;
  width: 100%;
  border-width: 1px;
  border-style: ridge;
  margin: 0px;
  height: 18px;
  padding-top: 2px;
}


.grayed {
  background-color: lightgray;

}

.white {
  background-color: #fff;
}

.abbr {
  color: darkslategray;
  padding-top: 2px;
  font-weight: 500;
  padding-right: 5px;
  height: 100%;
  float: left;
  margin-top: -2px;
  padding-left: 3.6px; width: 9.9px;
}

.daynumber {
  color: darkslategray;
  font-weight: 500;
  padding-top: 2px;
  padding-left: 2px;
  padding-right: 6px;
  float: left;
  height: 100%;
  margin-bottom: 3px;
  margin-top: -2px;
  width: 9.9px;
}

.weeknumber {
  float: right;
  font-size: 16px;
  font-weight: 600;
  margin-right: 5px;
  color: darkgray;
}

.eventtitle {
  font-size: calc(2.5px + 0.5vw);
  margin-left: 2px;
  color: darkslategray;
}


.moon {
  float: right;
  margin-right: 4px;
  opacity: 0.8;
  margin-top: -2px;
}

@media (max-width: 1920px) {
  .day {
    min-width: 147px;
  }
  .eventtitle {
    font-size: 12px;
  }
}

@media (max-width: 970px) {
  .day {
    min-width: 153px;
  }

  .eventtitle {
    font-size: 12px;
  }
}

@media (min-width: 1851px) {

  #yearheader6,
  #yearheader9,
  #yearheader3 {
    color: cornflowerblue !important;
  }
}

@media (max-width: 1850px) {

  #yearheader9,
  #yearheader3 {
    color: cornflowerblue !important;
  }

  #yearheader6 {
    color: white !important;
  }
}

@media (max-width: 760px) {
  .sixmonthcontainer {
    display: flex;
    flex-flow: column wrap;
    padding: 0px !important;
    flex: 100%;
  }

  #yearheader3,
  #yearheader6,
  #yearheader9 {
    color: white !important;
  }

  .eventtitle {
    font-size: calc(12px + 0.3vw);
    margin-left: 5px;
  }
}


              
            
!

JS

              
                // Reference to MeeusJs  - https://github.com/Fabiz/MeeusJs 
const abbr = "SMTOTFL";
const months = ["Januar", "Februar", "Marts", "April", "Maj", "Juni", "Juli", "August", "September", "Oktober", "November", "December"];
const Events = [
    { "danish": "Nytårsdag", "latin": "Circumcisio domini", "holliday": true, "primary": true },
    { "danish": "Helligtrekongersdag", "latin": "Epiphania", "holliday": false, "primary": false },
    { "danish": "1. s e Helligtrek.", "latin": "1 p. Epiphany", "holliday": true, "primary": false },
    { "danish": "2. s e Helligtrek.", "latin": "2 p. Epiphany", "holliday": true, "primary": false },
    { "danish": "3. s e Helligtrek.", "latin": "3 p. Epiphany", "holliday": true, "primary": false },
    { "danish": "4. s e Helligtrek.", "latin": "4 p. Epiphany", "holliday": true, "primary": false },
    { "danish": "5. s e Helligtrek.", "latin": "5 p. Epiphany", "holliday": true, "primary": false },
    { "danish": "6. s e Helligtrek.", "latin": "6 p. Epiphany", "holliday": true, "primary": false },
    { "danish": "Alle Helgensdag", "latin": "Omnium Sanctorum", "holliday": false, "primary": true },
    { "danish": "Mortensdag", "latin": "Morten Bisp", "holliday": false, "primary": true },
    { "danish": "1. søndag i Advent", "latin": "Adventus", "holliday": true, "primary": true },
    { "danish": "2. søndag i Advent", "latin": "2 Adventus", "holliday": true, "primary": true },
    { "danish": "3. søndag i Advent", "latin": "3 Adventus", "holliday": true, "primary": true },
    { "danish": "4. søndag i Advent", "latin": "4 Adventus", "holliday": true, "primary": true },
    { "danish": "Juledag", "latin": "Natio Christi", "holliday": true, "primary": true },
    { "danish": "2. Juledag", "latin": "Sanct Stefan", "holliday": true, "primary": true },
    { "danish": "9 søn før påske", "latin": "Septuagesima", "holliday": true, "primary": false, "easterDiffDays": -63 },
    { "danish": "8 søndag før påske", "latin": "Sexagesima", "holliday": true, "primary": false, "easterDiffDays": -56 },
    { "danish": "Fastelavnsøndag", "latin": "Quinquagesima", "holliday": true, "primary": true, "easterDiffDays": -49 },
    { "danish": "Hvide tirsdag", "latin": "Carnem Levare", "holliday": false, "primary": false, "easterDiffDays": -47 },
    { "danish": "Askeonsdag", "latin": "Caput Jejunii", "holliday": false, "primary": false, "easterDiffDays": -46 },
    { "danish": "6 søn f Påske ", "latin": "Quadragesima, Invocavit", "holliday": true, "primary": false, "easterDiffDays": -42 },
    { "danish": "5 søn f Påske ", "latin": "Reminiscere", "holliday": true, "primary": false, "easterDiffDays": -35 },
    { "danish": "4 søn f Påske ", "latin": "Oculi", "holliday": true, "primary": false, "easterDiffDays": -28 },
    { "danish": "Midfaste", "latin": "Laetare", "holliday": true, "primary": false, "easterDiffDays": -21 },
    { "danish": "2 søn f Påske ", "latin": "Judica", "holliday": true, "primary": false, "easterDiffDays": -14 },
    { "danish": "Palmesøndag", "latin": "Palmarum", "holliday": true, "primary": true, "easterDiffDays": -7 },
    { "danish": "Skærtorsdag", "latin": "Viridium", "holliday": true, "primary": true, "easterDiffDays": -3 },
    { "danish": "Langfredag", "latin": "Dies Adoratis, Passiones", "holliday": true, "primary": true, "easterDiffDays": -2 },
    { "danish": "Påskedag", "latin": "Pascha", "holliday": true, "primary": true, "easterDiffDays": 0 },
    { "danish": "2. påskedag ", "latin": "2. Pascha", "holliday": true, "primary": true, "easterDiffDays": 1 },
    { "danish": "1. søn e Påske", "latin": "Quasimodogeniti", "holliday": true, "primary": false, "easterDiffDays": 7 },
    { "danish": "2. søn e Påske", "latin": "Misericordia ", "holliday": true, "primary": false, "easterDiffDays": 14 },
    { "danish": "3. søn e Påske", "latin": "Jubilate", "holliday": true, "primary": false, "easterDiffDays": 21 },
    { "danish": "Store Bededag", "latin": "Metonoia", "holliday": true, "primary": true, "easterDiffDays": 26 },
    { "danish": "4. søn e Påske", "latin": "Cantate", "holliday": true, "primary": false, "easterDiffDays": 28 },
    { "danish": "5. søn e Påske", "latin": "Vocem jucunditatis", "holliday": true, "primary": false, "easterDiffDays": 35 },
    { "danish": "Kr Himmelfart", "latin": "Ascensionis Domini", "holliday": true, "primary": true, "easterDiffDays": 39 },
    { "danish": "6. søn e Påske", "latin": "Exaudi", "holliday": true, "primary": false, "easterDiffDays": 42 },
    { "danish": "Pinsedag", "latin": "Pentecoste", "holliday": true, "primary": true, "easterDiffDays": 49 },
    { "danish": "2. Pinsedag", "latin": "2. Pentecoste", "holliday": true, "primary": true, "easterDiffDays": 50 },
    { "danish": "Trinitatis", "latin": "Trinitatis", "holliday": true, "primary": false, "easterDiffDays": 56 },
    { "danish": "1. søn e trin.", "latin": "1 p. Trinitatis", "holliday": true, "primary": false, "easterDiffDays": 63 },
    { "danish": "2. søn e trin.", "latin": "2 p. Trinitatis", "holliday": true, "primary": false, "easterDiffDays": 70 },
    { "danish": "3. søn e trin.", "latin": "3 p. Trinitatis", "holliday": true, "primary": false, "easterDiffDays": 77 },
    { "danish": "4. søn e trin.", "latin": "4 p. Trinitatis", "holliday": true, "primary": false, "easterDiffDays": 84 },
    { "danish": "5. søn e trin.", "latin": "5 p. Trinitatis", "holliday": true, "primary": false, "easterDiffDays": 91 },
    { "danish": "6. søn e trin.", "latin": "6 p. Trinitatis", "holliday": true, "primary": false, "easterDiffDays": 98 },
    { "danish": "7. søn e trin.", "latin": "7 p. Trinitatis", "holliday": true, "primary": false, "easterDiffDays": 105 },
    { "danish": "8. søn e trin.", "latin": "8 p. Trinitatis", "holliday": true, "primary": false, "easterDiffDays": 112 },
    { "danish": "9. søn e trin.", "latin": "9 p. Trinitatis", "holliday": true, "primary": false, "easterDiffDays": 119 },
    { "danish": "10. søn e trin.", "latin": "10 p. Trinitatis", "holliday": true, "primary": false, "easterDiffDays": 126 },
    { "danish": "11. søn e trin.", "latin": "11 p. Trinitatis", "holliday": true, "primary": false, "easterDiffDays": 133 },
    { "danish": "12. søn e trin.", "latin": "12 p. Trinitatis", "holliday": true, "primary": false, "easterDiffDays": 140 },
    { "danish": "13. søn e trin.", "latin": "13 p. Trinitatis", "holliday": true, "primary": false, "easterDiffDays": 147 },
    { "danish": "14. søn e trin.", "latin": "14 p. Trinitatis", "holliday": true, "primary": false, "easterDiffDays": 154 },
    { "danish": "15. søn e trin.", "latin": "15 p. Trinitatis", "holliday": true, "primary": false, "easterDiffDays": 161 },
    { "danish": "16. søn e trin.", "latin": "16 p. Trinitatis", "holliday": true, "primary": false, "easterDiffDays": 168 },
    { "danish": "17. søn e trin.", "latin": "17 p. Trinitatis", "holliday": true, "primary": false, "easterDiffDays": 175 },
    { "danish": "18. søn e trin.", "latin": "18 p. Trinitatis", "holliday": true, "primary": false, "easterDiffDays": 182 },
    { "danish": "19. søn e trin.", "latin": "19 p. Trinitatis", "holliday": true, "primary": false, "easterDiffDays": 189 },
    { "danish": "20. søn e trin.", "latin": "20 p. Trinitatis", "holliday": true, "primary": false, "easterDiffDays": 196 },
    { "danish": "21. søn e trin.", "latin": "21 p. Trinitatis", "holliday": true, "primary": false, "easterDiffDays": 203 },
    { "danish": "22. søn e trin.", "latin": "22 p. Trinitatis", "holliday": true, "primary": false, "easterDiffDays": 210 },
    { "danish": "23. søn e trin.", "latin": "23 p. Trinitatis", "holliday": true, "primary": false, "easterDiffDays": 217 },
    { "danish": "24. søn e trin.", "latin": "24 p. Trinitatis", "holliday": true, "primary": false, "easterDiffDays": 224 },
    { "danish": "25. søn e trin.", "latin": "25 p. Trinitatis", "holliday": true, "primary": false, "easterDiffDays": 231 },
    { "danish": "Mariæ Bebudelse", "latin": "Mariæ Bebudelse", "holliday": false, "primary": false, "easterDiffDays": -14 },
    { "danish": "Kyndelmisse", "latin": "Kyndelmisse", "holliday": false, "primary": false }
];


/**
 * Start kalenderen med nuværende år
 */
document.addEventListener("DOMContentLoaded", function (event) {
    let y = new Date().getFullYear();
    document.getElementById('yearinput').value = y;
    Run(y);
});


/**
 * Pad enkeltciffer til dobbeltciffer ( 1 -> "01")
 */
function padout(number) {
    return (number < 10) ? '0' + number : number;
}


/**
 * Er året et skudår
 */
function leapYear(year) {
    return ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
}


/**
 * Tilføj angivne antal dage til Date-objekt
 */
Date.prototype.addDays = function (dayOffset) {
    var _date = new Date();
    var millisecondOffset = dayOffset * 24 * 60 * 60 * 1000;
    _date.setTime(this.getTime() + millisecondOffset);
    return _date;
};



/**
 *
 * Formater Date-object til eks. "2020-04-12"
 *
 */
Date.prototype.formatDate = function () {
    month = '' + (this.getMonth() + 1),
        day = '' + this.getDate(),
        year = this.getFullYear();
    if (month.length < 2)
        month = '0' + month;
    if (day.length < 2)
        day = '0' + day;
    return [year, month, day].join('-');

};

/**
 *
 *  Find ISO Ugenr for datoen
 *
 */
Date.prototype.getWeek = function () {
    var onejan = new Date(this.getFullYear(), 0, 1);
    var millisecsInDay = 86400000;
    return Math.ceil((((this - onejan) / millisecsInDay) + onejan.getDay() + 1) / 7);
};

/**
 *
 * Finder datoen for den førstkommende ugedag angivet i dayOfWeek
 * dayOfWeek (0=søndag .. 6=lørdag)
 *
 */
Date.prototype.getNextDayOfWeek = function (dayOfWeek) {
    var ret = new Date(this || new Date());
    var day = (dayOfWeek - 1 - this.getDay() + 7) % 7 + 1;
    if (day == 7) day = 0;
    ret.setDate(ret.getDate() + day);
    return ret;
};

let firstDayInYear = function(year){
    if (year > 1700) {
        return new Date(year, 0, 1).getDay(); //Find ugedag 1. januar
    }
    else {
        return new Date(year-1, 11, 28).getDay(); //Hvis 1700 eller ældre: træk fire dage fra for korrekt ugedag   
    }
}


function findDates(year) {
    var events = JSON.parse(JSON.stringify(Events)); // Tag kopi af events
    var _easter = new Date(Easter(year)); // Find Påskesøndag

    // Find dato for alle helligdage og mærkedage, der ikke er baseret på dato for påske
    events[0].date = year + "-01-01"; //Nytårsdag
    events[1].date = year + "-01-06"; // Helligtrekonger
    // Søndage efter Helligtrekonger
    var dt = new Date(year + "-01-06").getNextDayOfWeek(0);
    let counter = 0;
    for (ev = 2; ev < 8; ev++) {
        events[ev].date = dt.addDays(counter).formatDate();
        counter += 7;
    }
    events[8].date = new Date(year + "-11-01").getNextDayOfWeek(0).formatDate(); //Alle Helgensdag
    events[9].date = year + "-11-11"; //Mortensdag
    // Søndage i advent
    dt = new Date(year + "-11-27");
    events[10].date = dt.getNextDayOfWeek(0).formatDate(); // 1. søndag i advent (1. søndag efter 27/11)
    counter = 7;
    dt = new Date(events[10].date);
    for (ev = 11; ev < 14; ev++) {
        events[ev].date = dt.addDays(counter).formatDate();
        counter += 7;
    }
    events[14].date = year + "-12-25"; // Juledag
    events[15].date = year + "-12-26";  //2. juledag
    for (ev = 16; ev < 67; ev++) {  // Alle påskeafhængige mmærkedage
        events[ev].date = _easter.addDays(events[ev].easterDiffDays).formatDate();
    }

    if (year < 1771) events[67].date = year + "-03-25"; //Marie Bebudelsesdag- indt 1771 d. 25. marts, derefter søndag før palmesøndag
    else events[25].danish = "Mariæ Bebudelse"; // Skift "2. sæn. før påske" ud med "Marieæ Bebudelse"
    // events[67].date = _easter.addDays(events[67].easterDiffDays).formatDate();
    events[68].date = year + "-02-02"; //Kyndelmisse
    return events;
}



function panelChanged() {
    let i = document.getElementById('yearinput').value;
    if (i.length == 4) {
        if (i < 200) {
            document.getElementById("yearinput").value = "0200";
            i = 200;
        }
        Run(Number(i));
    }
}





function Run(year) {
    var events = findDates(year);
    var monthlength = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
    if (leapYear(year)) monthlength[1] = 29; //Sæt antald age i februar til 29 i skudår
    if (year == 1700) monthlength[1] = 18; //O Overgang fra Juliansk til Gregoriansk kalender 1. marts 1700
    
    //Tøm kalenderen for evt. indhold
    Array.from(document.getElementsByClassName("threemonthcontainer")).forEach(function(e) {e.innerHTML=""});    

    let abbrcounter = 0;
    let julianMoonPhases = [];

    abbrcounter = firstDayInYear(year);

    if (year < 1700) julianMoonPhases = moonPhaseInYear(year);
    var content = "";

    for (monthcounter = 0; monthcounter < months.length; monthcounter++) {
        var monthname = months[monthcounter];

        content += '<div class="month">';

        if ([0, 3, 6, 9].indexOf(monthcounter) > -1)
            content += '<div class="yearheader" id= "yearheader' + monthcounter + '"  >' + year + '</div>';
        else
            content += '<div class="yearheader"></div>';
        content += '<div class="header">' + monthname + '</div>';



        for (daycounter = 1; daycounter < monthlength[monthcounter] + 1; daycounter++) {
            let id = year + "-" + padout(monthcounter + 1) + "-" + padout(daycounter);
            let _date = new Date(year, monthcounter, daycounter);
            let moonClass = "";
            if (document.getElementById("moonCheck").checked) {
                if (year > 1699) moonClass = getMoonSymbolGregorian(_date.formatDate());
                else {
                    let thisPhase = null;
                    thisPhase = julianMoonPhases.find(o => o.dato === id);

                    if (thisPhase != null) {
                        if (thisPhase.phase == "new") moonClass = "&#x1F311;"; else
                            if (thisPhase.phase == "full") moonClass = "&#127765;"; else
                                if (thisPhase.phase == "firstquarter") moonClass = "	&#x1F313;"; else
                                    if (thisPhase.phase == "lastquarter") moonClass = "&#x1F317;"; else
                                        moonClass = "";

                    }
                }
            }

            let divcolor = "";
            let bgcolor = "";
            let _abbr = abbr[abbrcounter];
            let wn = "";
            let eventName = "";
            //if (id.substr(0,1)=="0") id = id.substr(1,id.length-1);
            var idx = events.findIndex(x => x.date == id);
            // if ((idx == -1) && (year < 1000)) {
            //     if (id.substr(0, 1) == "0") id = id.substr(1, id.length - 1);
            //     idx = events.findIndex(x => x.date == id);
            // }
            let latin = document.getElementById("latinCheck").checked;
            let extended = document.getElementById("eventCheck").checked;
            if (idx > -1) {
                if (extended != true) {
                    if (events[idx].primary == true)
                        if (latin == true)
                            eventName = events[idx].latin; else
                            eventName = events[idx].danish;
                } else {
                    if (latin == true)
                        eventName = events[idx].latin; else
                        eventName = events[idx].danish;
                }
                if (events[idx].holliday === true) divcolor = "grayed";
            }

            if (_abbr == "L") { bgcolor = "grayed" } else
                if (_abbr == "S") { divcolor = "grayed" } else 
                    if (_abbr == "M") { wn = new Date(id).getWeek(); } // Sæt ugenr hver mandag

            content += '<div id="' + id + '" class="day ' + divcolor + '"><span class="abbr ' + bgcolor + '">' + _abbr + '</span><span class="daynumber ' + bgcolor + '">' + daycounter + '</span><span class="eventtitle" style="max-height: 17px; width: 190.2px; top: 4px;">' + eventName + '</span><span class="moon">' + moonClass + '</span><span class="weeknumber">' + wn + '</span></div>';
            abbrcounter++;
            if (abbrcounter == 7) abbrcounter = 0;
        }
        content += '</div>';
        if (monthcounter < 3) document.getElementById("firstquarter").innerHTML += content; else
            if (monthcounter < 6) document.getElementById("secondquarter").innerHTML += content; else
                if (monthcounter < 9) document.getElementById("thirdquarter").innerHTML += content; else
                    if (monthcounter < 12) document.getElementById("fourthquarter").innerHTML += content;
        content = "";

    }

}

//Fra 1. marts 1700 og frem
let getMoonSymbolGregorian = function (_date) {
    let moonClass = "";
    let fromDate = "";
    year = _date.substr(0, _date.indexOf('-'));
    // Hvis 1700, så kun fra 1. marts og året ud
    if (year == 1700) {
        fromDate = new Date(year + '-03-01T00:00:00.000Z');

    } else
        fromDate = new Date(year + '-01-01T00:00:00.000Z');
    let toDate = new Date(year + '-12-31T23:59:59.999Z');
    let fullMoon_list = phaseRange(fromDate, toDate, FULL); 
    let newMoon_list = phaseRange(fromDate, toDate, NEW);
    let firstQuarterMoon_list = phaseRange(fromDate, toDate, FIRST);
    let lastQuarterMoon_list = phaseRange(fromDate, toDate, LAST);


    // Hardcoder månefaser for januar/februar 1700
    if (year == 1700) {
        fullMoon_list.push("1700-01-24");
        newMoon_list.push("1700-01-10");
        newMoon_list.push("1700-02-09");
        firstQuarterMoon_list.push("1700-01-18");
        firstQuarterMoon_list.push("1700-02-16");
        lastQuarterMoon_list.push("1700-01-02");
        lastQuarterMoon_list.push("1700-01-31");
    }

    if (newMoon_list.indexOf(_date) > -1) moonClass = "&#x1F311;"; else
        if (fullMoon_list.indexOf(_date) > -1) moonClass = "&#127765;"; else
            if (firstQuarterMoon_list.indexOf(_date) > -1) moonClass = "	&#x1F313;"; else
                if (lastQuarterMoon_list.indexOf(_date) > -1) moonClass = "&#x1F317;";
    return moonClass;
}


let moonPhase = function (date) {
    var jdo = new A.JulianDay(date);
    var coord = A.EclCoord.fromWgs84(55.719437, 13.197304, 50);
    var suntp = A.Solar.topocentricPosition(jdo, coord, true);
    var moontp = A.Moon.topocentricPosition(jdo, coord, true);
    var i = A.MoonIllum.phaseAngleEq2(moontp.eq, suntp.eq);
    return A.MoonIllum.illuminated(i);
}


let moonPhaseInYear = function (y) {
    var previousValue = 0;
    var currentValue = 0;
    var date = new Date(y - 1, 11, 31, 14, 0, 0); // Start med sidste dag i året før
    var previousDate = date.formatDate();
    var quarterStigende = true;
    var currentQuarterValue = 0;
    var phases = [];

    previousValue = moonPhase(date);
    var previousQuarterValue = Math.abs(0.5 - previousValue); //Afvigelse fra kvarter

    var stigende;
    do { // For alle dage i året
        currentValue = moonPhase(date);
        currentQuarterValue = Math.abs(0.5 - currentValue);
        if (currentQuarterValue > previousQuarterValue) {
            if (quarterStigende == false) {
                if (previousDate.indexOf(y) > -1)
                    phases.push({ "dato": previousDate, "phase": "quarter" }); // Sæt foreløbig til "quarter", vi ved endnu ikke om det er første eller tredje
            }
            quarterStigende = true;
        }
        else {
            quarterStigende = false;
        }
        if (currentValue > previousValue) {
            if (stigende == false) {
                phases.push({ "dato": previousDate, "phase": "new" });
            }
            stigende = true;
        }
        else {
            if (stigende == true) {
                phases.push({ "dato": previousDate, "phase": "full" });
            }
            stigende = false;
        }
        previousValue = currentValue;
        previousQuarterValue = currentQuarterValue;
        previousDate = date.formatDate();
        date = date.addDays(1);
    }
    while (date.getFullYear() == y)
    var i = 0;
    for (i = 0; i < phases.length; i++) { //På baggrund af nymånbe og fuldmåne søt 1. og 3. kvarter
        if (i == 0) {
            if (phases[1].phase == "new") phases[0].phase = "lastquarter";
            if (phases[1].phase == "full") phases[0].phase = "firstquarter";
        }
        else
            if (i == phases.legth) {
                if (phases[i - 1].phase == "new") phases[i].phase = "lastquarter";
                if (phases[i - 1].phase == "full") phases[i].phase = "firstquarter";

            }
        if (i != phases.legth && (i != 0)) {
            if (phases[i].phase == "new") {
                phases[i - 1].phase = "lastquarter";

                if (i + 1 < phases.length)
                    phases[i + 1].phase = "firstquarter";
            }
            if (phases[i].phase == "full") {
                phases[i - 1].phase = "firstquarter";
                if (i + 1 < phases.length)
                    phases[i + 1].phase = "lastquarter";
            }
        }
    }
    return phases;
}





function Easter(y) {
    if (y >= 1700) {
        return GregorianEaster(y); //Gregorianske kalender indført 1.marts 1700 (altså før påskedag i året)
    } else {
        return JulianEaster(y); //Find påske efter juliansk kalender indtil 1. marts 1700 
    }
}

//Se Wikipedia: Beregning af datoen for påskedag
// https://da.wikipedia.org/wiki/P%C3%A5ske#Beregning_af_datoen_for_p%C3%A5skedag
function GregorianEaster(y) {
    Y = parseInt(y);
    var C = Math.floor(Y / 100);
    var N = Y - 19 * Math.floor(Y / 19);
    var K = Math.floor((C - 17) / 25);
    var I = C - Math.floor(C / 4) - Math.floor((C - K) / 3) + 19 * N + 15;
    I = I - 30 * Math.floor((I / 30));
    I = I - Math.floor(I / 28) * (1 - Math.floor(I / 28) * Math.floor(29 / (I + 1)) * Math.floor((21 - N) / 11));
    var J = Y + Math.floor(Y / 4) + I + 2 - C + Math.floor(C / 4);
    J = J - 7 * Math.floor(J / 7);
    var L = I - J;
    var M = 3 + Math.floor((L + 40) / 44);
    var D = Math.floor(L + 28 - 31 * Math.floor(M / 4));
    if (y == 1744) return Y + "-" + padout(3) + "-" + padout(29);
    return Y + "-" + padout(M) + "-" + padout(D); // 12-04-2020
}


// JulianEaster baeret på J R Stocktons "The Calculation of Easter Sunday":	
// https://people.cs.nctu.edu.tw/~tsaiwn/sisc/runtime_error_200_div_by_0/www.merlyn.demon.co.uk/estr-bcp.htm

function JulianEaster(Y) {
    Y = parseInt(Y);
    function GoldenNumber(Yr) { return Mod(Yr, 19) + 1 }
    function Mod(X, Y) { return X - Math.floor(X / Y) * Y }
    function GNtoJulianPFM(GN) { // By analogy with Gregorian data
        // Golden Number to PFM as Day-of-March, valid perpetually
        var T = 21 + (GN * 19 - 4) % 30; return T
    }
    function Div(X, Y) { return Math.floor(X / Y) /* full range */ }
    function JulianSundayNumber(Y) {
        var Z = 4 + Y + Div(Y, 4)
        return 6 - Mod(Z, 7) /* 0-6 matches Sunday Letter A-G */
    }
    function JPFMtoDate2(Year, DM) {
        var SN // Ahead to Julian Sunday
        SN = JulianSundayNumber(Year)
        return YDoMtoYMonDD(Year, SundayAfterPFM(DM, SN))
    }
    function YDoMtoYMonDD(Y, DM) { return Y + DoMtoMonDD(DM) }
    function DoMtoMonDD(DM) {
        return DM > 31 ? "-04-" + LZ(DM - 31) : "-03-" + DM
    }
    function LZ(n) { return (n != null && n < 10 && n >= 0 ? "0" : "") + n }
    function SundayAfterPFM(DM, SN) { // plus 1..7 days to Sunday, J & G
        return DM + 1 + (60 + SN - DM) % 7 /* Day-of-March */
    }
    Y = parseInt(Y);
    var GN = GoldenNumber(Y)
    var PFM = GNtoJulianPFM(GN)
    return JPFMtoDate2(Y, PFM)
}

/*
 * TruePhase and PhaseRange er dele af lune.js;
 * Author: Ryan Seys (https://github.com/ryanseys)
 * Author: Jay LaPorte (https://github.com/ironwallaby)
 */
const NEW = 0
const FIRST = 1
const FULL = 2
const LAST = 3

function dsin(d) {
    return Math.sin(torad(d))
}

function dcos(d) {
    return Math.cos(torad(d))
}

function torad(d) {
    return (Math.PI / 180.0) * d
}

function fromDate(date) {
    return date.getTime() / 86400000 + 2440587.5
}

function toDate(julian) {
    return new Date((julian - 2440587.5) * 86400000)
}

function truephase(k, tphase) {
    tphase = tphase & 3
    k = k + 0.25 * tphase
    const t = (1.0 / 1236.85) * k
    let pt = 2415020.75933 +
        29.53058868 * k +
        (0.0001178 - 0.000000155 * t) * t * t +
        0.00033 * dsin(166.56 + (132.87 - 0.009173 * t) * t)
    const m = 359.2242 + 29.10535608 * k - (0.0000333 - 0.00000347 * t) * t * t
    const mprime = 306.0253 + 385.81691806 * k + (0.0107306 + 0.00001236 * t) * t * t
    const f = 21.2964 + 390.67050646 * k - (0.0016528 - 0.00000239 * t) * t * t
    switch (tphase) {
        case NEW:
        case FULL:
            pt += (0.1734 - 0.000393 * t) * dsin(m) +
                0.0021 * dsin(2 * m) -
                0.4068 * dsin(mprime) +
                0.0161 * dsin(2 * mprime) -
                0.0004 * dsin(3 * mprime) +
                0.0104 * dsin(2 * f) -
                0.0051 * dsin(m + mprime) -
                0.0074 * dsin(m - mprime) +
                0.0004 * dsin(2 * f + m) -
                0.0004 * dsin(2 * f - m) -
                0.0006 * dsin(2 * f + mprime) +
                0.0010 * dsin(2 * f - mprime) +
                0.0005 * dsin(m + 2 * mprime)
            break
        case FIRST:
        case LAST:
            pt += (0.1721 - 0.0004 * t) * dsin(m) +
                0.0021 * dsin(2 * m) -
                0.6280 * dsin(mprime) +
                0.0089 * dsin(2 * mprime) -
                0.0004 * dsin(3 * mprime) +
                0.0079 * dsin(2 * f) -
                0.0119 * dsin(m + mprime) -
                0.0047 * dsin(m - mprime) +
                0.0003 * dsin(2 * f + m) -
                0.0004 * dsin(2 * f - m) -
                0.0006 * dsin(2 * f + mprime) +
                0.0021 * dsin(2 * f - mprime) +
                0.0003 * dsin(m + 2 * mprime) +
                0.0004 * dsin(m - 2 * mprime) -
                0.0003 * dsin(2 * m + mprime)

            const sign = (tphase < FULL) ? +1 : -1
            pt += sign * (0.0028 - 0.0004 * dcos(m) + 0.0003 * dcos(mprime))
            break
    }
    return toDate(pt)
}


function phaseRange(start, end, phase) {

    if (end - start < 0) {
        let temp = end
        end = start
        start = temp
    }

    start = start.getTime()
    end = end.getTime()
    let t = start - 45 * 86400000
    let k
    {
        const d = new Date(t)
        k = Math.floor(12.3685 * (d.getFullYear() + (1.0 / 12.0) * d.getMonth() - 1900))
    }

    let date = truephase(k, phase)

    while (date.getTime() < start) {
        k++
        date = truephase(k, phase)
    }
    const list = []

    while (date.getTime() <= end) {
        list.push(date.formatDate())
        k++
        date = truephase(k, phase)
    }
    return list
}

              
            
!
999px

Console