Entity DB e ora in formato String e non LocalTime ad esempio.

di il
9 risposte

Entity DB e ora in formato String e non LocalTime ad esempio.

Salve sto facendo un Applicazione Spring.
In generale non dovrebbe essere richiesto il passaggio/fuso orario da un ora ad un' altra.
Così nell' Entity ho scelto di salvare l'ora in formato String,
Il sito deve essere funzionante in Italia del resto.
Pro e contro?
Ho scelto questa soluzione perché malgrado le richieste anche ChatGPT sbaglia, non mi dà una soluzione quindi.

Nel senso che il sistema continua a salvare l'ora 1 o 2 ore prima rispetto all'immensa nel DB.

Dal momento che l'app funziona in Italia ho pensato che può andare bene ma non vorrei avere sorprese più avanti.

Il motivo che stranamente ChatGPT non coglie, è dovuto certamente al fuso orario.

Mi ha praticamente fatto perdere mezza giornata perché mi ero scordata UTC.

Io passo al modello, tramite controller il LocalTime.

Tuttavia dovrei passare ora preimpostata in UTC.

Ovviamente non va bene salvare l'ora locale come testo e correggerò, i consigli di chatgpt ...

9 Risposte

  • Re: Entity DB e ora in formato String e non LocalTime ad esempio.

    Non è molto chiaro quali siano stati i suggerimenti di ChatGPT.

    Ad ogni modo, dovresti dare qualche specifica in più:

    1. Quale DBMS stai utilizzando?
    2. Dove si trova fisicamente il DBMS? Qui in Italia o altrove?
    3. La macchina su cui è installato il DBMS che impostazioni di timezone ha?
    4. Qual è il tipo di dato che hai provato a definire nel campo della tabella che dovrà contenere questa informazione?
    5. Puoi far vedere un po' di codice che hai provato a scrivere?
    6. Riesci a farci vedere degli esempi di date/ore che provi ad inserire e il valore effettivamente memorizzato a DB?

    .

    Io, generalmente, quando devo memorizzare informazioni di data e ora tendo a seguire una di queste due strade:

    • Memorizzazione in un'unico campo di tipo DATETIME (gestito dal driver JDBC come valore java.sql.Timestamp)
    • Memorizzazione separata della data (in un campo DATE) e dell'ora (in un campo di testo)

    .

    Nei DBMS esiste il tipo di dato TIME, ma sinceramente non ho mai avuto necessità di utilizzarlo, anche perchè è un campo che non ha alcuna cognizione del timezone (rappresenta semplicemente un dato di ore, minuti e secondi, utile se vogliamo per rappresentare delle "durate").

    Attendiamo tue.

  • Re: Entity DB e ora in formato String e non LocalTime ad esempio.

    17/03/2026 - SpiritoLibero ha scritto:

    Non è molto chiaro quali siano stati i suggerimenti di ChatGPT.

    Ad ogni modo, dovresti dare qualche specifica in più:

    1. Quale DBMS stai utilizzando?
    2. Dove si trova fisicamente il DBMS? Qui in Italia o altrove?
    3. La macchina su cui è installato il DBMS che impostazioni di timezone ha?
    4. Qual è il tipo di dato che hai provato a definire nel campo della tabella che dovrà contenere questa informazione?
    5. Puoi far vedere un po' di codice che hai provato a scrivere?
    6. Riesci a farci vedere degli esempi di date/ore che provi ad inserire e il valore effettivamente memorizzato a DB?

    .

    Io, generalmente, quando devo memorizzare informazioni di data e ora tendo a seguire una di queste due strade:

    • Memorizzazione in un'unico campo di tipo DATETIME (gestito dal driver JDBC come valore java.sql.Timestamp)
    • Memorizzazione separata della data (in un campo DATE) e dell'ora (in un campo di testo)

    .

    Nei DBMS esiste il tipo di dato TIME, ma sinceramente non ho mai avuto necessità di utilizzarlo, anche perchè è un campo che non ha alcuna cognizione del timezone (rappresenta semplicemente un dato di ore, minuti e secondi, utile se vogliamo per rappresentare delle "durate").

    Attendiamo tue.

    -----------------------------

    Ciao e grazie molte per la risposta:

    1. I suggerimenti di ChatGpt son stati di usare un attributo di testo per salvare l'ora. E qui penso che sia assolutamente fourviante.

    2. Sto usando MySQL.

    3. Le impostazioni della macchina sono quelle standard, non ho modficato nulla. Uso un portatile per ora. (Sai indicarmi come vedo questo?)

    4. Ora usa Instant e pare(devo fare test ma ho molte cose da tesare) funzionare: restituisce l' ora corretta e nel DB dovrei averla salvata in UTC, poi se ho ben capito la rilleggo in LocalTime Zona Rome/Europe. ChatGpt mi aveva fourviato a usare String.

    5. Personalmente è un progetto che deve nascere ancora quindi preferirei di no.

    Mi pare funziona ora, ma dovrei fare ancora dei test. Fammi sapere che ne pensi e se dovrebbe funzionare. Sauti e grazie.

    
    6. Questi si, eco qui salvo l' entity:
    
    //Converto date e time in singola datetime instant usando il fuso orario.
    
    	    LocalDate date = obj.getDate(); 	
        	
        	LocalTime time = obj.getTime();     	
        	
        	System.out.println(obj.getDate().toString() + " - " + obj.getTime().toString());
        	
        	ZoneId zone = ZoneId.of("Europe/Rome");
        	
        	Instant dateTimeInstant = ZonedDateTime.of(date, time, zone).toInstant();
        	
            entity.setDateTime(dateTimeInstant);
    
    
    Per la lettura dei singoli date e time eseguo il percorso inverso:
    
        	Instant dateTime = entity.getDateTime();
    
        	ZoneId zone = ZoneId.of("Europe/Rome");
    
        	ZonedDateTime zdt = dateTime.atZone(zone);
    
        	LocalDate date = zdt.toLocalDate();
        	
        	LocalTime time = zdt.toLocalTime();
  • Re: Entity DB e ora in formato String e non LocalTime ad esempio.

    Secondo me ti stai complicando la vita.

    Ho voluto realizzare un esempio, utilizzando MySQL, per verificare come vengono trattati i tipi di data/ora (io solitamente lavoro su SQL Server, quindi per non sbagliare, ho installato l'ultima versione LTS di MySQL disponibile e ho realizzato l'esempietto).

    Ho creato un database e ho definito la seguente tabella (nome: "registro"):

    Come puoi vedere ho tre campi di tipo data/ora:
    dataProtocollo di tipo DATE (può contenere solo date senza indicazione di orario)
    oraProtocollo di tipo TIME (può contenere solo orari)
    timeStampRegistro di tipo DATETIME (contiene sostanzialmente dei timestamp, quindi un valore di DATA + ORA)

    Poi ho creato un'applicazione SpringBoot.

    Qui di seguito l'entity che mappa quella tabella:

    package test.demo.entities;
    
    import jakarta.persistence.Column;
    import jakarta.persistence.Entity;
    import jakarta.persistence.Id;
    import jakarta.persistence.Table;
    import java.time.LocalDate;
    import java.time.LocalDateTime;
    import java.time.LocalTime;
    
    @Entity
    @Table(name = "registro")
    public class Registro implements java.io.Serializable {
        @Id
        @Column(name = "idRegistro")
        private Integer idRegistro;
        
        @Column(name = "cognome", length=80)
        private String cognome;
        
        @Column(name = "nome", length=80)
        private String nome;
        
        @Column(name = "dataProtocollo")
        private LocalDate dataProtocollo;
        
        @Column(name = "oraProtocollo")
        private LocalTime oraProtocollo;
        
        @Column(name = "timeStampRegistro")
        private LocalDateTime timeStampRegistro;
    
        public Integer getIdRegistro() {
            return idRegistro;
        }
    
        public void setIdRegistro(Integer idRegistro) {
            this.idRegistro = idRegistro;
        }
    
        public String getCognome() {
            return cognome;
        }
    
        public void setCognome(String cognome) {
            this.cognome = cognome;
        }
    
        public String getNome() {
            return nome;
        }
    
        public void setNome(String nome) {
            this.nome = nome;
        }
    
        public LocalDate getDataProtocollo() {
            return dataProtocollo;
        }
    
        public void setDataProtocollo(LocalDate dataProtocollo) {
            this.dataProtocollo = dataProtocollo;
        }
    
        public LocalTime getOraProtocollo() {
            return oraProtocollo;
        }
    
        public void setOraProtocollo(LocalTime oraProtocollo) {
            this.oraProtocollo = oraProtocollo;
        }
    
        public LocalDateTime getTimeStampRegistro() {
            return timeStampRegistro;
        }
    
        public void setTimeStampRegistro(LocalDateTime timeStampRegistro) {
            this.timeStampRegistro = timeStampRegistro;
        }
    }

    L'applicazione si limita a creare un'oggetto Registro, stampare a video i tre valori dataProtocollo, oraProtocollo e timeStampRegistro, salvare l'entity a DB, poi andarla a rileggere e stampare nuovamente i tre valori appena riletti dalla tabella del DB.

        @Autowired
        private RegistroRepository repo;
        
        @Override
        public void run(String... args) {
            
            LocalDate oggi = LocalDate.now();
            LocalTime adesso = LocalTime.now();
            LocalDateTime timeStamp = LocalDateTime.now();
            
            Registro reg = new Registro();
            reg.setIdRegistro(0);
            reg.setCognome("Rossi");
            reg.setNome("Mario");
            reg.setDataProtocollo( oggi );
            reg.setOraProtocollo( adesso );
            reg.setTimeStampRegistro( timeStamp );
            
            System.out.println("Creo entity via Java:");
            System.out.println("Data protocollo: " + oggi.toString());
            System.out.println(" Ora protocollo: " + adesso.toString());
            System.out.println("      Timestamp: " + timeStamp.toString());
            
            System.out.println("Scrivo record in tabella");
            repo.saveAndFlush( reg );
            
            System.out.println("Rileggo entity da DB:");
            Registro regLetta = repo.findById(0).orElse( null );
            if (regLetta != null) {
                System.out.println("Data protocollo: " + regLetta.getDataProtocollo().toString());
                System.out.println(" Ora protocollo: " + regLetta.getOraProtocollo().toString());
                System.out.println("      Timestamp: " + regLetta.getTimeStampRegistro().toString());
            }
        }

    Qui l'output del programma:

    Qui lo screenshot dei dati contenuti nella tabella:

    Come puoi vedere non ci sono problemi di TimeZone. L'esecuzione è stata da me effettuata effettivamente alle ore 12:14:03 ora italiana.

    La mia macchina, dove gira sia il DBMS MySQL, sia l'applicazione Java, è un PC Windows 10 con le impostazioni del fuso orario impostate sul fuso orario di Roma.

    Come puoi vedere ho semplicemente creato gli oggetti LocalDate, LocalTime e LocalDateTime e li ho usati direttamente per valorizzare i campi dell'entità.

  • Re: Entity DB e ora in formato String e non LocalTime ad esempio.

    Ciao probabilmente funziona a te così perché tu mi hai detto che hai il tuo PC è impostato sul fuso orario Europe/Rome.
    Hai impostato come? Tramite application.properties?
    Ti assicuro che sia con Instant che con LocalDateTime o LocadTime a me l'ora appare anticipata su MySql.
    ma quando la prelevo in lettura appare coretta con Instant.
    Inizialmente mi ero aspettato di leggerla uguale con LocalTime ma non avveniva appunto penso per le pre-impostazioni.

    In pratica tu leggi l'ora corretta perché hai pre impostato il fuso orario mentre io imposto a runtime?

    D'altra parte nel mio caso dovrebbe essere lettera correttamente come si deve anche in un'altro stato/Giappone/Usa/ecc.

  • Re: Entity DB e ora in formato String e non LocalTime ad esempio.

    Non c'entra nulla né Java, né l'application.properties.

    Sto parlando di impostazioni di sistema (nel mio caso Windows: Pannello di Controllo -> Orologio e area geografica -> Data e ora). Non qualcosa che vado a cambiare quando mi serve: sono così da quando è stato installato il sistema operativo (del resto, vivendo e lavorando in Italia vorrei vedere l'ora italiana nel PC).

    Ti assicuro che sia con Instant che con LocalDateTime o LocadTime a me l'ora appare anticipata su MySql.

    Qui sarebbe interessante capire esattamente cosa vuol dire: in che modo verifichi i dati presenti su MySQL? Usando la CLI? Usando un software di terze parti (io ho usato HeidiSQL per gli screenshot)? Altro?

  • Re: Entity DB e ora in formato String e non LocalTime ad esempio.

    Leggo i dati tramite select su tabella da MySQL.

    Se leggo l' ora però con Java risulta convertita correttamente 

  • Re: Entity DB e ora in formato String e non LocalTime ad esempio.

    Quindi esegui le query direttamente dalla CLI di MySQL?

    Allora prova ad eseguire le seguenti istruzioni e prova a vedere cosa ti restituisce:

    SELECT NOW();
    SELECT @@global.time_zone, @@session.time_zone;
    SELECT TIMEDIFF(NOW(), UTC_TIMESTAMP);

    Da me questi sono gli output:

    Questo significa che erano le 14:01:29 quando ho eseguito la prima query e che le impostazioni del time-zone sono prese dal sistema operativo (e la differenza da UTC al momento è correttamente di 1 ora).

  • Re: Entity DB e ora in formato String e non LocalTime ad esempio.

    Il punto è che data/ora legge l'utente.

    L'utente che crea l'ora è nel suo paese, quindi la sua LocalTime non corrisponde a quella del destinatario che è quella che serve.

    Per questo ho pensato di usare prima UTC ora universale e poi convertire nella zona richiesta sebbene è sempre l' Italia per adesso.

  • Re: Entity DB e ora in formato String e non LocalTime ad esempio.

    Cerchiamo di fare chiarezza: il timezone dell'utente non c'entra nulla con il valore memorizzato nel DB.

    Quando viene scritto il dato, all'interno del DB ci finisce sostanzialmente un numero.

    Quel numero dovrà poi essere "renderizzato" per poter essere letto da un umano.

    Qui conta il COME viene renderizzato. E conta il TimeZone.

    Facciamo un esempio. Supponiamo che io (utente dall'Italia) memorizzi la seguente data/ora: 2026-03-20 13:05:19.879

    Ciò che verrà memorizzato all'interno del database sarà un numero: 1774008319879 (è un esempio, ciascun DBMS potrebbe memorizzarlo in modo diverso, con regole diverse). Quel numero rappresenta un istante preciso nel tempo (la differenza in millisecondi dalla Epoch: 1970-01-01 00:00:00.000).

    Se vado a renderizzare io quel dato (io utente Italia), mostrerò a video questo dato: 2026-03-20 13:05:19.879

    Se lo va a renderizzare un utente che vive in Inghilterra, verrà mostrato questo dato: 2026-03-20 12:05:19.879

    Se lo va a renderizzare un utente che vive in Giappone, verrà mostrato questo dato: 2026-03-20 21:05:19.879 (in Giappone sono a GMT+9)

    Ma il valore memorizzato a DB è sempre lo stesso. Ed è corretto in tutte e tre le renderizzazioni perchè effettivamente, quando io (utente Italia) ho inserito quel dato, in Giappone erano le 21:05.

Devi accedere o registrarti per scrivere nel forum
9 risposte