Autor Zpráva
H@ck
Profil *
Mám 2 inputy DatumOd (id=nOd), DatumDo (id=nDo)
Do třetího inputu (id=dni) vkládám rozdíl těchto dvou dat (číslo)
Nyní bych potřeboval poradit, zda je možné, aby toto číslo byly pouze pracovní dny.

Př.: Pokud bude první datum páteční a konečné pondělní, tak aby se neobjevilo 4(PA,SO,NE,PO), ale pouze 2(PA,PO).
Neřešil tento problém někdo?
Poradil by někdo?


<script type="text/javascript">

$(function() { 
      $('#nOd').datepicker({onSelect: spoctiRozdil});
      $('#nDo').datepicker({onSelect: spoctiRozdil});  
  
function spoctiRozdil() {
            var d1 = $('#nOd').datepicker('getDate');
            var d2 = $('#nDo').datepicker('getDate');
            var diff = 0;
            if (d1 && d2) {
                  diff = Math.floor((d2.getTime() - d1.getTime()) / 86400000);
            }
            $('#dni').val(diff);
      }
});
</script>
peta
Profil
H@ck:
Neresil. JS ani PHP nezna statni svatky. Kalendar si musis pridat sam a urcit, ktere dny jdou pracovni. Svatky se meni kazdy rok, cislo dne. Nektere maji slozitejsi algoritmy pro vypocet dne, kdy je treba podminkou lichy, sudy tyden :)

init - Udelej si pole se seznamem vsech svatku. Zjisti si pres JS na ktery den ti vychazi. A pokud to neni po-pa, tak ho z pole smaz.
rozdil - Pri tom rozdilu pak musis zjistit, ktere ze zbylych svatku jsou mezi A a B a pak odpocitat tento pocet.
margin
Profil *
peta:
Svatky se meni kazdy rok, cislo dne. Nektere maji slozitejsi algoritmy pro vypocet dne, kdy je treba podminkou lichy, sudy tyden
Všechny naše statní svátky mají pevný termín. Jedinou výjimkou je velikonoční pondělí, ale výpočet data velikonoc se dá vyhledat (pro spoustu programovacích jazyků).
peta
Profil
Jeste bych dodal tento link, aby jsi lepe pochopil, o co bezi s tim vypoctem.
http://cs.wikipedia.org/wiki/V%C3%BDpo%C4%8Det_data_Velikonoc
1Pupik1989
Profil
S výpočtem velikonoc se dá tzv. "Vyčůrat" přes PHP.

<?php
header("Content-type: text/javascript");
echo "function easterDate(){
return '".date("d.m.Y", easter_date()+60*60*24*2)."';
}";
?>

Vrátí 09.04.2012, což je velikonoční pondělí.
Joker
Profil
1Pupik1989:
Záleží na tom, jestli může vybírat data jen v rámci jednoho pevně daného roku. Pokud ne, bude lepší to dělat přes JS (on ten výpočet není zas tak složitý).

peta:
Jak píše margin, všechny svátky krom Velikonočního pondělí mají pevné datum a žádný svátek není závislý na sudém/lichém týdnu.

H@ck:
Záleží i v jak širokém intervalu jde vybírat ta data. Pokud je rok daný relativně napevno, třeba „letos“, je možné si svátky místo počítání uložit do pole, třeba:
svatky = new Array(new Date(2012, 3, 9), new Date(2012, 4, 1), new Date(2012, 4, 8), new Date(2012, 6, 5), new Date(2012, 6, 6), new Date(2012, 8, 28), new Date(2012, 11, 25), new Date(2012, 11, 26));
// svátky připadající na pracovní dny, jen připomínám, že číslování měsíců je 0-11

Sice to není obecné ani moc elegantní, ale vyplnit jeden rok mi zabralo asi půl minuty, takže pro některá použití je možná lepší si naplnit třeba 10 let dopředu, než tam zabudovávat algoritmus určení svátků připadajících na pracovní dny.
1Pupik1989
Profil
No šlo by to teoreticky přes get, přičemž by jedna funkce vracela svátky na celý rok. Schválně to zkusím,pak editnu.

//edit: Tak mi docvaklo, že je to vlastně blbost. Jedině to řešit ajaxem, což je v tomhle případě zbytečné.
H@ck
Profil *
Když mě by stačilo vynechat jen SO a NE. Použil bych tuto funkci, která převádí datum na číslo (den v týdnu 6=SO, 0=NE):
Nějak to projet cyklem a u každého dnu zjistit o jaký se jedná
var jakyDen = testovaneDatum.getDay();



