sql >> Databasteknik >  >> RDS >> Mysql

JPA Sparar fel datum i MySQL-databasen

tl;dr

Använd JPA 2.2 för dess stöd för java.time .

Använd en klass för endast datum i Java för att arbeta med värden endast för datum i SQL.

LocalDate                           // Represent a date-only, without a time-of-day and without a time zone.
.now(                               // Get today's date…
    ZoneId.of( "Africa/Tunis" )     // …as seen in the wall-clock time used by the people of a particular region.
)                                   // Returns a `LocalDate` object.
.plusMonths( 1 )                    // Returns another `LocalDate` object, per immutable objects pattern.

java.time

JPA 2.2 stöder nu modern java.time klasser. Du behöver inte längre använda Joda-Time.

Gör det inte använd java.sql.Date . Den klassen låtsas representerar endast ett datum men har faktiskt en tid på dagen inställd på UTC på grund av det hemska designbeslutet att ärva från java.util.Date (som trots namnet representerar ett datum och en tid på dagen och en offset på noll för själva UTC). Dessa äldre klasser är en fruktansvärd eländig röra. Sun, Oracle och JCP-communityt gav alla upp avhandlingarna för flera år sedan med antagandet av JSR 310, och det borde du också göra.

LocalDate

LocalDate klass representerar ett värde endast för datum utan tid på dagen och utan tidszon eller offset-from-UTC .

En tidszon är avgörande för att bestämma ett datum. För varje givet ögonblick varierar datumet runt om i världen efter zon. Till exempel några minuter efter midnatt i Paris Frankrike är en ny dag medan det fortfarande är "igår" i Montréal Québec .

Om ingen tidszon anges, tillämpar JVM implicit sin nuvarande standardtidszon. Den standarden kan ändra när som helst under körning(!), så dina resultat kan variera. Bättre att ange din önskade/förväntade tidszon uttryckligen som ett argument. Om det är kritiskt, bekräfta zonen med din användare.

Ange ett riktigt tidszonnamn i formatet Kontinent/Region , till exempel America/Montreal , Afrika/Casablanca , eller Pacific/Auckland . Använd aldrig förkortningen på 2-4 bokstäver såsom EST eller IST eftersom de inte är det sanna tidszoner, inte standardiserade och inte ens unika(!).

ZoneId z = ZoneId.of( "America/Montreal" ) ;  
LocalDate today = LocalDate.now( z ) ;

Om du vill använda JVM:s nuvarande standardtidszon, fråga efter det och skicka som ett argument. Om den utelämnas blir koden tvetydig att läsa i att vi inte med säkerhet vet om du tänkt använda standarden eller om du, som så många programmerare, inte var medveten om problemet.

ZoneId z = ZoneId.systemDefault() ;  // Get JVM’s current default time zone.

Eller ange ett datum. Du kan ställa in månaden med en siffra, med siffra 1-12 för januari-december.

LocalDate ld = LocalDate.of( 1986 , 2 , 23 ) ;  // Years use sane direct numbering (1986 means year 1986). Months use sane numbering, 1-12 for January-December.

Eller, bättre, använd Månad enum-objekt fördefinierade, ett för varje månad på året. Tips:Använd dessa Månad objekt i din kodbas snarare än ett heltal för att göra din kod mer självdokumenterande, säkerställa giltiga värden och tillhandahålla typsäkerhet . Ditto för År &YearMonth .

LocalDate ld = LocalDate.of( 1986 , Month.FEBRUARY , 23 ) ;

Datum-tid matematik

Tydligen vill du börja med ett datum och få en månad senare som datumintervall.

LocalDate monthLater = ld.plusMonths( 1 ) ;

JDBC 4.2

Från och med JDBC 4.2 krävs din JDBC-drivrutin för att stödja några av nyckeln java.time klasser som LocalDate .

Datumintervall

Notera länkarna nedan för ThreeTen-Extra . Du kan hitta LocalDateRange klass där för att vara praktiskt om du arbetar mycket med datumintervall.

Om java.time

java.time ramverket är inbyggt i Java 8 och senare. Dessa klasser ersätter det besvärliga gamla arvet datum-tid-klasser som java. util.Datum , Kalender , &SimpleDateFormat .

Om du vill veta mer, se Oracle Tutorial . Och sök på Stack Overflow för många exempel och förklaringar. Specifikationen är JSR 310 .

Joda-Time projekt, nu i underhållsläge , rekommenderar migrering till java.time klasser.

Du kan byta ut java.time objekt direkt med din databas. Använd en JDBC-drivrutin kompatibel med JDBC 4.2 eller senare. Inget behov av strängar, inget behov av java.sql.* klasser.

Var får man tag i java.time-klasserna?

ThreeTen-Extra projektet utökar java.time med ytterligare klasser. Detta projekt är en provgrund för möjliga framtida tillägg till java.time. Du kan hitta några användbara klasser här som Intervall , YearWeek , YearQuarter , och mer .



  1. Hur tar jag reda på mitt root MySQL-lösenord?

  2. Vad gör DELIMITER // i en utlösare?

  3. Skrivoptimeringar för Qualcomm Centriq 2400 i MariaDB 10.3.5 Release Candidate

  4. Konvertera åtkomst till PostgreSQL?