sql >> Database >  >> RDS >> Mysql

JPA Verkeerde datum opslaan in MySQL-database

tl;dr

Gebruik JPA 2.2 voor zijn steun aan java.time .

Gebruik een alleen-datum-klasse in Java om met alleen-datum-waarden in SQL te werken.

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 ondersteunt nu de moderne java.time klassen. U hoeft Joda-Time niet meer te gebruiken.

Doe niet gebruik java.sql.Date . Die klas doet alsof om alleen een datum weer te geven, maar heeft feitelijk een tijd van de dag ingesteld op UTC vanwege de vreselijke ontwerpbeslissing om te erven van java.util.Date (die ondanks de naam een ​​datum voorstelt en een tijdstip en een offset van nul voor UTC zelf). Deze legacy-klassen zijn een vreselijke ellendige puinhoop. Sun, Oracle en de JCP-gemeenschap hebben jaren geleden alle scriptielessen opgegeven met de adoptie van JSR 310, en dat zou jij ook moeten doen.

LocalDate

De LocalDate class vertegenwoordigt een alleen-datumwaarde zonder tijd van de dag en zonder tijdzone of offset-from-UTC .

Een tijdzone is cruciaal bij het bepalen van een datum. Voor elk willekeurig moment varieert de datum over de hele wereld per zone. Bijvoorbeeld een paar minuten na middernacht in Parijs Frankrijk is een nieuwe dag terwijl het nog steeds "gisteren" is in Montréal Québec .

Als er geen tijdzone is opgegeven, past de JVM impliciet de huidige standaardtijdzone toe. Die standaard kan op elk moment wijzigen tijdens runtime(!), dus uw resultaten kunnen variëren. Het is beter om uw gewenste/verwachte tijdzone expliciet als argument op te geven. Indien kritiek, bevestig de zone met uw gebruiker.

Geef een juiste tijdzonenaam op in de indeling Continent/Region , zoals America/Montreal , Africa/Casablanca , of Pacific/Auckland . Gebruik nooit de afkorting van 2-4 letters zoals EST of IST zoals ze zijn niet echte tijdzones, niet gestandaardiseerd, en zelfs niet uniek(!).

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

Als je de huidige standaardtijdzone van de JVM wilt gebruiken, vraag er dan om en geef het door als argument. Als u deze weglaat, wordt de code dubbelzinnig om in te lezen, zodat we niet zeker weten of u van plan was de standaardinstelling te gebruiken of dat u, zoals zoveel programmeurs, niet op de hoogte was van het probleem.

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

Of geef een datum op. U kunt de maand met een cijfer instellen, met normale nummering 1-12 voor 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.

Of, beter nog, gebruik de Month enum objecten vooraf gedefinieerd, één voor elke maand van het jaar. Tip:gebruik deze Month objecten in uw codebase in plaats van louter een geheel getal om uw code meer zelfdocumenterend te maken, geldige waarden te garanderen en type-veiligheid . Idem voor Year &YearMonth .

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

Datum-tijd wiskunde

Blijkbaar wil je met één datum beginnen en een maand later als datumbereik nemen.

LocalDate monthLater = ld.plusMonths( 1 ) ;

JDBC 4.2

Vanaf JDBC 4.2 is uw JDBC-stuurprogramma vereist om enkele van de belangrijkste java.time te ondersteunen klassen zoals LocalDate .

Datumbereik

Let op de onderstaande links voor ThreeTen-Extra . Mogelijk vindt u de LocalDateRange klasse daar om handig te zijn als je veel met datumbereiken werkt.

Over java.time

De java.time framework is ingebouwd in Java 8 en hoger. Deze klassen vervangen de lastige oude legacy date-time klassen zoals java.util.Date , Calendar , &SimpleDateFormat .

Zie voor meer informatie de Oracle-zelfstudie . En zoek Stack Overflow voor veel voorbeelden en uitleg. Specificatie is JSR 310 .

De Joda-Time project, nu in onderhoudsmodus , adviseert migratie naar de java.time lessen.

Je mag java.time ruilen objecten rechtstreeks met uw database. Gebruik een JDBC-stuurprogramma voldoet aan JDBC 4.2 of later. Geen strings nodig, geen java.sql.* lessen.

Waar zijn de java.time-klassen te verkrijgen?

De ThreeTen-Extra project breidt java.time uit met extra klassen. Dit project is een proeftuin voor mogelijke toekomstige toevoegingen aan java.time. Mogelijk vindt u hier enkele nuttige klassen, zoals Interval , YearWeek , YearQuarter , en meer .



  1. Is het slecht voor de prestaties om alle kolommen te selecteren?

  2. Stop alsjeblieft met het gebruik van dit UPSERT-antipatroon!

  3. Hoe genereer ik een willekeurig tijdsinterval en voeg ik het toe aan een mysql datetime met behulp van php?

  4. SQL-gegevenstypen:5 slechtste keuzes die u vandaag moet stoppen