Nevím jak v cyjku k testovanému datumu přičíst X dní:
function spoctiDny() {
            var d1 = $('#nOd').datepicker('getDate');
            var d2 = $('#nDo').datepicker('getDate');
            var diff = 0;
            if (d1 && d2) {
                  diff = Math.floor((d2.getTime() - d1.getTime()) / 86400000)+1;
            }
var pracDni = 0
var pocetDni = diff
var prvniDen = d1.getDay(); 
for (var i=0; i<diff; i++)
{
     var testivaneDatum = prvniDen + i [tady nevím jak přičíst x dni ke dnu v proměné];
     if( testivaneDatum !==6 && testivaneDatum !==0 ) { 
          pracDni +1;
     }
      
      
}
}
H@ck
Profil *
Už to mám:
$(function() { 
      $('#nOd').datepicker({onSelect: spoctiRozdil});
      $('#nDo').datepicker({onSelect: spoctiRozdil});  
  
  function spoctiRozdil() {
            msZaDen = 24*60*60*1000;// počet milisekund za den
            var d1 = $('#nOd').datepicker('getDate');
            var d2 = $('#nDo').datepicker('getDate');
            var pocetDni = 0;
            var pracDni = 0;
            if (d1 && d2) {
                  pocetDni = Math.floor((d2.getTime() - d1.getTime()) / msZaDen)+1;
                                   
                  for (var i=0; i<pocetDni; i++){
                        testovaneDatum = new Date();
                        testovaneDatum.setTime(d1.getTime() + (msZaDen * i));
                        
                        if(testovaneDatum.getDay() !==6 && testovaneDatum.getDay() !==0 ) { 
                        pracDni = pracDni + 1;
                        }
                        $('#dni').val(pracDni);
                  }}}
});
Chamurappi
Profil
Reaguji na H@cka:
Nelíbí. Nešlo by to napsat alespoň trochu chytře? Tedy bez toho cyklu testujícího každý den?
H@ck
Profil *
Nechám se poučit, opravdu nevím
joe
Profil
Chamurappi:
Co třeba zjistit si aktuální den (tím se zjistí za jak dlouho je víkend) a tím si ukládat někam vedle kolikrát ten víkend byl do toho konečného data a nebo víš o jiném lepším postupu? :-)

H@ck:
Krom toho v cyklu vytváříš neustále novou instanci data a jQuery objektu.
H@ck
Profil *
Tak už jsem tu znova, skript je v pohodě, ale jednou počítá správně a jindy ne, např počet prac. dní mezi datumy 1.10. - 10.10 spočítá správně 8 pracovních dní, ale když zvolím 24.10 - 31.10. tak spočítá pouze 5 a správně je 6. Můžu poprosit o radu? Věděl by někdo?
Když jsem ladil, tak jsem zjistil ze se v cyklu, kdy se kontroluje o jaký den se jedná (0=PO až 6=SO) 2x objeví NEDĚLE (0) :-( absolutně to nechápu
$(function() { 
      $('#nOd').datepicker({onSelect: spoctiRozdil});
      $('#nDo').datepicker({onSelect: spoctiRozdil});  
  
  function spoctiRozdil() {
            msZaDen = 86400000;// počet milisekund za den
            var d1 = $('#nOd').datepicker('getDate');
            var d2 = $('#nDo').datepicker('getDate');
            var pocetDni = 0;
            var pracDni = 0;
            if (d1 < d2) {
                  pocetDni = Math.floor((d2.getTime() - d1.getTime()) / msZaDen)+1;
                        $('#kdni').val(pocetDni);                 
                  for (var i=0; i<pocetDni; i++){
                        testovaneDatum = new Date();
                        testovaneDatum.setTime(d1.getTime() + (msZaDen * i));
                        alert(testovaneDatum.getDay());
                        if(testovaneDatum.getDay() !==6 && testovaneDatum.getDay() !==0 ) { 
                        pracDni = pracDni + 1;
                        }
                        $('#pdni').val(pracDni);
                        
                  }}else{
                        $('#kdni').val('1');
                        $('#pdni').val('1');
                  }
                  
                  }

});
Joker
Profil
H@ck:
Nestudoval jsem kód, ale tipnu příčinu problému:
Nebude to tím, že neděle 28.10. je zároveň státní svátek a skript ji odečte dvakrát?

Ještě poznámka: Jak už psal před půl rokem Chamurappi, procházet den po dni je zbytečné. Dny jdou přece za sebou v daném pořadí, takže k určení počtu víkendů stačí jen dvě informace: Počet dní a který den v týdnu byl první den daného intervalu (resp. to nemusí nezbytně být zrovna první den).
Kajman
Profil
Také by to mohlo být tím, že ona neděle 28.10. má jen 23 hodin a floor to zaokrouhlí na nula dnů. Zkuste Math.round.
H@ck
Profil *
Math.round
Nepomohlo


Moc rád bych použil to co píše Chamurappi, ale nevím jak na to :-(
Kajman
Profil
Napsal jsem to chybně. 28. 10. má letos 25 hodin, proto při přičítání 24 hodin na řádku 16 můžete dostat neděli dvakrát.

Co třeba počet dnů vydělit 7 a vzniklé celé číslo vynásobit 5. Pak jen dořešit zbytek porovnáním dne v týdnu počátku a konce intervalu?
1Pupik1989
Profil
Bez cyklu to jde, akorát u svátků nejspíš bude muset být. Nebo mě nenapadá jiné řešení.
H@ck
Profil *
Aha, takže to vlastně vše bude fungovat jen ne ve dny kdy se mění čas. Na ten bez cyklový způsob asi nepříjdu.
1Pupik1989
Profil
Cyklový je jednoduchý. U bezcyklového se musí stejně ale řešit ty svátky cyklem. Už je to ale jen pár hodnot oproti celku.

Další věc je nevytvářet nový Date objekt v cyklu. Lepší je prostě přičíst datum.
H@ck
Profil *
O svátky mi ani tak nejde.
1Pupik1989
Profil
Spočítal jsem první týden, což je třeba 1. - 5. 10. a ze zbytku jsem odečetl počet týdnů * 2, což jsou víkendy.

Krom toho ještě přenastavuji první datum, aby to nebyla sobota či neděle.

Vaše odpověď

Mohlo by se hodit

Neumíte-li správně určit příčinu chyby, vkládejte odkazy na živé ukázky.
Užíváte-li nějakou cizí knihovnu, ukažte odpovídajícím, kde jste ji vzali.

Užitečné odkazy:

Odkud se sem odkazuje


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm:

0