Računala Windows Internet

Koliko dana u mjesecu svibnju. Određivanje broja dana u mjesecu u programu Microsoft Excel. Izračunavanje broja dana između datuma

Nedavno sam, nakon dugo vremena provedenog bez sna, razmišljao o tome kako možete saznati broj dana u mjesecu, znajući njegov broj. Postoje dječje pjesme na ovu temu, postoji način brojanja po zglobovima, ali ove metode mi ne odgovaraju - uronio sam u potragu za matematičkom formulom, koju sam nakon nekog vremena izveo.

Dakle zadatak

Formalno Drugim riječima, trebamo dobiti funkciju f (x) koja bi dala sljedeću listu vrijednosti (koju sam, usput rečeno, našao negdje na internetu, a nisam je zaključio koristeći mnemonička pravila):

Treba napomenuti da kao argument primamo samo broj mjeseca, t.j. ne brojimo prijestupne godine, i f (2) = 28.

Ako želite znati rezultat koji sam dobio, pomaknite se do dna ove stranice. Ono što će biti opisano u nastavku je izvođenje željene formule.

Što ćemo koristiti

Uz zbrajanje, oduzimanje i množenje, koristit ću dvije operacije: cjelobrojno dijeljenje i ostatak. Da vas podsjetim o čemu se radi:

  • Cjelobrojna podjela, ili "podjela i zaokruživanje prema dolje". Predstavit ću to kao uobičajenu podjelu: a / b - što znači ⌊a / b⌋. Na primjer, 5/3 = 1.
  • Uzimajući ostatak po modulu... Označit ću tradicionalnu podjelu ostatkom: a% b = a - (a / b) * b. Na primjer, 5% 3 = 2.

Imaju isti prioritet i lijevo su asocijativni.

Osnove ili pravilo s mnogo iznimaka

Pokušajmo pronaći takav obrazac koji bi zadovoljio što više vrijednosti argumenta. Obično se broj dana u mjesecu kreće između 30 i 31. Istovremeno, možete primijetiti ovisnost ovog broja o paritetu mjeseca - pa ćemo koristiti operaciju uzimanja ostatka po modulu 2. To čini se da bi trebalo biti nešto poput:

f₁ (x) = 30 + x% 2


Lijep početak! Bez obzira na veljaču, koja će očito morati ići na neke trikove, budimo sretni što smo uspjeli prilagoditi funkciju za prvu polovicu godine. A onda, počevši od kolovoza, paritet se mora promijeniti u suprotno. To se može učiniti zamjenom x% 2 u prvoj verziji formule na (x + 1)% 2:

f₂ (x) = 30 + (x + 1)% 2


Očekivano, sada je prva polovica godine već izvan raspona točnih vrijednosti, no mjeseci od kolovoza do prosinca dali su ono što nam treba. Nađimo način da spojimo ova dva dijela.

Maska

Trebamo +1 u dividendi da se "aktivira" samo kada argument dosegne vrijednosti veće od 8, tj. moramo nanijeti neku masku. U ovom slučaju vrijednosti argumenta ne mogu prelaziti 12. Stoga je za nas idealna cjelobrojna podjela argumenta s 8:


Točno onako kako nam treba. Poslužimo se ovim zaključkom:

f₃ (x) = 30 + (x + x / 8)% 2


Vau! Sve je točno, osim veljače. Kako neočekivano.

veljača

Svi mjeseci imaju 30 ili 31 dan, u veljači - 28 (zapamtite, ne smatramo prijestupne godine).

Povijesna referenca: u rimskom kalendaru veljača je bila posljednji mjesec u godini - morate priznati da je dodavanje jednog dana u prijestupnoj godini na kraj kalendara intuitivnije. No, mi koristimo gregorijanski kalendar, u kojem se najkraći mjesec voljom jednog od mudrih vladara pomiče bliže početku.

U većini Najnovija verzija naša formula je dobila 30 dana u veljači. Stoga mu trebamo odsjeći par dana. Naravno, još će nekoliko mjeseci patiti od toga: ili lijevo od veljače, ili desno od nje na našem popisu - međutim, ima mnogo manje mjeseci desno, pa ćemo morati žrtvovati siječanj, a zatim prilagoditi formulu za to. Pomoću izraza možete odrezati dane za prvi i drugi mjesec 2% x.

Bilješka: ovaj post je prijevod članka cmcenroe.me/2014/12/05/days-in-month-formula.html ( dio I), kao i autorov dodatak njemu ( Dio II). Ne biste trebali shvaćati gradivo ozbiljno, već radije kao zagrijavanje uma, koje ne zahtijeva ništa više od školskog znanja aritmetike i nema praktičnu primjenu. Sretno čitanje, svima!

dio I

Uvod

