giovedì 29 marzo 2012

Convertitore UNIX Timestamp - Data in Java

Bene, per una mia applicazione Java avevo sempre questo problema del UNIX timestamp (ovvero il numero di secondi trascorsi dal 1 Gennaio 1970 alle ore 00:00:00), ovvero convertire una data in formato anno, mese, giorno, ore minuti e secondi in UNIX timestamp. Forse non ho cercato bene nella libreria di Java o forse non ho googlato per bene, ma una funzione che facesse ciò non l'ho trovata, solo timestamp dell'ora corrente (che non mi interessava).

Avevo urgentemente bisogno dell'algoritmo per calcolarlo che per pigrizia non ho mai scritto; adesso con il cambiamento all'ora legale è seguito un nuovo malfunzionamento del mio programma e quindi ho deciso di scriverlo una volta per tutte e condividerlo con chi ne avesse bisogno. 

L'algoritmo si compone di due parti: data una data (scusate il gioco di parole), la prima parte calcola il numero di secondi trascorsi fino al primo gennaio dell'anno corrente alle 00:00:00, la seconda parte aggiunge il "resto", ovvero il numero di secondi mancante. 

Specularmente, ho riciclato il suddetto algoritmo per fare il procedimento inverso, e ne è uscita fuori una bella classe che contiene i due metodi statici. 
Innanzitutto ho creato una classe ausiliaria Data, invece di utilizzare la java.util.Date.

package it.albe;

/**
 *
 * @author Alberto
 * 29/03/2012
 */
public class Data {
    public Data(int a,int m,int g, int o, int min, int sec){
        anno = a;
        mese = m;
        giorno = g;
        ore = o;
        minuti = min;
        secondi = sec;
    }
    public String toString(){
        String ms;
        switch(mese){
            case 1: ms = "Gennaio";break;
            case 2: ms = "Febbraio";break;
            case 3: ms = "Marzo";break;
            case 4: ms = "Aprile";break;
            case 5: ms = "Maggio";break;
            case 6: ms = "Giugno";break;
            case 7: ms = "Luglio";break;
            case 8: ms = "Agosto";break;
            case 9: ms = "Settembre";break;
            case 10: ms = "Ottobre";break;
            case 11: ms = "Novembre";break;
            case 12: ms = "Dicembre";break;
            default: ms="";
        }
        return String.valueOf(giorno)+" "+ms+" "+
                String.valueOf(anno)+" "+
                String.valueOf(ore)+":"+
                String.valueOf(minuti)+":"+
                String.valueOf(secondi);
    }
    public int anno;
    public int mese;
    public int giorno;
    public int ore;
    public int minuti;
    public int secondi;
}
Fatto ciò, ecco allora la classe Timestamp:

package it.albe;

/**
 *
 * @author Alberto
 * 29/03/2012
 */
