Scientific Calculator

(public) Giordano/FunzioniDataOra

By Giordano Giordano Cignani

//16/03/2020
// Funzioni di data e ora
var cifre="0123456789";
var global:fu_or=1;
var global:set_=[["lunedì","martedì","mercoledì","giovedì","venerdì","sabato","domenica"],
	["lun","mar","mer","gio","ven","sab","dom"],
	["lun","mar","mer","gio","ven","sab","dom"],
	["","","","","","",""]]';
var global:mesi_=[[" ","Gennaio","Febbraio","Marzo","Aprile","Maggio","Giugno","Luglio","Agosto","Settembre","Ottobre","Novembre","Dicembre"],
	[" ","Gen","Feb","Mar","Apr","Mag","Giu","Lug","Ago","Set","Ott","Nov","Dic"],
	["","/01/","/02/","/03/","/04/","/05/","/06/","/07/","/08/","/09/","/10/","/11/","/12/"],
	["","/01/","/02/","/03/","/04/","/05/","/06/","/07/","/08/","/09/","/10/","/11/","/12/"]]';
var global:fd_=1;
frac=function(x,n){[floor(x/n),x mod n]};
// numero di fuso orario; anche per l' ora legale; -12<=k<=11
fusoorario=function(k){fu_or=(k+12) mod 24-12};		
// formato della data: format in [1,2,3,4], se altro si apre una finestra di input
formatodata=function(format){var fd= string(findc(string(format),"1234"));   
	fd_ =(findc(fd,"1234") != -1) ? (format-1) :
    (while (findc(fd,"1234") == -1)->(
    fd=prompt("1:estesa, 2:ristretta, 3:numerica,4:numerica no settimana",
    "Formato Data",string(fd_+1)));val(fd)-1)};
// data e ora corrente; in format formato data, se nullo o altro assume il valore della variabile fd_ 
data=function(format){var (s,d)=[[],[]];
	var frmt= ((format==null) or (findc(string(format),"1234")== -1)) ? fd_ : format-1;
	var mettizero= function(g){(g<10) ? string:join([0,g]) : g};	
	var mesegiorno=function(x){var j=11;
        var yy=[0,31,61,92,122,153,184,214,245,275,306,337];
        while (yy[j]>x)->j=j-1;[j,x-yy[j]]};   
    var (ii,ff)=frac(floor(time()/10)/100,60);push(s,ff*1.);
    var (ii,ff)=frac(ii+60*fu_or,60);push(s,ff);
    var (ii,ff)=frac(ii,24);push(s,ff);var gs=set_[(ii+3) mod 7][frmt];
    ii-=790;var g4a = frac(ii,1461);
    var ga=frac(g4a[1],365);
    var mg= (g4a[1]==1460) ? [11,28] : mesegiorno(ga[1]);
    mg[0]= ((mg[0]+2) mod 12)+1;mg[1]=mg[1]+1;
    ii=1972+g4a[0]*4+ga[0]+floor(ga[1]/306);
    d=string:join([mettizero(mg[1]),mesi_[mg[0]][frmt],ii],mesi_[0][frmt]);
    string:trim(string:join([gs,d,string:join(reverse(map(x->mettizero(x),s)),":")]," "))};


mettizero= function(g){(g<10) ? string:join([0,g]) : g};
data_reverse=function(d){var dd=string:split(d,"/");
    string:join([dd[2],mettizero(val(dd[1])),mettizero(val(dd[0]))],"/") };
	
// data ->numero seriale 01/01/1972 == 0; se manca l' anno assume l' anno corrente
data_num=function(strd){
		
		var std=map(x->ipart(x),VAL(strd));var f=true;var mg=0;
		var mss=["Dati insufficienti","Mese non valido","Giorno non valido",
            "Anno non bisestile","giorni aboliti dalla riforma gregoriana"];
		var ult=[31,29,31,30,31,30,31,31,30,31,30,31];
        var yy=[0,31,61,92,122,153,184,214,245,275,306,337];
	var verstd=function(){var ls=len(std);
		CASE([ls<2,   x->error(mss[0]);
			  ls==2,  x->std=push(std,VAL(data(4))[2]);
			  ls>3,   x->std=slice(std,0,3) ]);
		var t:stst= data_reverse(string:join(std,"/"));
        f=  (std[1] in 1...12);mg=1;
        if f ->  (f=f and (std[0] in 1...ult[std[1]-1]);mg=2);
        if f ->  (f= f and not((std[1]==2) and (std[0]==29) and ((std[2] mod 4) != 0));mg=3);
		if f ->  (f= f and not ((std[2]>1582) and (std[0]==29) and (std[1]==2) and ((floor(std[2]/100) mod 4) != 0));mg=3);
		if f ->  (f= f and not ((t:stst>"1582/10/04") and (t:stst<"1582/10/15"));mg=4);
        f};
	
	if not verstd()->error(mss[mg]);	
	var (g,m,a)=std-[1,1,1600];mm=frac(m+10,12)-[1,0];a += mm[0];
	var (a400,b400)= frac(a,400);
	var (a100,b100)=frac(b400,100); 
	var (bis,nob)=frac(b100,4);
	if (a>=0) -> (n400=146097;n100=36524) else (n400=146100;n100=36525);
	  	g=n400*a400+n100*a100+1461*bis+365*nob+yy[mm[1]]+g-135080; //zero al 1/1/1970
	if (t:stst<"1582/10/15")-> g+=10;                              //giorni aboliti dalla rif. greg.
	g};	
	
data_set=function(datastr,format){num_set(data_num(datastr),format-1)};	
num_set=function(n,format){set_[(n+3) mod 7][format]};
	
num_data=function(nu,format){
    var frmt= ((format==null) or (findc(string(format),"1234")== -1)) ? fd_ : format-1;
    var aggiusta=function(m,d){(m==[4,0]) ? [3,d] : m };	
    var mesegiorno=function(x){var j=11;
        var yy=[0,31,61,92,122,153,184,214,245,275,306,337];
        while (yy[j]>x)->j=j-1;[j,x-yy[j]]};   
	var gs=set_[(nu+3) mod 7][frmt];
	if (nu<= -141428) -> nu -= 10;       // correzione 10 giorni rif. greg.
	var nu=nu+135080;                   // zero al 1/3/1600
	if (nu>=0) -> (n400=146097;n100=36524) else (n400=146100;n100=36525);	
    var g4s = frac(nu,n400);         // 4 secoli
	var gsec = aggiusta(frac(g4s[1],n100),n100);    // 1 secolo
	var g4a = aggiusta(frac(gsec[1],1461),1461);      // 4 anni
    var ga=aggiusta(frac(g4a[1],365),365);           //giorni nell' anno		
    var mg= mesegiorno(ga[1]);
    mg[0]= ((mg[0]+2) mod 12)+1;mg[1]=mg[1]+1;
    nu=1600+400*g4s[0]+100*gsec[0]+4*g4a[0]+ga[0]+floor(ga[1]/306);
	var d=string:join([mettizero(mg[1]),mesi_[mg[0]][frmt],nu],mesi_[0][frmt]);
    string:join([gs,d]," ")};

spam? | offensive?

0 Comments

Sign in to leave a comment