Nedavno, nakon još jedne neprospavane noći, razmišljao sam o metodama pamćenja broja dana u svakom mjesecu u godini. Za to postoji stroj za brojanje, kao i način računanja na zglobove, ali meni ni jedno ni drugo nije odgovaralo. Pitao sam se postoji li neka vrsta matematičke formule za rješavanje takvog problema, i - ne pronašavši je na površnoj studiji - izazvao sam sebe da je stvorim.

Formaliziranje Drugim riječima, potrebno je pronaći funkciju f tako da vrijednost f (x) za svaki mjesec x, predstavljen brojem između 1 i 12, jednak je broju dana u tom mjesecu. Tablica vrijednosti argumenata i funkcija:

x 1 2 3 4 5 6 7 8 9 10 11 12
f (x) 31 28 31 30 31 30 31 31 30 31 30 31

Ako imate želju isprobati ga i sami prije nego što pročitate moje rješenje, sada je pravo vrijeme. Ako više volite odmah vidjeti gotov odgovor, pogledajte ispod spojlera.

Odgovor


U nastavku su moji koraci za pronalaženje rješenja.

Matematički aparat

Prvo, osvježimo brzo pamćenje na dva vitalna operatora u rješavanju ovog problema: cjelobrojno dijeljenje i ostatak dijeljenja.

Cjelobrojna podjela to je operator koji se koristi u mnogim programskim jezicima kada se dijele dva cijela broja i odbacuje razlomak iz kvocijenta. Ja ću ga prikazati kao. Na primjer:

Ostatak divizije to je operator koji pronalazi ostatak dijeljenja. Mnogi programski jezici koriste simbol % , ali koristit ću konstrukcije oblika, na primjer:

Imajte na umu da ostatak podjele ima isti prioritet kao i podjela.

Osnove

Dakle, primijenimo naš matematički aparat da dobijemo osnovnu formulu. U tipičnom mjesecu ima 30 ili 31 dan, tako da možemo koristiti 1 ili 0 da dobijemo naizmjenično, a zatim ovom broju samo dodati konstantu:

Dobivamo tablicu, ispravne vrijednosti su podebljane:
x 1 2 3 4 5 6 7 8 9 10 11 12
f (x) 31 30 31 30 31 30 31 30 31 30 31 30

Lijep početak! Već postoje točne vrijednosti za siječanj i za mjesece od ožujka do uključujući srpanj. Veljača je poseban slučaj, a njime ćemo se pozabaviti nešto kasnije. Nakon srpnja, za preostale mjesece, redoslijed dobivanja 0 i 1 mora se obrnuti.
Da bismo to učinili, dividendi možemo dodati 1:

x 1 2 3 4 5 6 7 8 9 10 11 12
f (x) 30 31 30 31 30 31 30 31 30 31 30 31

Sada su točne vrijednosti od kolovoza do prosinca, ali očekivano, vrijednosti za ostale mjesece nisu točne. Pogledajmo kako možemo kombinirati ove formule.

Prekrivanje maske

Za to je potrebna djelićno definirana funkcija, ali - budući da mi se činilo dosadnim - razmišljao sam o drugom rješenju, koristeći jedan dio funkcije na jednom intervalu, drugi na drugom.
Mislim da je najlakše pronaći izraz koji je jednak 1 u jednoj aplikaciji i 0 u ostatku. Metodu u kojoj, množenjem argumenta s izrazom, izuzimamo ga iz formule izvan njegovog opsega, nazvao sam "maskiranje", jer je to ponašanje slično nekoj vrsti bit maske.
Da biste koristili ovu metodu u posljednjem dijelu naše funkcije, trebate pronaći izraz jednak 1 za, a - budući da su vrijednosti argumenata uvijek manje od 16 - za to je u redu cjelobrojno dijeljenje s 8.
x 1 2 3 4 5 6 7 8 9 10 11 12
x ⁄ 8 ⌋ 0 0 0 0 0 0 0 1 1 1 1 1

Sada, koristeći ovu masku, koristeći izraz umjesto 1 u dividendi, možemo zamijeniti redoslijed dobivanja 0 i 1 u formuli suprotnim:

x 1 2 3 4 5 6 7 8 9 10 11 12
f (x) 31 30 31 30 31 30 31 31 30 31 30 31

Eureka! Sve je točno, osim veljače. Iznenađenje iznenađenje.

veljača

Svaki mjesec ima 30 ili 31 dan, osim veljače sa svojim 28. (prijestupna godina je izvan okvira ovog problema). Trenutno, prema našoj formuli, ima 30 dana, pa bi bilo lijepo oduzeti izraz jednak 2 at.
Najbolje što sam smislio je ovo, koje maskira sve mjesece nakon veljače:
x 1 2 3 4 5 6 7 8 9 10 11 12
2 mod x 0 0 2 2 2 2 2 2 2 2 2 2

