Zeitraum splitten bei Jahreswechsel

Zero2000

Erfahrenes Mitglied
Hallo,

ich Programmiere gerade einen Urlaubsplaner und stehe nun vor dem Problem Jahresübergreifender Urlaub.
Bisher hatten wir es so gehandhabt, dass nur ein Person den Urlaub eintragen und verwalten konnte. Nehmen wir mal einen Zeitraum vom 24.12.2015 bis 08.01.2016. Diese Person wusste, dass der Urlaub beim Jahreswechsel z.B. vom 24.12.2015 bis 31.12.2015 und danach noch ein Urlaub vom 01.01.2015 bis 08.01.2016 einzutragen ist.

Nun habe ich den Urlaubsplaner Grundlegend verändert und jeder kann seinen eigenen Urlaub verwalten. Aus diesem Grund wollte ich es den Benutzern so einfach wie möglich machen und zwar so, dass diese ganz normal ihren gewünschten Zeitraum eingeben können, also 24.12.2015 bis 08.01.2016. Ich benötige dennoch zwei Eintragungen in die MYSQL-DB wegen der Berechnung der Arbeitstage und der Anzeige der Urlaube pro Jahr.

Wie kann ich das am besten realisieren? Keine Ahnung welchen Code Ihr benötigt, nachfolgend mal wie der Eintrag in die DB aussieht.

