Dokumenty > Algorytm wyliczania elementów typu Lata, Miesiące, Dni

Drukuj

Algorytm wyliczania elementów typu Lata, Miesiące, Dni

Algorytm liczenia LMD dla pojedynczego okresu

Algorytm wyznaczania liczby lat, miesięcy i dni jest dość złożony ze względu na nieregularność kalendarza. Podczas obliczeń trzeba uwzględnić fakt, że:

Sąsiadujące miesiące mogą mieć różną długość (np. sierpień, wrzesień).

Ten sam miesiąc może mieć różną długość w różnych latach (luty).

 

Z tego względu nie da się obliczyć LMD, jako prostej różnicy lat, miesięcy i dni, wziętych z dat końcowej i początkowej. Zastosowano algorytm kolejnych przybliżeń. Polega on na obliczeniu przybliżonej wartości LMD  a następnie znalezieniu wartości dokładnej poprzez inkrementację lub dekrementację LMD w przedziale kilku dni.

 

Krok 1 - Różnica pomiędzy datą końcową a początkową

Podstawą obliczenia wartości LMD jest okres od ustalonej daty początkowej (POC) do ustalonej daty końcowej (KON) włącznie. W pierwszym kroku od daty końcowej odejmujemy datę początkową, następnie otrzymany wynik powiększamy o 1 dzień. Ta ostatnia operacja wynika z założenia, że analizowany okres czasu jest przedziałem domkniętym tj. zawiera zarówno datę początkową jak i końcową.

 

Na przykład, okres od 2011-03-01 do 2011-03-01 trwa 1 dzień, okres od 2011-03-01 do 2011-03-02 trwa 2 dni itd.

 

dok_LMD_01

 

Obliczając różnicę pomiędzy datą końcową a początkową oddzielnie odejmujemy lata, oddzielnie miesiące i oddzielnie dni. Tak więc wartością LMD jest trójka liczb (L; M; D) oznaczająca kolejno lata, miesiące i dni.

 

dok_LMD_02

 

Przykład 1

Okres od 2011-05-01 do 2011-05-01 trwa 1 dzień.

LMD = (2011-2011; 5-5; 1-1) + 1 dzień

LMD = (0; 0; 0) + 1 dzień

LMD = (0; 0; 1)

 

Przykład 2

Okres od 2011-05-01 do 2011-05-05 trwa 5 dni.

LMD = (2011-2011; 5-5; 5-1) + 1 dzień

LMD = (0; 0; 4) + 1 dzień

LMD = (0; 0; 5)

 

Jeżeli wynikiem obliczeń jest wartość (L; M; 30) + 1 dzień, to nie wiemy czy mamy powiększyć liczbę dni do 31, czy też zwiększyć liczbę miesięcy do M + 1 a liczbę dni ustawić na 1. Drobna modyfikacja wzoru na obliczanie LMD pozwoli uniknąć tej wątpliwości. Zamiast dodawać 1 dzień do wynikowego LMD będziemy dodawać jeden dzień do daty końcowej:

 

dok_LMD_03

 

Przykład 3

Okres od 2011-05-01 do 2011-05-05 trwa 5 dni.

LMD = (2011-05-05 + 1 dzień) - 2011-05-01

LMD = (2011-2011; 5-5; 6-1)

LMD = (0; 0; 5)

 

Krok 2 - Normalizacja liczby miesięcy

Celem kolejnych kroków algorytmu jest normalizacja liczby miesięcy i dni. Zauważmy, że jeśli miesiąc w dacie końcowej jest mniejszy od miesiąca w dacie początkowej, to w wyniku otrzymamy ujemną liczbę miesięcy. Podobnie, jeśli dzień w dacie końcowej jest mniejszy od dnia w dacie początkowej, to w wyniku otrzymamy ujemną liczbę dni.

 

Przykład 4

Okres od 2010-12-20 do 2011-01-19.

LMD = (2011-2010; 01-12; 20-20) = (1; -11; 0)

 

Normalizacja ujemnej liczby miesięcy jest prosta: należy pożyczyć 12 miesięcy z pozycji reprezentującej lata tj. do ujemnej liczby miesięcy dodać 12, jednocześnie od liczby lat odjąć 1.

 

Przykład 5

Okres od 2010-12-20 do 2011-01-19.

LMD = (2011-2010; 01-12; 20-20)

LMD = (1; -11; 0)

LMD = (1-1; -11+12; 0)

LMD = (0; 1; 0)

 