Mijenjajući osnovnu konstantu na 28, dodajući 2 ostatku mjeseci, dobivamo formulu:

x 1 2 3 4 5 6 7 8 9 10 11 12
f (x) 29 28 31 30 31 30 31 31 30 31 30 31

Nažalost, siječanj je sada 2 dana kraći. Srećom, lako je dobiti izraz koji vrijedi samo za prvi mjesec: to je obrnut broj zaokružen prema dolje. Množenjem s 2 dobivamo konačnu formulu:

x 1 2 3 4 5 6 7 8 9 10 11 12
f (x) 31 28 31 30 31 30 31 31 30 31 30 31

Pogovor

Evo je - formula za dobivanje broja dana u bilo kojem mjesecu u godini pomoću jednostavne aritmetike. Sljedeći put kada razmislite o tome koliko je dana u rujnu, jednostavno učinite ovo pomoću ove jednorečne JavaScript funkcije:

Funkcija f (x) (povrat 28 + (x + Math.floor (x / 8))% 2 + 2% x + 2 * Math.floor (1 / x);)

Dio II

Uvod

U prvom dijelu dobivena je kratka i čak pomalo elegantna formula čije su glavne prednosti jednostavnost matematičkog aparata, odsutnost grana i uvjetnih izraza te lakonizam. Nedostaci - osim činjenice da ga nećete koristiti u svom projektu - uključuju nedostatak provjere za viscoco i neprijestupne godine.
Stoga sam si postavio zadatak kreirati funkciju f tako da vrijednost f (x, y) za svaki mjesec x predstavljeno brojem od 1 do 12 i godinom y veći od 0 jednako je broju dana u mjesecu x u godini y.
Za nestrpljive ispod spojlera je gotov odgovor, dok se ostali mole da me prate.

Odgovor

Ostatak podjele: mod i ⌊⌋

Radi vizualne jasnoće, dogovorimo se da je u nekim formulama operator dijeljenja s ostatkom zamijenjen nižim zagradama, gdje mi se činilo potrebnim:

Prijestupna godina

U prijestupnoj godini uvodi se dodatni kalendarski dan: 29. veljače. Kao što znate, prijestupna godina je višekratnik 4, a ne višekratnik 100, ili višekratnik 400. Napišimo izraz identičan ovoj izjavi:

Za pretvaranje ovog izraza u algebarski, potrebno je primijeniti injekciju oblika na rezultat izraza:

Što će vam omogućiti da dobijete 1 pri dijeljenju bez ostatka i 0 pri dijeljenju s ostatkom, kako biste ga koristili u formuli za određivanje broja dana u mjesecu.

Kao funkcija g " možete koristiti 1 minus ostatak za:

x 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
g "(x) Beskonačnost 1 0 0 0 0 0 0 0 0 0 0 0 0 0

Lako je vidjeti da povećanjem dividende i djelitelja za 1 dobivamo ispravnu formulu za:
x 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
g "(x) 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0

Dakle, izraz će biti napisan kao:


I zapisujemo izraz kao:

Primjenom ovog pristupa dobivamo sljedeću funkciju g (y), čija će vrijednost biti 1 ako je godina prijestupna, ili 0 u suprotnom:

y 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000
g (y) 0 0 1 0 0 0 1 0 0 0 1
y 2000 2100 2200 2300 2400 2500 2600 2700 2800 2900 3000
g (y) 1 0 0 0 1 0 0 0 1 0 0

Prijestupne godine su podebljane.

Podsjećam da se u okviru prihvaćenog sporazuma operater za dobivanje ostatka podjele može prikazati kao mod i ⌊⌋.

Prekrivanje maske

U formuli, dio je amandman koji dodaje 2 dana do siječnja. Ako uklonimo faktor 2 i zamijenimo 1 s 2 u brojniku, tada će ova formula dodati 2 dana siječnju i 1 dan veljači, što nam daje ključ za dodavanje dana u prijestupnoj godini. Radi jasnoće koristimo srednju vrijednost u formuli g (y) i kao y koristimo 2000 (prijestupnu) i 2001 (neprijestupnu) godinu:

x 1 2 3 4 5 6 7 8 9 10 11 12
f (x, 2000) 31 29 31 30 31 30 31 31 30 31 30 31
f (x, 2001.) 30 28 31 30 31 30 31 31 30 31 30 30

Vrijednosti za sve mjesece osim siječnja neprestupne godine su točne.

Da biste ispravili ovaj dosadni nesporazum, dodajte 1 dan siječnju s formulom koju već poznajemo:


Ili:

x 1 2 3 4 5 6 7 8 9 10 11 12
f (x, 2000) 31 29 31 30 31 30 31 31 30 31 30 31
f (x, 2001.) 31 28 31 30 31 30 31 31 30 31 30 30

Zaključak