public class Timestamp {
    public static long toUNIXtimestamp(Data data){
        long timestamp = 0;     
        for (int a=1970;a < data.anno;a++){ //anno
            if (a % 4 == 0 && (a % 100 != 0 || a % 400 == 0)){  //bisestile
                int m;
                for (m=1;m <= 12;m++)
                    switch(m){
                        case 1:
                        case 3:
                        case 5:
                        case 7:
                        case 8:
                        case 10:
                        case 12: {
                            int g;
                            for (g=1;g <= 31;g++)
                               timestamp+= 86400;
                        }break;
                        case 2: {
                            int g;
                            for (g=1;g <= 29;g++)
                               timestamp+= 86400;
                        }break;
                        case 4:
                        case 6:
                        case 9:
                        case 11:{
                            int g;
                            for (g=1;g <= 30;g++)
                               timestamp+= 86400;
                        }break;
                    } //switch                
            } //if
            else {      //non bisestile
                int m;
                for (m=1;m <= 12;m++)
                    switch(m){
                        case 1:
                        case 3:
                        case 5:
                        case 7:
                        case 8:
                        case 10:
                        case 12: {
                            int g;
                            for (g=1;g <= 31;g++)
                               timestamp+= 86400;
                        }break;
                        case 2:{
                            int g;
                            for (g=1;g <= 28;g++)
                               timestamp+= 86400;
                        }break;
                        case 4:
                        case 6:
                        case 9:
                        case 11:{
                            int g;
                            for (g=1;g <= 30;g++)
                               timestamp+= 86400;
                        }break;
                    } //switch
            } //else
        }    //for anno
        /***********************************************************/
        /*                   AGGIUNGO RESIDUO                      */
        /***********************************************************/
        if (data.anno % 4 == 0 && (data.anno % 100 != 0 || data.anno % 400 == 0)){
            int m;
            for (m=1;m < data.mese;m++)
                switch(m){
                    case 1:
                    case 3:
                    case 5:
                    case 7:
                    case 8:
                    case 10:
                    case 12: {
                        int g;
                        for (g=1;g <= 31;g++)
                           timestamp+= 86400;
                    }break;
                    case 2: {
                        int g;
                        for (g=1;g <= 29;g++)
                           timestamp+= 86400;
                    }break;
                    case 4:
                    case 6:
                    case 9:
                    case 11:{
                        int g;
                        for (g=1;g <= 30;g++)
                           timestamp+= 86400;
                    }break;
               } //switch  
           int g;
           for (g=1;g < data.giorno;g++)
               timestamp+= 86400;
           timestamp += data.secondi+data.minuti*60+data.ore*3600;             
        }
        else {
             int m;
            for (m=1;m < data.mese;m++)
                switch(m){
                    case 1:
                    case 3:
                    case 5:
                    case 7:
                    case 8:
                    case 10:
                    case 12: {
                        int g;
                        for (g=1;g <= 31;g++)
                           timestamp+= 86400;
                    }break;
                    case 2: {
                        int g;
                        for (g=1;g <= 28;g++)
                           timestamp+= 86400;
                    }break;
                    case 4:
                    case 6:
                    case 9:
                    case 11:{
                        int g;
                        for (g=1;g <= 30;g++)
                           timestamp+= 86400;
                    }break;
               } //switch  
           int g;
           for (g=1;g < data.giorno;g++)
               timestamp+= 86400;
           timestamp += data.secondi+data.minuti*60+data.ore*3600;  
        }
        return timestamp;
    }
    public static Data toDate(long Ptimestamp){
        int a;
        long timestamp = 0;
        for (a=1970;a < 2038;a++){ //anno
            if (a % 4 == 0 && (a % 100 != 0 || a % 400 == 0)){  //bisestile
                int m;
                for (m=1;m <= 12;m++)
                    switch(m){
                        case 1:
                        case 3:
                        case 5:
                        case 7:
                        case 8:
                        case 10:
                        case 12: {
                            int g;
                            int o;
                            int min;
                            int s;
                            for (g=1;g <= 31;g++)
                                for (o=0;o < 24;o++)
                                    for(min=0;min < 60;min++)
                                        for (s=0;s < 60;s++){
                                            timestamp++;
                                            if (Ptimestamp==timestamp){
                                                return new Data(a,m,g,o,min,s+1);
                                            
                                            }
                                        }
                        }break;
                        case 2: {
                            int g;
                            int o;
                            int min;
                            int s;
                            for (g=1;g <= 29;g++)
                                for (o=0;o < 24;o++)
                                    for(min=0;min < 60;min++)
                                        for (s=0;s < 60;s++){
                                            timestamp++;
                                            if (Ptimestamp==timestamp){
                                                return new Data(a,m,g,o,min,s+1);
                                            }
                                        }
                        }break;
                        case 4:
                        case 6:
                        case 9:
                        case 11:{
                            int g;
                            int o;
                            int min;
                            int s;
                            for (g=1;g <= 30;g++)
                                for (o=0;o < 24;o++)
                                    for(min=0;min < 60;min++)
                                        for (s=0;s < 60;s++){
                                            timestamp++;
                                            if (Ptimestamp==timestamp){
                                                return new Data(a,m,g,o,min,s+1);
                                            }
                                        }
                        }break;
                    } //switch                
            } //if
            else {      //non bisestile
                int m;
                for (m=1;m <= 12;m++)
                    switch(m){
                        case 1:
                        case 3:
                        case 5:
                        case 7:
                        case 8:
                        case 10:
                        case 12: {
                            int g;
                            int o;
                            int min;
                            int s;
                            for (g=1;g <= 31;g++)
                                for (o=0;o < 24;o++)
                                    for(min=0;min < 60;min++)
                                        for (s=0;s < 60;s++){
                                            timestamp++;
                                            if (Ptimestamp==timestamp){
                                                return new Data(a,m,g,o,min,s+1);
                                            }
                                        }
                        }break;
                        case 2:{
                            int g;
                            int o;
                            int min;
                            int s;
                            for (g=1;g <= 28;g++)
                                for (o=0;o < 24;o++)
                                    for(min=0;min < 60;min++)
                                        for (s=0;s < 60;s++){
                                            timestamp++;
                                            if (Ptimestamp==timestamp){
                                                return new Data(a,m,g,o,min,s+1);
                                            }
                                        }
                        }break;
                        case 4:
                        case 6:
                        case 9:
                        case 11:{
                            int g;
                            int o;
                            int min;
                            int s;
                            for (g=1;g <= 30;g++)
                                for (o=0;o < 24;o++)
                                    for(min=0;min < 60;min++)
                                        for (s=0;s < 60;s++){
                                            timestamp++;
                                            if (Ptimestamp==timestamp){
                                                return new Data(a,m,g,o,min,s+1);
                                            }
                                        }
                        }break;
                    } //switch
            } //else
        }    //for anno 
        return new Data(0,0,0,0,0,0);
    }
    
}
In pratica il metodo toUNIXtimestamp() nella prima parte fa un ciclo dove anno per anno controlla innanzitutto se è bisestile, e mese per mese controlla se è un 31 o un 28 o un 30, e poi giorno per giorno aumenta il timestamp di 86400 (numero di secondi in un giorno), mentre la seconda parte procede in maniera analoga tenendo conto della data di cui si vuol calcolare il timestamp.

L'altro metodo è analogo e non c'è nemmeno bisogno che lo spieghi.

Ed ecco un utilizzo esemplare di questa classe:


        Data data = new Data(2012,3,29,21,48,45); //29 marzo 2012 alle 21:48 e 45 secondi
        long ts = toUNIXtimestamp(data);
        System.out.print(ts+"\n");
        data = toDate(ts);
        System.out.print(data);

Nessun commento:

Posta un commento