nikolausdulgeridis
  JavaScript naechstermonat
 
JavaScript - Beispiel zur Datumsberechnung - Monatswechsel
 
Thema: 
Beispiele für Datumsberechnung in JavaScript, anhand einer mit wenig Aufwand anpassbaren Vorlage

siehe auch: JavaScript-ClockExample.htm

Im Intranet sammelt sich einiges an: Dienstpläne, Umsatzberichte, ...
Der Zugriff kann z. B. über eine Ubersichtsseite erfolgen, mit einem Link auf jeden Monat.

Beispiel Linkliste:
/dfs/berichte/Ausgaben-01-2019.html
/dfs/berichte/Ausgaben-02-2019.html
... 
Nun wäre es eleganter, das ganze etwas dynamischer zu gestelten. Das wird im folgenden Beispiel mit etwas JavaScript realisiert (da wir derzeit noch keine Inhalte haben, ist der iFrame natürlich leer, es soll hier nur die Mechanik dargestellt werden).
 

Beispiel (Hinweis: das iFrame ist leer bzw. undefiniert)


      Bericht  -JavaScript needed-   -JavaScript needed-       Dateiname -JavaScript needed- 

 

 
Der JavaScript Code im Einzelnen
 
A) Angenommen, wir wollen den Namen des Berichts im aktuellen Monat erhalten: 

Die Berichte wurden in unserem Beispiel nach folgendem Schema abgelegt: 
<basepath>/Bericht-<mm>-<jjjj>.html
 
 var jetzt= new Date(); 
 var mm= ""+(jetzt.getMonth()+1);   // Wertebereich 1 bis 12 
 var jjjj= jetzt.getFullYear();     // vierstellig (ab 1970)
 var basepath="./";
 if(mm<10) mm='0'+z;                // zwei Ziffern 
 var result=basepath+"Bericht-"+mm+"-"+jjjj;
 
Hier sehen wir den ersten Fallstrick: die haeufigste Konvention ist ein zweistelliges Monatsformat (also 01 ), das muss aber natuerlich nicht so sein. Hier muss man sich mit demjenigen, der den Bericht einstellt abstimmen. Man kann alternativ den Link direkt von der Übersichtsseite nehmen, damit wäre auch sichergestellt, dass das Dokument existiert.
 
Elegant ist die Verwendung eines Templates, mm und jjjj sind die Platzhlter:
 var bericht= "Bericht-mm-jjjj.htm"; // hier das Template mit Platzhaltern
 bericht= bericht.replace(/mm/,mm);  // ersetze mm mit dem aktuellen Monat
 bericht= bericht.replace(/jjjj/,jjjj); // ersetze jjjj mit dem aktuellen Jahr
 var result=basepath+bericht;
 
Benötigt man den Monat in Textform, kann man das wie folgt loesen;
 MonatAr= ["Januar","Februar","M&auml;rz","April","Mai","Juni","Juli","August","September","Oktober","November","Dezember"];
 monatTxt= MonatAr[new Date().getMonth()];
(Man beachte den Umlaut im Monat Maerz - ein weiterrer Fallstrick, da der Umlaut auf versch. Arten geschrieben oder codiert werden kann)
 
B) Jetzt kommen wir zum eigentlichen Thema des Blogs: Ermitteln des Folgemonats
 
Im Grunde wäre die Augabe einfach, müsste nicht der Jahreswechsel berücksichtigt werden. Es bieten sich zwei grundsaetzlich verschiedene Ansätze: 
 
mathematisch:
 
 var jetzt= new Date();              // hole aktuelles Datum
 var m= jetzt.getMonth();          // Monat Wertebereich 1 bis 12 
 var jjjj= jetzt.getFullYear();     // Jahr´vierstellig 
 
 function nxtmon(direction,m,j) 
 {
  // direction= +1 => vorwaerts, -1 => rueckwaerts 
  // m= Monat, Wertebereich 0..11
  m+=direction;
  if (m<0 || m>11) {m-=direction*12; j+=direction;}
  // alternativ mit Modulorechnung: 
  //m=(m+direction+12)%12;
  //if (m-direction<0 || m-direction>11) j+=direction;
 }
 