Kao rezultat, dobiva se mnogo glomaznija, ali univerzalnija formula, koja se također može koristiti za dobivanje broja dana u mjesecu određene godine:

Funkcija f (x, y) (povrat 28 + ((x + Math.floor (x / 8))% 2) + 2% x + Math.floor ((1 + (1 - (y% 4 + 2)% (y% 4 + 1)) * ((y% 100 + 2)% (y% 100 + 1)) + (1 - (y% 400 + 2)% (y% 400 + 1))) / x) + Matematički pod (1 / x) - Matematički pod (((1 - (y% 4 + 2)% (y% 4 + 1)) * ((y% 100 + 2)% (y% 100 + 1 )) + (1 - (y% 400 + 2)% (y% 400 + 1))) / x;)
Primjer u C # ideone.com/fANutz.

1 ... Ne znam koristiti takvu mnemotehniku, pa sam špijunirao znak na internetu.
2 ... "Osnove" ili "Pravilo s mnogo iznimaka", kao i većina pravila.
3 ... U početku je veljača bila posljednji mjesec u rimskom kalendaru, pa postoji logika da je kraća od svih ostalih. Logično je i dodavanje ili uklanjanje dana na kraju godine, pa je njegova duljina promjenjiva.

Upd. 1:
Alternativni prijevod prvog dijela u

Da biste riješili neke probleme pri izradi tablice, morate odrediti broj dana u mjesecu u zasebnoj ćeliji ili unutar formule kako bi program mogao izvršiti potrebne izračune. Excel ima alate za izvođenje ove operacije. razmotrimo različiti putevi primjena ove prilike.

Možete izračunati broj dana u mjesecu u Excelu koristeći posebne operatore kategorije "Datum i vrijeme"... Da biste saznali koju opciju je najbolje primijeniti, prvo morate utvrditi ciljeve operacije. Ovisno o tome, rezultat izračuna može se prikazati u zasebnom elementu na listu ili se može koristiti unutar druge formule.

Metoda 1: kombinacija DAY i EONMONTH operatora

Najviše na jednostavan način za rješavanje ovog problema kombinacija je operatora DAN i OD EONTA.

Funkcija DAN pripada skupini operatora "Datum i vrijeme"... Ona pokazuje na određeni broj iz 1 prije 31 ... U našem slučaju, zadatak ovog operatera bit će naznačiti zadnji dan mjeseci koristeći ugrađenu funkciju kao argument OD EONTA.

Sintaksa operatora DAN Sljedeći:

DAN (format_broj_datuma)

To jest, jedini argument ove funkcije je "Datum u numeričkom formatu"... Postavit će ga operater OD EONTA... Mora se reći da se datum u numeričkom formatu razlikuje od uobičajenog formata. Na primjer, datum 04.05.2017 brojčano će izgledati 42859 ... Stoga Excel koristi ovaj format samo za interne operacije. Rijetko se koristi za prikaz u ćelijama.

Operater OD EONTA namijenjen je označavanju rednog broja posljednjeg dana u mjesecu, a to je određeni broj mjeseci unaprijed ili unatrag od navedenog datuma. Sintaksa funkcije je sljedeća:

EON MONTHS (datum_početka, broj_mjeseci)

Operater "Početni datum" sadrži datum od kojeg se vrši odbrojavanje ili referencu na ćeliju u kojoj se nalazi.

Operater "Broj mjeseci" označava broj mjeseci od određenog datuma.

Pogledajmo sada kako to funkcionira na konkretnom primjeru. Da bismo to učinili, uzmimo Excel list, u jednoj od ćelija u kojem je upisan određeni kalendarski broj. Potrebno je, koristeći gornji skup operatora, odrediti koliko dana ima mjesečno razdoblje na koje se ovaj broj odnosi.


Naša opća formula dobila je sljedeći oblik:

DAN (SJEDINJENE (B3,0))

U ovoj formuli vrijednost varijable je samo adresa ćelije ( B3). Dakle, ako ne želite izvršiti proceduru s Čarobnjaci za funkcije, možete umetnuti ovu formulu u bilo koji element lista jednostavnim zamjenom adrese ćelije koja sadrži broj onom koja je relevantna u vašem konkretnom slučaju. Rezultat će biti sličan.

Metoda 2: automatsko određivanje broja dana

Pogledajmo sada drugi problem. Potrebno je da se broj dana ne prikazuje prema zadanom kalendarskom datumu, već prema trenutnom. Osim toga, promjena razdoblja bi se izvršila automatski bez intervencije korisnika. Iako se čini čudnim, ovaj zadatak je lakši od prethodnog. Da se to riješi, čak i otvori Čarobnjak za funkcije nepotrebno jer formula koja izvodi ovu operaciju ne sadrži varijabilne vrijednosti ili reference ćelije. Možete jednostavno ubaciti sljedeću formulu u ćeliju lista gdje želite da se rezultat prikaže bez promjena:

DAN (E-MJESECI (DANAS (); 0))

Ugrađena funkcija TODAY koju smo koristili u ovom slučaju prikazuje današnji broj i nema argumente. Tako će vaša ćelija stalno prikazivati ​​broj dana u tekućem mjesecu.

Metoda 3: izračunavanje broja dana za korištenje u složenim formulama

U gornjim primjerima pokazali smo kako izračunati broj dana u mjesecu za određeni kalendarski datum ili automatski za tekući mjesec s izlazom rezultata u zasebnoj ćeliji. Ali pronalaženje ove vrijednosti može biti potrebno i za izračunavanje drugih pokazatelja. U tom slučaju, izračun broja dana izvršit će se unutar složene formule i neće biti prikazan u zasebnoj ćeliji. Pogledajmo kako to učiniti na primjeru.

Moramo učiniti da ćelija prikazuje broj dana koji je ostao do kraja tekućeg mjeseca. Kao iu prethodnoj metodi, ova opcija ne zahtijeva otvaranje Čarobnjaci za funkcije... Možete jednostavno upisati sljedeći izraz u ćeliju:

DAN (E-MJESECI (DANAS (); 0)) - DAN (DANAS ())

Nakon toga će se u navedenoj ćeliji prikazati broj dana do kraja mjeseca. Svaki dan rezultat će se automatski ažurirati, a od početka novog razdoblja odbrojavanje će početi ispočetka. Ispada neka vrsta odbrojavanja vremena.

Kao što vidite, ova formula se sastoji od dva dijela. Prvi od njih je već poznati izraz za izračun broja dana u mjesecu:

DAN (E-MJESECI (DANAS (); 0))

Ali u drugom dijelu, današnji broj se oduzima od ovog pokazatelja:

DAN ZA DANOM ())