PHP:
if(isset($_POST['up_sub_u']))
{
 //var_dump($_SESSION);
 $ma_id = $_POST['ma_id'];
 $abt_id = $_POST['abt_id'];
 //  Abfrage ob Ganztag oder Halbtag
 if(isset($_POST['am']))
 {
 $von = date_german2mysql($_POST['am']);
 $bis = date_german2mysql($_POST['am']);
 }else{
 $von = date_german2mysql($_POST['vom']);
 $bis = date_german2mysql($_POST['bis']);
 }
 $grund = $_POST['grund'];
 $freitagenamen_id = $_POST['urlaub'];
 $zeitraum = $_POST['zeitraum'];
 $vertretung = $_POST['vertretung'];
 $urlaubsanschrift = $_POST['urlaubsanschrift'];
 $kommentar = $_POST['kommentar'];
##########################################################################################
$year = date("Y");
// Feste Feiertage Sachsen-Anhalt
$feiertage[] = "0101"; // Neujahrstag
$feiertage[] = "0601"; // Heilige drei Könige
$feiertage[] = "0105"; // Tag der Arbeit
$feiertage[] = "0310"; // Tag der Deutschen Einheit
$feiertage[] = "3110"; // Reformationstag
$feiertage[] = "2512"; // Erster Weihnachtstag
$feiertage[] = "2612"; // Zweiter Weihnachtstag
// Bewegliche Feiertage berechnen
function get_easter_datetime($year) {
$days = easter_days($year);
return mktime(0, 0, 0, 3, 21+$days,$year);
}
$tage = 86400; //60 * 60 * 24
$ostersonntag = get_easter_datetime($year);
$feiertage[] = date("dm", $ostersonntag - 2 * $tage);  // Karfreitag
$feiertage[] = date("dm", $ostersonntag + 1 * $tage);  // Ostermontag
$feiertage[] = date("dm", $ostersonntag + 39 * $tage); // Himmelfahrt
$feiertage[] = date("dm", $ostersonntag + 50 * $tage); // Pfingstmontag

//Wochenenden des Jahres ausgeben
$prevTime = mktime(0,0,0, 1,1,$year);
$currYear = date ('Y');
$aWeekends = array ();
while(true)
  {
  $prevTime = strtotime ('next saturday' , $prevTime);
  $prevYear = date ('Y' , $prevTime);
  if ($prevYear > $currYear) break;
  $aWeekends[] = date ('dm' , $prevTime);
  $aWeekends[] = date ('dm' , $prevTime + 3600 * 24);
  }
// Array mit den gesamten Tagen aus von und bis bilden
$startdatum = strtotime($von);
$enddatum = strtotime($bis);
while ($startdatum <= $enddatum)
{
 $vonbis[] = date('dm', $startdatum);
 $startdatum += 24 * 60 * 60;
}
// neues array erstellen wo die wochenenden nicht mehr dabei sind
$cleanarraywe = array_diff($vonbis, $aWeekends);
// neues array erstellen wo die Feiertage nicht mehr dabei sind
$cleanarrayft = array_diff($cleanarraywe, $feiertage);

if(isset($_POST['am'])){
 $tage = 0.5;
}else{
 $tage = count($cleanarrayft);
}

// TEST JAHRESWECHSEL
$vonjahr = date("Y",strtotime($von));
$bisjahr = date("Y",strtotime($bis));
if($bisjahr > $vonjahr){
 echo "Das ist ein Jahreswechsel<br>";
 echo "Eintrag 1 müsste dann vom ".$von. " bis 2015-12-31 gehen<br>";
 echo "Eintrag 2 müsste dann vom ".$bisjahr."-01-01 bis ".$bis." gehen";
}

$res = mysql_query("
INSERT INTO freitage
 (ma_id,abteilungen_id,freitagenamen_id,von,bis,tage,zeitraum,vertretung,grund,urlaubsanschrift,kommentar,datum_beantragt)
VALUES
 ('$ma_id','$abt_id','$freitagenamen_id','$von','$bis','$tage','$zeitraum','$vertretung','$grund','$urlaubsanschrift','$kommentar',now())") or die("Eintrag fehlgeschlagen.<br><br>".mysql_error());

  $num = mysql_affected_rows();
  if ($num>0)
  {
  $last_id = mysql_insert_id();
  
  include('up_eintrag_u_view.php');
  // Mail nur versenden wenn admin_mail_notification gesetzt
  if($_SESSION['user_admin_mail_notification'] == 1 ){
  include('up_mail_u_neu.php');
  }
  
  }else{
  echo '<div id="nachricht"><div class="alert alert-danger" role="alert">';
  echo '<strong>Es ist ein Fehler aufgetreten!</strong><br>Der Urlaub konnte nicht erstellt werden.';
  echo '</div></div>';
  }
}

MfG
Maik
 
Du bist da denke ich schon auf einem guten Weg. Testen ob das Jahr in den beiden Einträgen unterschiedlich ist und wenn ja, die Funktion (die noch zu erstellen ist) zum Eintragen zweimal mit unterschiedlichen Zeiträumen aufrufen.
von -31.12.j1 und 1.1.j2 -bis
 
Naja, ich sehe ja selbst das ich auf einem guten Weg bin ;), aber genau das mit dem zweimal eintragen bereitet mir ja doch noch Kopfschmerzen. Eine For-Schleife ist denke ich hier das richtige Mittel, aber wie mache ich der klar, dass in die DB zwei Einträge mit unterschiedlichen Daten kommen?
 
Gemeint war das folgende:

PHP:
function Eintragen(ma_id,abteilungen_id,freitagenamen_id,von,bis,tage,zeitraum,vertretung,grund,urlaubsanschrift,kommentar,datum_beantrag){
  $res = mysql_query("
  INSERT INTO freitage
   (ma_id,abteilungen_id,freitagenamen_id,von,bis,tage,zeitraum,vertretung,grund,urlaubsanschrift,kommentar,datum_beantragt)
  VALUES
   ('$ma_id','$abt_id','$freitagenamen_id','$von','$bis','$tage','$zeitraum','$vertretung','$grund','$urlaubsanschrift','$kommentar',now())") or die("Eintrag fehlgeschlagen.<br><br>".mysql_error());
  
  $num = mysql_affected_rows();
  if ($num>0)
  {
  $last_id = mysql_insert_id();
}
// TEST JAHRESWECHSEL
$vonjahr = date("Y",strtotime($von));
$bisjahr = date("Y",strtotime($bis));
if($bisjahr > $vonjahr){
 echo "Das ist ein Jahreswechsel<br>";
 echo "Eintrag 1 müsste dann vom ".$von. " bis 2015-12-31 gehen<br>";
 echo "Eintrag 2 müsste dann vom ".$bisjahr."-01-01 bis ".$bis." gehen";
Eintragen(ma_id,abteilungen_id,freitagenamen_id,$von,"$vonjahr-12-31",tage,zeitraum,vertretung,grund,urlaubsanschrift,kommentar,datum_beantrag
Eintragen(ma_id,abteilungen_id,freitagenamen_id,"$bisjahr-01-01",$bis,tage,zeitraum,vertretung,grund,urlaubsanschrift,kommentar,datum_beantrag
}
else{
Eintragen(ma_id,abteilungen_id,freitagenamen_id,$von,$bis,tage,zeitraum,vertretung,grund,urlaubsanschrift,kommentar,datum_beantrag
}
 
Vielen Dank, das klappt schonmal sehr gut. Was ich jetzt noch nicht geschafft habe, ist die berechneten Tage für beide Einträge korrekt zu berechnen.
Ich erhalte die Tage für den gesamten Zeitraum bei beiden Einträgen, also statt Eintrag 1 = 5 Tage und Eintrag 2 = 4 Tage erhalte ich eben bei beiden 9 Tage.
 
Ich denke, du musst deinen Code ein bisschen umschreiben. Wenn du zwei separate Einträge haben willst, musst du die Berechnung der Tage auch zweimal machen.
Wenn du deine Berechnung ebenfalls in eine Funktion kapselst, sollte das einfach gehen.
 
Ja, also Funktionen muss ich mir unbedingt mal genauer ansehen, auf jeden Fall klappt es so nicht:
PHP:
if(isset($_POST['up_sub_u']))
{
 //var_dump($_SESSION);
 $ma_id = $_POST['ma_id'];
 $abt_id = $_POST['abt_id'];
 //  Abfrage ob Ganztag oder Halbtag
 if(isset($_POST['am']))
 {
 $von = date_german2mysql($_POST['am']);
 $bis = date_german2mysql($_POST['am']);
 }else{
 $von = date_german2mysql($_POST['vom']);
 $bis = date_german2mysql($_POST['bis']);
 }
 $grund = $_POST['grund'];
 $freitagenamen_id = $_POST['urlaub'];
 $zeitraum = $_POST['zeitraum'];
 $vertretung = $_POST['vertretung'];
 $urlaubsanschrift = $_POST['urlaubsanschrift'];
 $kommentar = $_POST['kommentar'];
##########################################################################################

#########
function arbeitstage($von,$bis)
{
 
$year = date("Y");
// Feste Feiertage Sachsen-Anhalt
$feiertage[] = "0101"; // Neujahrstag
$feiertage[] = "0601"; // Heilige drei Könige
$feiertage[] = "0105"; // Tag der Arbeit
$feiertage[] = "0310"; // Tag der Deutschen Einheit
$feiertage[] = "3110"; // Reformationstag
$feiertage[] = "2512"; // Erster Weihnachtstag
$feiertage[] = "2612"; // Zweiter Weihnachtstag
// Bewegliche Feiertage berechnen
function get_easter_datetime($year) {
$days = easter_days($year);
return mktime(0, 0, 0, 3, 21+$days,$year);
}
$tage = 86400; //60 * 60 * 24
$ostersonntag = get_easter_datetime($year);
$feiertage[] = date("dm", $ostersonntag - 2 * $tage);  // Karfreitag
$feiertage[] = date("dm", $ostersonntag + 1 * $tage);  // Ostermontag
$feiertage[] = date("dm", $ostersonntag + 39 * $tage); // Himmelfahrt
$feiertage[] = date("dm", $ostersonntag + 50 * $tage); // Pfingstmontag

//Wochenenden des Jahres ausgeben
$prevTime = mktime(0,0,0, 1,1,$year);
$currYear = date ('Y');
$aWeekends = array ();
while(true)
  {
  $prevTime = strtotime ('next saturday' , $prevTime);
  $prevYear = date ('Y' , $prevTime);
  if ($prevYear > $currYear) break;
  $aWeekends[] = date ('dm' , $prevTime);
  $aWeekends[] = date ('dm' , $prevTime + 3600 * 24);
  }
// Array mit den gesamten Tagen aus von und bis bilden
$startdatum = strtotime($von);
$enddatum = strtotime($bis);
while ($startdatum <= $enddatum)
{
 $vonbis[] = date('dm', $startdatum);
 $startdatum += 24 * 60 * 60;
}
// neues array erstellen wo die wochenenden nicht mehr dabei sind
$cleanarraywe = array_diff($vonbis, $aWeekends);
// neues array erstellen wo die Feiertage nicht mehr dabei sind
$cleanarrayft = array_diff($cleanarraywe, $feiertage);

/*if(isset($_POST['am'])){
 $tage = 0.5;
}else{
 $tage = count($cleanarrayft);
}*/

return ($tage);

}//ENDE FUNKTION ARBEITSTAGE
########

################################ FUNKTION ZUM EINTRAGEN ##############################################
function Eintragen($ma_id,$abt_id,$freitagenamen_id,$von,$bis,$tage,$zeitraum,$vertretung,$grund,$urlaubsanschrift,$kommentar,$datum_beantragt)
{
 $res = mysql_query("
 INSERT INTO freitage
 (ma_id,abteilungen_id,freitagenamen_id,von,bis,tage,zeitraum,vertretung,grund,urlaubsanschrift,kommentar,datum_beantragt)
 VALUES
 ('$ma_id','$abt_id','$freitagenamen_id','$von','$bis','$tage','$zeitraum','$vertretung','$grund','$urlaubsanschrift','$kommentar',now())
 ") or die("Eintrag fehlgeschlagen.<br><br>".mysql_error());

 $num = mysql_affected_rows();
 if ($num>0){
 $last_id = mysql_insert_id();
 include('up_eintrag_u_view.php');
 // Mail nur versenden wenn admin_mail_notification gesetzt
 if($_SESSION['user_admin_mail_notification'] == 1 ){
 include('up_mail_u_neu.php');
 }
  
  }else{
  echo '<div id="nachricht"><div class="alert alert-danger" role="alert">';
  echo '<strong>Es ist ein Fehler aufgetreten!</strong><br>Der Urlaub konnte nicht erstellt werden.';
  echo '</div></div>';
 }
 
}// ENDE FUNKTION EINTRAGEN
 
 // TEST JAHRESWECHSEL
 $vonjahr = date("Y",strtotime($von));
 $bisjahr = date("Y",strtotime($bis));
 if($bisjahr > $vonjahr){
 echo "Das ist ein Jahreswechsel<br>";
 echo "Eintrag 1 müsste dann vom ".$von. " bis ".$vonjahr."-12-31 gehen<br>";
 echo "Eintrag 2 müsste dann vom ".$bisjahr."-01-01 bis ".$bis." gehen";
 $von1 = $von;
 $von2 = $bisjahr.'-01-01';
 $bis1 = $vonjahr.'-12-31';
 $bis2 = $bis;
 
 var_dump($von1,$bis1,$von2,$bis2);
 
 $tage1 = arbeitstage($von1,$bis1);
 //$tage2 = arbeitstage($von2,$bis2);
 
 var_dump($tage1);
 var_dump($tage2);
 
 Eintragen($ma_id,$abt_id,$freitagenamen_id,$von,"$vonjahr-12-31",$tage1,$zeitraum,$vertretung,$grund,$urlaubsanschrift,$kommentar,$datum_beantragt);
 Eintragen($ma_id,$abt_id,$freitagenamen_id,"$bisjahr-01-01",$bis,$tage2,$zeitraum,$vertretung,$grund,$urlaubsanschrift,$kommentar,$datum_beantragt);
 }else{
 echo "Das ist kein Jahreswechsel<br>";
 echo "Eintrag müsste demnach vom ".$von. " bis ".$bis." gehen<br>";
 $tage = arbeitstage($von,$bis);
 Eintragen($ma_id,$abt_id,$freitagenamen_id,$von,$bis,$tage,$zeitraum,$vertretung,$grund,$urlaubsanschrift,$kommentar,$datum_beantragt);
 }
 
}// ENDE IF SUBMIT
Vielleicht kann mich da wer nochmal in die richtige Richtung schubsen?
 
Hab einen Teilerfolg erzielen können..
So wie nachfolgend trägt er mir beide Urlaube ein, jedoch führt er die Funktion zum berechnen der Arbeitstage nur einmal aus.
PHP:
#################################################################
### URLAUBE EINTRAGEN
#################################################################
if(isset($_POST['up_sub_u']))
{
 //var_dump($_SESSION);
 $ma_id = $_POST['ma_id'];
 $abt_id = $_POST['abt_id'];
 //  Abfrage ob Ganztag oder Halbtag
 if(isset($_POST['am']))
 {
 $von = date_german2mysql($_POST['am']);
 $bis = date_german2mysql($_POST['am']);
 }else{
 $von = date_german2mysql($_POST['vom']);
 $bis = date_german2mysql($_POST['bis']);
 }
 $grund = $_POST['grund'];
 $freitagenamen_id = $_POST['urlaub'];
 $zeitraum = $_POST['zeitraum'];
 $vertretung = $_POST['vertretung'];
 $urlaubsanschrift = $_POST['urlaubsanschrift'];
 $kommentar = $_POST['kommentar'];
##########################################################################################

######################### FUNKTION ZUM BERECHNEN DER ARBEITSTAGE #########################
function arbeitstage($von,$bis)
{
 
$year = date("Y");
// Feste Feiertage Sachsen-Anhalt
$feiertage[] = "0101"; // Neujahrstag
$feiertage[] = "0601"; // Heilige drei Könige
$feiertage[] = "0105"; // Tag der Arbeit
$feiertage[] = "0310"; // Tag der Deutschen Einheit
$feiertage[] = "3110"; // Reformationstag
$feiertage[] = "2512"; // Erster Weihnachtstag
$feiertage[] = "2612"; // Zweiter Weihnachtstag
// Bewegliche Feiertage berechnen
function get_easter_datetime($year) {
$days = easter_days($year);
return mktime(0, 0, 0, 3, 21+$days,$year);
}
$tage = 86400; //60 * 60 * 24
$ostersonntag = get_easter_datetime($year);
$feiertage[] = date("dm", $ostersonntag - 2 * $tage);  // Karfreitag
$feiertage[] = date("dm", $ostersonntag + 1 * $tage);  // Ostermontag
$feiertage[] = date("dm", $ostersonntag + 39 * $tage); // Himmelfahrt
$feiertage[] = date("dm", $ostersonntag + 50 * $tage); // Pfingstmontag

//Wochenenden des Jahres ausgeben
$prevTime = mktime(0,0,0, 1,1,$year);
$currYear = date ('Y');
$aWeekends = array ();
while(true)
  {
  $prevTime = strtotime ('next saturday' , $prevTime);
  $prevYear = date ('Y' , $prevTime);
  if ($prevYear > $currYear) break;
  $aWeekends[] = date ('dm' , $prevTime);
  $aWeekends[] = date ('dm' , $prevTime + 3600 * 24);
  }
// Array mit den gesamten Tagen aus von und bis bilden
$startdatum = strtotime($von);
$enddatum = strtotime($bis);
while ($startdatum <= $enddatum)
{
 $vonbis[] = date('dm', $startdatum);
 $startdatum += 24 * 60 * 60;
}
// neues array erstellen wo die wochenenden nicht mehr dabei sind
$cleanarraywe = array_diff($vonbis, $aWeekends);
// neues array erstellen wo die Feiertage nicht mehr dabei sind
$cleanarrayft = array_diff($cleanarraywe, $feiertage);

$tage = count($cleanarrayft);
return($tage);

}
################################ ENDE FUNKTION ARBEITSTAGE ###########################################

################################ FUNKTION ZUM EINTRAGEN ##############################################
function Eintragen($ma_id,$abt_id,$freitagenamen_id,$von,$bis,$tage,$zeitraum,$vertretung,$grund,$urlaubsanschrift,$kommentar,$datum_beantragt)
{
 $res = mysql_query("
 INSERT INTO freitage
 (ma_id,abteilungen_id,freitagenamen_id,von,bis,tage,zeitraum,vertretung,grund,urlaubsanschrift,kommentar,datum_beantragt)
 VALUES
 ('$ma_id','$abt_id','$freitagenamen_id','$von','$bis','$tage','$zeitraum','$vertretung','$grund','$urlaubsanschrift','$kommentar',now())
 ") or die("Eintrag fehlgeschlagen.<br><br>".mysql_error());

 $num = mysql_affected_rows();
 if ($num>0){
 $last_id = mysql_insert_id();
 include('up_eintrag_u_view.php');
 // Mail nur versenden wenn admin_mail_notification gesetzt
 if($_SESSION['user_admin_mail_notification'] == 1 ){
 include('up_mail_u_neu.php');
 }
  
  }else{
  echo '<div id="nachricht"><div class="alert alert-danger" role="alert">';
  echo '<strong>Es ist ein Fehler aufgetreten!</strong><br>Der Urlaub konnte nicht erstellt werden.';
  echo '</div></div>';
 }
 
}// ENDE FUNKTION EINTRAGEN
 
 // TEST JAHRESWECHSEL
 $vonjahr = date("Y",strtotime($von));
 $bisjahr = date("Y",strtotime($bis));
 if($bisjahr > $vonjahr){
 echo "Das ist ein Jahreswechsel<br>";
 echo "Eintrag 1 müsste dann vom ".$von. " bis ".$vonjahr."-12-31 gehen<br>";
 echo "Eintrag 2 müsste dann vom ".$bisjahr."-01-01 bis ".$bis." gehen";
 $von1 = $von;
 $von2 = $bisjahr.'-01-01';
 $bis1 = $vonjahr.'-12-31';
 $bis2 = $bis;
 
 var_dump($von1,$bis1,$von2,$bis2);
 
 $tage1 = arbeitstage($von1,$bis1);
 var_dump($tage1);
 Eintragen($ma_id,$abt_id,$freitagenamen_id,$von,"$vonjahr-12-31",$tage1,$zeitraum,$vertretung,$grund,$urlaubsanschrift,$kommentar,$datum_beantragt);
 
 $tage2 = arbeitstage($von2,$bis2);
 var_dump($tage2);
 Eintragen($ma_id,$abt_id,$freitagenamen_id,"$bisjahr-01-01",$bis,$tage2,$zeitraum,$vertretung,$grund,$urlaubsanschrift,$kommentar,$datum_beantragt);
 }else{
 echo "Das ist kein Jahreswechsel<br>";
 echo "Eintrag müsste demnach vom ".$von. " bis ".$bis." gehen<br>";
 $tage = arbeitstage($von,$bis);
 // Wenn nur ein halber Tag ausgewählt setzte $tage auf 0.5
 if(isset($_POST['am'])){
 $tage = 0.5;
 }
 Eintragen($ma_id,$abt_id,$freitagenamen_id,$von,$bis,$tage,$zeitraum,$vertretung,$grund,$urlaubsanschrift,$kommentar,$datum_beantragt);
 }
 
}// ENDE IF SUBMIT
Wenn ich diese Zeile auskommentiere: $tage2 = arbeitstage($von2,$bis2);
dann fügt er mir zwei Datensätze in die DB, beim ersten werden die Tage berechnet beim zweiten logisch nicht. Lasse ich diese Zeile nicht auskommentiert, dann fügt er mir nur einen Datensatz korrekt ein, bricht aber das Script auch danach ab.

Irgendwelche Ideen in Sicht?
 
komischerweise die korrekten Daten.
PHP:
string '2015-12-24' (length=10)

string '2015-12-31' (length=10)

string '2016-01-01' (length=10)

string '2016-01-08' (length=10)

int 5
letzteres ist var_dump($tage1); was ja auch korrekt ist.
Der Eintrag passiert auch noch aber dann bricht das Script ab.
Wenn ich wie schon gesagt $tage2 = arbeitstage($von2,$bis2); auskommentiere bekomme ich beide Datensätze in die DB aber nur zum ersten die Tage dazu.
 

Neue Beiträge

Zurück