W rezultacie wartość LMD dla okresu od 2010-12-20 do 2011-01-19 włącznie jest równa 1 miesiąc.

 

Krok 3 - Normalizacja liczby dni

Normalizacja liczby dni jest o wiele trudniejsza, gdyż trzeba uwzględnić wspomnianą nieregularność kalendarza. Przybliżoną liczbę dni dla LMD wyznaczamy, jako różnicę pomiędzy datą końcową KON a pomocniczą data AUX, którą uzyskamy poprzez przesunięcie daty początkowej POC o liczbę lat i miesięcy LMD0 = (L; M; 0) wyznaczoną w krokach 1 i 2:

 

dok_LMD_04

 

dok_LMD_05

 

dok_LMD_06

 

Przykład 6

Okres od 2010-12-15 do 2011-01-20.

 

AUX = 2010-12-15 + (2011-2010; 01-12; 0)

AUX = 2010-12-15 + (1; -11; 0)

AUX = 2010-12-15 + (1-1; -11+12; 0)

AUX = 2010-12-15 + (0; 1; 0)

AUX = 2011-01-15

 

∆ = (2011-01-20 + 1 dzień) – 2011-01-15

∆ = 2011-01-21 – 2011-01-15

∆ = 6 dni

 

LMD = (0; 1; 6)

 

Z powodu nieregularności kalendarza, data AUX uzyskana w wyniku prostego dodawania miesięcy i lat może być niepoprawna. Na przykład jeżeli do daty POC = 2011-01-30 dodamy 1 miesiąc czyli LMD(0;1;0), otrzymamy datę AUX = 2011-02-30, która w rzeczywistości nie istnieje. W celu uniknięcia takiej sytuacji zastosowano następującą modyfikację: zamiast daty POC przesuwany jest początek miesiąca POCPM, w wyniku czego otrzymujemy zawsze poprawną datę AUXPM.

 

dok_LMD_07

 

Przykład 7

POC = 2011-01-31  oraz  LMD0 = (0;1;0)

AUX = 2011-01-31 + (0;1;0) = 2011-02-31  /* data niepoprawna */

POCPM = 2011-01-01                        /* początek miesiąca */

AUXPM = 2011-01-01 + (0;1;0) = 2011-02-01 /* data poprawna */

AUXKM = 2011-02-28                        /* koniec miesiąca */

 

Po obliczeniu daty początku miesiąca AUXPM wyznaczamy datę końca tego miesiąca AUXKM. Pomocniczy dzień miesiąca AUX obliczamy względem początku lub końca miesiąca, w taki sposób, by był on datą formalnie poprawną i zgodną z intuicją. Odległość daty AUX od wybranego końca AUXPM lub AUXKM powinna odpowiadać odległości daty początkowej POC od POCPM lub POCKM.

 

Jeżeli data początkowa POC jest blisko daty końca miesiąca POCKM (np. POCKM – POC < 15), wówczas dzień miesiąca dla AUX jest liczony względem końca miesiąca AUXKM:

 

dok_LMD_08

 

dok_LMD_09

 

Przykład 8

POC = 2011-01-25  oraz  LMD0 = (0;1;0)

Data POC jest blisko daty końca miesiąca POCKM = 2011-01-31

 

∆ = POCKM – POC = 2011-01-31 - 2011-01-25 = 6    /* nie trzeba dodawać 1 dnia */

AUXPM = 2011-01-01 + (0;1;0) = 2011-02-01        /* początek miesiąca */

AUXKM = 2011-02-28                               /* koniec miesiąca */

AUX = AUXKM – 6 = 2011-02-22

 

Jeżeli data początkowa POC jest bliżej daty początkowej miesiąca POCPM (np. POCKM – POC > 15), wówczas dzień miesiąca dla AUX jest liczony względem początku miesiąca AUXPM:

 

dok_LMD_10

 

dok_LMD_11

 

Przykład 9

POC = 2011-01-03  oraz  LMD0 = (0;1;0)

Data POC jest blisko daty początku miesiąca POCPM = 2011-01-01

 

∆ = POC – POCPM = 2011-01-03 - 2011-01-01 = 2    /* nie trzeba dodawać 1 dnia */

AUXPM = 2011-01-01 + (0;1;0) = 2011-02-01        /* początek miesiąca */

AUX = AUXPM + 2 = 2011-02-03

 

Po wyznaczeniu daty pomocniczej AUX możemy obliczyć przybliżoną wartość LMD według wzorów podanych na początku rozdziału.

 