Dakle, pri izvođenju ovog izračuna formula za izračun broja dana dio je složenije formule.

Metoda 4: alternativna formula

Ali, nažalost, verzije programa ranije od Excela 2007 nemaju operatora OD EONTA... Što je s onim korisnicima koji koriste stare verzije aplikacije? Za njih ova prilika postoji kroz drugu formulu, koja je masovnija od gore opisane. Pogledajmo kako izračunati broj dana u mjesecu za određeni kalendarski datum pomoću ove opcije.

  1. Odaberite ćeliju za prikaz rezultata i idite na prozor s argumentima operatora DAN na nama već poznat način. Postavite pokazivač u jedino polje ovog prozora i kliknite na obrnuti trokut lijevo od trake formule. Idite na odjeljak "Druge funkcije...".
  2. U prozoru Čarobnjaci za funkcije u grupi "Datum i vrijeme" označite ime "DATUM" i kliknite na gumb "U REDU".
  3. Pokreće se prozor operatera DATUM. Ova funkcija pretvara datum iz uobičajenog formata u numeričku vrijednost, koju će operater tada morati obraditi DAN.

    Prozor koji se otvori ima tri polja. U polju "Dan" možete odmah unijeti broj "1"... Ovo će biti ista akcija za svaku situaciju. Ali druga dva polja morat će se temeljito pozabaviti.

    Postavite kursor u polje "Godina"... Zatim prelazimo na izbor operatora kroz poznati trokut.

  4. Sve u istoj kategoriji Čarobnjaci za funkcije označite ime "GODINA" i kliknite na gumb "U REDU".
  5. Pokreće se prozor s argumentima operatora GODINA... Određuje godinu prema navedenom datumu. U kutiji s jednim prozorom "Datum u numeričkom formatu" navodimo vezu na ćeliju koja sadrži izvorni datum za koji želite odrediti broj dana. Nakon toga nemojte žuriti kliknuti na gumb "U REDU", i kliknite na ime "DATUM" na traci formule.
  6. Zatim se ponovno vraćamo na prozor s argumentima. DATUM... Postavite kursor u polje "Mjesec" i prijeđite na izbor funkcija.
  7. V Čarobnjak za funkcije kliknite na ime "MJESEC" i kliknite na gumb "U REDU".
  8. Pokreće se prozor s argumentima funkcije MJESEC... Njegovi zadaci su slični prethodnom operatoru, samo što prikazuje vrijednost broja mjeseca. U jedinom polju ovog prozora postavite istu referencu na izvorni broj. Zatim u traci formule kliknite na naziv "DAN".
  9. Vraćanje na prozor s argumentima DAN... Ovdje moramo napraviti samo jedan mali potez. U jedinom polju prozora, koje već sadrži podatke, dodajte izraz na kraj formule "-1" bez navodnika, a također stavite "+1" nakon operatora MJESEC... Nakon toga kliknite na gumb "U REDU".
  10. Kao što vidite, unaprijed odabrana ćelija prikazuje broj dana u mjesecu kojem pripada navedeni broj. Opća formula izgleda ovako:

    DAN (DATUM (GODINA (D3); MJESEC (D3) +1; 1) -1)

