The year changes from negative -509 to positive 510 in JDBC with the H2 database

-509 vs 510

I see some kind of altered or erroneous data using JDBC. Therefore, I am observing the use of H2 Database version 1.4.196 on Java 8 Update 151.

Here is a complete example.

Pay attention to the fact that we get the date value three times, first as an object LocalDate, secondly as a text, and thirdly as a year number intextracted from a cast object LocalDate. In the text version, we see that the year is really negative. Mysteriously LocalDatehas a different year number, and it is more likely positive than negative. Sounds like a mistake.

private void doIt ( )
{
    System.out.println( "BASIL - Running doIt." );
    try
    {
        Class.forName( "org.h2.Driver" );
    } catch ( ClassNotFoundException e )
    {
        e.printStackTrace( );
    }

    try (
            Connection conn = DriverManager.getConnection( "jdbc:h2:mem:" ) ;  // Unnamed throw-away in-memory database.
    )
    {
        conn.setAutoCommit( true );
        String sqlCreate = "CREATE TABLE history  ( id IDENTITY , when  DATE ); ";
        String sqlInsert = "INSERT INTO history ( when ) VALUES ( ? ) ; ";
        String sqlQueryAll = "SELECT * FROM history  ; ";

        PreparedStatement psCreate = conn.prepareStatement( sqlCreate );

        psCreate.executeUpdate( );

        PreparedStatement psInsert = conn.prepareStatement( sqlInsert );

        psInsert.setObject( 1 , LocalDate.of( 2017 , 1 , 23 ) );
        psInsert.executeUpdate( );

        psInsert.setObject( 1 , LocalDate.of( -509 , 1 , 1 ) );
        psInsert.executeUpdate( );

        PreparedStatement psQueryAll = conn.prepareStatement( sqlQueryAll );
        ResultSet rs = psQueryAll.executeQuery( );
        while ( rs.next( ) )
        {
            long l = rs.getLong( 1 );  // Identity column.
            // Retrieve the same date value in three different ways.
            LocalDate ld = rs.getObject( 2 , LocalDate.class );  // Extract a `LocalDate`, and implicitly call its `toString` method that uses standard ISO 8601 formatting.
            String s = rs.getString( 2 );  // Extract the date value as text from the database using the database-engine’s own formatting.
            int y = ( ( LocalDate ) rs.getObject( 2 , LocalDate.class ) ).getYear( );  // Extract the year number as an integer from a `LocalDate` object.
            String output = "ROW: " + l+ " | " + ld + " | when as String: " + s+ " | year: " + y ;
            System.out.println( output );
        }

        conn.close( );
    } catch ( SQLException e )
    {
        e.printStackTrace( );
    }
}

At startup.

ROW: 1 | 2017-01-23 | when as a string: 2017-01-23 | Year: 2017

ROW: 2 | 0510-01-01 | : -509-01-01 | : 510

, JDBC, , - . , 510, 509. .

, JDBC, LocalDate. . , IdeOne.com, , LocalDate .

LocalDate ld = LocalDate.of( -509 , 1 , 1 ) ;
System.out.println( "ld.toString(): " + ld ) ;
System.out.println( "ld.getYear(): " + ld.getYear() ) ;

, -509 510 LocalDate, JDBC.

ld: -0509-01-01

ld.getYear(): -509

"" H2.

+6
3

, ​​

- H2.

, 2018-01.

+1

java.sql.Date LocalDate , , Calendar, , 1 , LocalDate java ( == BC), , year < 0 , . enter image description here

:

public class Test {
 public static void main(String[] args) {

            Calendar instance = Calendar.getInstance();
            instance.set(-509,1,1);

            java.sql.Date d = new Date(instance.getTime().getTime());

            System.out.println(d.toLocalDate().getYear());// 510


        }
}

.. !!!

+4

TL; DR. JDBC java.sql.Date java.sql.Date.toLocalDate(), Date.getYear() ( ) .

, .

SEY_91s , , Calendar GregorianCalendar. Calendar LocalDate, java.sql.Date . .

: toLocalDate getYear. :

@SuppressWarnings("deprecation")
public LocalDate toLocalDate() {
    return LocalDate.of(getYear() + 1900, getMonth() + 1, getDate());
}

, getYear , :

    OffsetDateTime dateTimeBce 
            = OffsetDateTime.of(-509, 1, 1, 0, 0, 0, 0, ZoneOffset.ofHours(1));
    Date d = Date.from(dateTimeBce.toInstant());
    System.out.println("d.toInstant() " + d.toInstant());
    System.out.println("d.getYear() (deprecated): " + d.getYear() 
                        + ", means " + (d.getYear() + 1900));

getYear "1900", -2409. 1900 , -509, , . , :

d.toInstant() -0510-12-31T23:00:00Z
d.getYear() (deprecated): -1390, means 510

, Date , ( UTC -509 -510, ). java.util.Date, java.sql.Date getYear, java.sql.Date .

, . .

+3

All Articles