oder über die JS Datumsbibliothek: 
 
 function naechsterMonat(aktdatum,direction) 
 {
  var eintag=24*60*60*1000; 
  var nxt=aktdatum;
  var aktmonat= aktdatum.getMonth(); 
  max = 32;
  do 
    {
     nxt=  new Date(nxt.getTime() + eintag * direction);
    } 
  while (max-- && (aktmonat == nxt.getMonth()));
  return nxt; // ergebnis ist der erste Tag im naechsten Monat oder der letzte im vorigen
 }
 
Die letzte Variante hat den Vorteil, dass die internen Bibliotheken automatisch Schaltjahre etc. beruecksichtigen. Das ist im vorliegenden Fall nicht interessant, aber bei komplizierteren Berechnungen (z. Bsp. Ermittlung des nächsten Tages) erspart man sich eine Menge Arbeit. 
 
C) Zeit runden
 
Ein etwas anderes Thema ist die Frage, wie auf ganze Stunden oder Minuten werden kann

Die Fragestellung ist etwas offtopic, kann aber spaeter benoetigt werden, deshalb erlauben wir uns den kleinen Ausflug 
 
Algorithmus: Angenommen wir wollen auf 30 Minuten runden.
 - Hole Integer Wert aus der Unix Zeit
 - teile durch 30 Min
 - Nachkommastellen abschneiden
 - multipliziere mit 30 
 - Wandle Integer zurück in Unix Zeit

<script>
jetzt= new Date();
t=(Date.parse(jetzt));
rundeaufminuten=30;
//abrunden, runden, aufrunden: floor round ceil
var result = new Date(Math.round(t/(rundeaufminuten*60*1000))*(rundeaufminuten*60*1000));
document.write("<br>Zeit gerundet auf 30 Minuten<br> ");
document.write(result);
</script>


noch ein Beispiel: 
zur aktuellen Zeit eine halbe Stunde addieren

jetzt= new Date();
t=(Date.parse(jetzt));
result = new Date(t+30*60*1000);

 
D) der fertige Code 

Das Skript enthält ein iFrame für den aktuellen Monat und einen Button zum Vor- und Zurückblättern.

Man könnte argumentieren, dass ein CMS eine eher zeitgemaesse Lösung darstellt. 
Das ist aber mitnichten der Fall. Ein Firmenintranet ist inhomogen aufgebaut und enthält den Zugriff auf verschiedenste Datenquellen. Ein oder mehrere CMS (z.Bsp. ein Firmenwiki) stellen hier nur einen Teilaspekt dar.



<head>
<style>
 #berichtframe { margin: 1px; border-radius: 8px; box-shadow: 1px 1px 4px #000; height: 300px; width: 600px; display: inline}
</style>
</head>

<div>
&nbsp;<input type="button" onclick='nextmonat(-1);' value="<<" title="zurueck"/>&nbsp;
&nbsp;<input type="button" onclick='nextmonat(+1);' value=">>" title="vor" />&nbsp;
Bericht&nbsp;
<b><span id="Anzeigemonat">-JavaScript needed-</span> </b>&nbsp;
<b><span id="Anzeigejahr" >-JavaScript needed-</span> </b>&nbsp;
&nbsp;&nbsp; Dateiname: <span id="berichturl">-JavaScript needed-</span> &nbsp;
</div>

<div style="clear:both">
<iframe src="bericht-12-2019.htm" id="berichtframe" ></iframe>
</div>

<script>

var basispfad="./";
var basisname="bericht-mm-jjjj";
var jetzt= new Date();
var monat=jetzt.getMonth();
var jahr= jetzt.getFullYear();;
var MonatAr= ["Januar","Februar","M&auml;rz","April","Mai","Juni","Juli","August","September","Oktober","November","Dezember"];

show();

function show()
 {
  document.getElementById("Anzeigemonat").innerHTML=MonatAr[monat];
  document.getElementById("Anzeigejahr").innerHTML=jahr;

  // lade Bericht im Frame  
  mm=monat+1;
  if(mm<10) mm='0'+mm; // zwei Ziffern
  var berichtname= basisname.replace(/mm/,mm);
  berichtname= berichtname.replace(/jjjj/,jahr);
  var berichturl= basispfad+berichtname;
  document.getElementById("berichturl").innerHTML=berichturl;
  // lade Bericht in frame
  document.getElementById("berichtframe").src=berichturl;
 }

function nextmonat(direction)
 {
 monat+=direction; // direction +1=vor, -1=zurueck
 if (monat<0 || monat>11) {monat-=direction*12; jahr+=direction;}
 show();
 }

</script>
 
  33 Besucher