Tajna ove formule je jednostavna. Koristimo ga da odredimo datum prvog dana sljedećeg razdoblja, a zatim od njega oduzmemo jedan dan i dobijemo broj dana u navedenom mjesecu. Varijabla u ovoj formuli je referenca ćelije D3 na dva mjesta. Ako ga zamijenite adresom ćelije u kojoj se nalazi datum u vašem konkretnom slučaju, tada možete jednostavno ubaciti ovaj izraz u bilo koji element lista bez pomoći Čarobnjaci za funkcije.

Kao što vidite, postoji nekoliko opcija za doznavanje broja dana u mjesecu u Excelu. Koju će koristiti ovisi o krajnjem cilju korisnika, kao i o tome koju verziju programa koristi.

Bilješka: ovaj post je prijevod članka cmcenroe.me/2014/12/05/days-in-month-formula.html ( dio I), kao i autorov dodatak njemu ( Dio II). Ne biste trebali shvaćati gradivo ozbiljno, već radije kao zagrijavanje uma, koje ne zahtijeva ništa više od školskog znanja aritmetike i nema praktičnu primjenu. Sretno čitanje, svima!

dio I

Uvod

Nedavno, nakon još jedne neprospavane noći, razmišljao sam o metodama pamćenja broja dana u svakom mjesecu u godini. Za to postoji stroj za brojanje, kao i način računanja na zglobove, ali meni ni jedno ni drugo nije odgovaralo. Pitao sam se postoji li neka vrsta matematičke formule za rješavanje takvog problema, i - ne pronašavši je na površnoj studiji - izazvao sam sebe da je stvorim.

Formaliziranje Drugim riječima, potrebno je pronaći funkciju f tako da vrijednost f (x) za svaki mjesec x, predstavljen brojem između 1 i 12, jednak je broju dana u tom mjesecu. Tablica vrijednosti argumenata i funkcija:

x 1 2 3 4 5 6 7 8 9 10 11 12
f (x) 31 28 31 30 31 30 31 31 30 31 30 31

Ako imate želju isprobati ga i sami prije nego što pročitate moje rješenje, sada je pravo vrijeme. Ako više volite odmah vidjeti gotov odgovor, pogledajte ispod spojlera.

Odgovor


U nastavku su moji koraci za pronalaženje rješenja.

Matematički aparat

Prvo, osvježimo brzo pamćenje na dva vitalna operatora u rješavanju ovog problema: cjelobrojno dijeljenje i ostatak dijeljenja.

Cjelobrojna podjela to je operator koji se koristi u mnogim programskim jezicima kada se dijele dva cijela broja i odbacuje razlomak iz kvocijenta. Ja ću ga prikazati kao. Na primjer:

Ostatak divizije to je operator koji pronalazi ostatak dijeljenja. Mnogi programski jezici koriste simbol % , ali koristit ću konstrukcije oblika, na primjer:

Imajte na umu da ostatak podjele ima isti prioritet kao i podjela.

Osnove

Dakle, primijenimo naš matematički aparat da dobijemo osnovnu formulu. U tipičnom mjesecu ima 30 ili 31 dan, tako da možemo koristiti 1 ili 0 da dobijemo naizmjenično, a zatim ovom broju samo dodati konstantu:

Dobivamo tablicu, ispravne vrijednosti su podebljane:
x 1 2 3 4 5 6 7 8 9 10 11 12
f (x) 31 30 31 30 31 30 31 30 31 30 31 30

Lijep početak! Već postoje točne vrijednosti za siječanj i za mjesece od ožujka do uključujući srpanj. Veljača je poseban slučaj, a njime ćemo se pozabaviti nešto kasnije. Nakon srpnja, za preostale mjesece, redoslijed dobivanja 0 i 1 mora se obrnuti.
Da bismo to učinili, dividendi možemo dodati 1:

x 1 2 3 4 5 6 7 8 9 10 11 12
f (x) 30 31 30 31 30 31 30 31 30 31 30 31

Sada su točne vrijednosti od kolovoza do prosinca, ali očekivano, vrijednosti za ostale mjesece nisu točne. Pogledajmo kako možemo kombinirati ove formule.

Prekrivanje maske