Przykład 10

POC = 2011-01-25      /* data początkowa blisko końca miesiąca */

KON = 2011-02-27

AUX = 2011-02-22      /* wartość z przykładu 1.3.3 */

 

∆ = (KON + 1) – AUX

∆ = 2011-02-28 - 2011-02-22 = 6 dni

 

LMD = (0;1;6)         /* przybliżona wartość LMD */

 

Przykład 11

POC = 2011-01-03      /* data początkowa blisko początku miesiąca */

KON = 2011-02-27

AUX = 2011-02-03      /* wartość z przykładu 1.3.4 */

 

∆ = (KON + 1) – AUX

∆ = 2011-02-28 - 2011-02-03 = 25 dni

 

LMD = (0;1;25)        /* przybliżona wartość LMD */

 

Krok 4 - Wyznaczenie dokładnej wartości LMD

Należy pamiętać, że wartość LMD wyliczona w poprzednich krokach algorytmu jest wartością przybliżoną i może zawierać niewielki błąd. Wynika to – jak już wspomniano – z nieregularności kalendarza. Wartość dokładną obliczamy poprzez krokowe powiększanie lub zmniejszanie LMD o 1 dzień według poniższego algorytmu:

 

1.Mamy okres od daty POC do daty KON oraz wyliczoną przybliżoną wartość LMD.

2.Jeżeli POC + LMD > KON to zmniejszamy LMD o 1 dzień i powtarzamy krok 2;
w przeciwnym wypadku idziemy do kroku 3.

3.Jeżeli POC + LMD < KON to zwiększamy LMD o 1 dzień i powtarzamy krok 3;
w przeciwnym wypadku idziemy do kroku 4.

4.Koniec: obliczono dokładną wartość LMD.

 

Przykład 12

POC = 2011-01-25      /* data początkowa blisko końca miesiąca */

KON = 2011-02-27

LMD = (0;1;6)         /* przybliżona wartość LMD z przykładu 10 */

 

POC + LMD = 2011-01-25 + (0;1;6) = 2011-01-24 + 6 dni = 2011-03-02

Data KON < 2011-03-02, więc krokowo zmniejszamy LMD,

aż do chwili gdy POC + LMD = KON.

 

Ostatecznie, dokładna wartość LMD = (0;1;3)

 

Przykład 13

POC = 2011-01-03      /* data początkowa blisko początku miesiąca */

KON = 2011-02-27

LMD = (0;1;25)        /* przybliżona wartość LMD z przykładu 11 */

 

POC + LMD = 2011-01-03 + (0;1;25) = 2011-01-02 + 25 dni = 2011-01-27

Data KON = 2011-01-27 więc nie trzeba modyfikować LMD.

 

Ostatecznie, dokładna wartość LMD = (0;1;25)

 

Sumowanie okresów podczas wyznaczania stażu pracy

W poprzedniej części dokumentu opisano sposób wyliczania wartości LMD dla pojedynczych okresów. Teraz zostanie opisany sposób sumowania wielu wartości LMD (reprezentujących wiele okresów) podczas obliczania stażu pracy.

 

Krok 1 - Sumowanie okresów zatrudnienia

Pierwszym krokiem podczas wyliczania stażu jest zsumowanie wartości LMD dla wszystkich okresów zatrudnienia. Sumę LMD dla dwóch kolejnych okresów obliczamy następująco.

 

Załóżmy, że mamy okresy A = (POCA; KONA) oraz B = (POCB; KONB). Jeżeli pomiędzy okresami A i B jest przerwa w pracy (KONA < POCB) to przesuwamy okres A w kierunku okresu B w taki sposób, aby nie zmienić wartości LMDA dla okresu A oraz aby po przesunięciu końce okresów sąsiadowały ze sobą, konkretnie aby  KONA + 1 = POCB.

 

dok_LMD_12

 

 

Następnie obliczamy sumaryczne LMDA+B dla okresu od przesuniętej daty POCA2 do oryginalnej daty KONB. Jeżeli pomiędzy okresami A i B nie ma przerwy, to obliczenie sumarycznego LMDA+B jest proste. Wystarczy wyznaczyć zwykłe LMD dla okresu od daty oryginalnej POCA do oryginalnej daty KONB.

 

Krok 2 - Uwzględnienie stażu nauki

Jeżeli staż wynikający z okresów nauki jest korzystniejszy, to uwzględniamy go.