Za to je potrebna djelićno definirana funkcija, ali - budući da mi se činilo dosadnim - razmišljao sam o drugom rješenju, koristeći jedan dio funkcije na jednom intervalu, drugi na drugom.
Mislim da je najlakše pronaći izraz koji je jednak 1 u jednoj aplikaciji i 0 u ostatku. Metodu u kojoj, množenjem argumenta s izrazom, izuzimamo ga iz formule izvan njegovog opsega, nazvao sam "maskiranje", jer je to ponašanje slično nekoj vrsti bit maske.
Da biste koristili ovu metodu u posljednjem dijelu naše funkcije, trebate pronaći izraz jednak 1 za, a - budući da su vrijednosti argumenata uvijek manje od 16 - za to je u redu cjelobrojno dijeljenje s 8.
x 1 2 3 4 5 6 7 8 9 10 11 12
x ⁄ 8 ⌋ 0 0 0 0 0 0 0 1 1 1 1 1

Sada, koristeći ovu masku, koristeći izraz umjesto 1 u dividendi, možemo zamijeniti redoslijed dobivanja 0 i 1 u formuli suprotnim:

x 1 2 3 4 5 6 7 8 9 10 11 12
f (x) 31 30 31 30 31 30 31 31 30 31 30 31

Eureka! Sve je točno, osim veljače. Iznenađenje iznenađenje.

veljača

Svaki mjesec ima 30 ili 31 dan, osim veljače sa svojim 28. (prijestupna godina je izvan okvira ovog problema). Trenutno, prema našoj formuli, ima 30 dana, pa bi bilo lijepo oduzeti izraz jednak 2 at.
Najbolje što sam smislio je ovo, koje maskira sve mjesece nakon veljače:
x 1 2 3 4 5 6 7 8 9 10 11 12
2 mod x 0 0 2 2 2 2 2 2 2 2 2 2

Mijenjajući osnovnu konstantu na 28, dodajući 2 ostatku mjeseci, dobivamo formulu:

x 1 2 3 4 5 6 7 8 9 10 11 12
f (x) 29 28 31 30 31 30 31 31 30 31 30 31

Nažalost, siječanj je sada 2 dana kraći. Srećom, lako je dobiti izraz koji vrijedi samo za prvi mjesec: to je obrnut broj zaokružen prema dolje. Množenjem s 2 dobivamo konačnu formulu:

x 1 2 3 4 5 6 7 8 9 10 11 12
f (x) 31 28 31 30 31 30 31 31 30 31 30 31

Pogovor

Evo je - formula za dobivanje broja dana u bilo kojem mjesecu u godini pomoću jednostavne aritmetike. Sljedeći put kada razmislite o tome koliko je dana u rujnu, jednostavno učinite ovo pomoću ove jednorečne JavaScript funkcije:

Funkcija f (x) (povrat 28 + (x + Math.floor (x / 8))% 2 + 2% x + 2 * Math.floor (1 / x);)

Dio II

Uvod

U prvom dijelu dobivena je kratka i čak pomalo elegantna formula čije su glavne prednosti jednostavnost matematičkog aparata, odsutnost grana i uvjetnih izraza te lakonizam. Nedostaci - osim činjenice da ga nećete koristiti u svom projektu - uključuju nedostatak provjere za viscoco i neprijestupne godine.
Stoga sam si postavio zadatak kreirati funkciju f tako da vrijednost f (x, y) za svaki mjesec x predstavljeno brojem od 1 do 12 i godinom y veći od 0 jednako je broju dana u mjesecu x u godini y.
Za nestrpljive ispod spojlera je gotov odgovor, dok se ostali mole da me prate.

Odgovor

Ostatak podjele: mod i ⌊⌋

Radi vizualne jasnoće, dogovorimo se da je u nekim formulama operator dijeljenja s ostatkom zamijenjen nižim zagradama, gdje mi se činilo potrebnim:

Prijestupna godina

U prijestupnoj godini uvodi se dodatni kalendarski dan: 29. veljače. Kao što znate, prijestupna godina je višekratnik 4, a ne višekratnik 100, ili višekratnik 400. Napišimo izraz identičan ovoj izjavi:

Za pretvaranje ovog izraza u algebarski, potrebno je primijeniti injekciju oblika na rezultat izraza:

Što će vam omogućiti da dobijete 1 pri dijeljenju bez ostatka i 0 pri dijeljenju s ostatkom, kako biste ga koristili u formuli za određivanje broja dana u mjesecu.

Kao funkcija g " možete koristiti 1 minus ostatak za:

x 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
g "(x) Beskonačnost 1 0 0 0 0 0 0 0 0 0 0 0 0 0

Lako je vidjeti da povećanjem dividende i djelitelja za 1 dobivamo ispravnu formulu za:
x 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
g "(x) 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0

Dakle, izraz će biti napisan kao:


I zapisujemo izraz kao:

Primjenom ovog pristupa dobivamo sljedeću funkciju g (y), čija će vrijednost biti 1 ako je godina prijestupna, ili 0 u suprotnom:

y 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000
g (y) 0 0 1 0 0 0 1 0 0 0 1
y 2000 2100 2200 2300 2400 2500 2600 2700 2800 2900 3000
g (y) 1 0 0 0 1 0 0 0 1 0 0

Prijestupne godine su podebljane.

Podsjećam da se u okviru prihvaćenog sporazuma operater za dobivanje ostatka podjele može prikazati kao mod i ⌊⌋.

Prekrivanje maske

U formuli, dio je amandman koji dodaje 2 dana do siječnja. Ako uklonimo faktor 2 i zamijenimo 1 s 2 u brojniku, tada će ova formula dodati 2 dana siječnju i 1 dan veljači, što nam daje ključ za dodavanje dana u prijestupnoj godini. Radi jasnoće koristimo srednju vrijednost u formuli g (y) i kao y koristimo 2000 (prijestupnu) i 2001 (neprijestupnu) godinu:

x 1 2 3 4 5 6 7 8 9 10 11 12
f (x, 2000) 31 29 31 30 31 30 31 31 30 31 30 31
f (x, 2001.) 30 28 31 30 31 30 31 31 30 31 30 30

Vrijednosti za sve mjesece osim siječnja neprestupne godine su točne.

Da biste ispravili ovaj dosadni nesporazum, dodajte 1 dan siječnju s formulom koju već poznajemo:


Ili:

x 1 2 3 4 5 6 7 8 9 10 11 12
f (x, 2000) 31 29 31 30 31 30 31 31 30 31 30 31
f (x, 2001.) 31 28 31 30 31 30 31 31 30 31 30 30

Zaključak

Kao rezultat, dobiva se mnogo glomaznija, ali univerzalnija formula, koja se također može koristiti za dobivanje broja dana u mjesecu određene godine:

Funkcija f (x, y) (povrat 28 + ((x + Math.floor (x / 8))% 2) + 2% x + Math.floor ((1 + (1 - (y% 4 + 2)% (y% 4 + 1)) * ((y% 100 + 2)% (y% 100 + 1)) + (1 - (y% 400 + 2)% (y% 400 + 1))) / x) + Matematički pod (1 / x) - Matematički pod (((1 - (y% 4 + 2)% (y% 4 + 1)) * ((y% 100 + 2)% (y% 100 + 1 )) + (1 - (y% 400 + 2)% (y% 400 + 1))) / x;)
Primjer u C # ideone.com/fANutz.

1 ... Ne znam koristiti takvu mnemotehniku, pa sam špijunirao znak na internetu.
2 ... "Osnove" ili "Pravilo s mnogo iznimaka", kao i većina pravila.
3 ... U početku je veljača bila posljednji mjesec u rimskom kalendaru, pa postoji logika da je kraća od svih ostalih. Logično je i dodavanje ili uklanjanje dana na kraju godine, pa je njegova duljina promjenjiva.

Upd. 1:
Alternativni prijevod prvog dijela u

Kalkulator datuma dizajniran je za izračunavanje broja dana između datuma i pronalaženje datuma dodavanjem ili oduzimanjem određenog broja dana od poznatog datuma.

Dodajte dane do datuma

Kako biste saznali koji će datum biti za određeni broj dana, koristite ovu opciju. Unesite datum početka i broj dana za dodavanje. Za oduzimanje koristite vrijednost minus. Kalkulator također ima mogućnost dodavanja samo radnih dana.

Izračunavanje broja dana između datuma

Ova metoda izračuna će odgovoriti na pitanje "koliko je dana prošlo od datuma". Unesite datum početka i datum završetka i kliknite gumb "izračunaj". Kalkulator će pokazati koliko je dana između unesenih datuma. Zasebno, kalkulator će pokazati broj radnih dana.

Ovom opcijom možete izračunati koliko je dana ostalo do određenog događaja, poput rođendana ili praznika. Da biste to učinili, u polje datuma početka unesite današnji datum, a u polje datum završetka datum događaja.

Praznici

Kalkulator može izračunati, zbrajati i oduzimati i kalendarske i radne dane. Službeni neradni praznici su:

  • 1,2,3,4,5,6,8 siječnja - Novogodišnji praznici
  • 7. siječnja - pravoslavni Božić
  • 23. veljače - Dan branitelja domovine
  • 8. ožujka – Međunarodni dan žena
  • 1. svibnja - Praznik proljeća i rada
  • 9. svibnja - Dan pobjede
  • 12. lipnja - Dan Rusije
  • 4. studenog - Dan narodnog jedinstva

Ako je praznik pao u subotu ili nedjelju, odgađa se za sljedeći radni dan. No, ponekad se vikend prenese na sasvim drugo mjesto u kalendaru. Primjerice, subota i nedjelja, koje su padale na novogodišnje praznike, mogu se premjestiti na svibanj kako bi se produžili svibanjski praznici.

Prilikom izračunavanja dana, kalkulator uzima u obzir i službene praznike i sve transfere.