sql >> Database teknologi >  >> RDS >> Sqlserver

ved at bruge datetimeoffset-datatypen med jTDS

Som nævnt i afsnittet "Backward Compatibility for Down-level Clients" i datetime offset dokumentation , kan vi arbejde med strengrepræsentationer af datetimeoffset værdier. Faktisk, hvis vi henter en datetimeoffset værdi med jTDS 1.3.1 får vi en java.lang.String værdien af ​​formularen

YYYY-MM-DD hh:mm:ss[.nnnnnnn] {+|-}hh:mm

En sådan værdi kan parses sådan:

// rs is our ResultSet object
String valueRetrieved = rs.getString(1);  // e.g., "2016-12-08 12:34:56.7850000 -07:00"
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSSSSS ZZZZZ");
ZonedDateTime zdt = ZonedDateTime.parse(valueRetrieved, dtf);

Med hensyn til at skrive en datetimeoffset værdi til SQL Server, er jTDS ikke i stand til at håndtere en opdatering korrekt ved hjælp af .setTimestamp , f.eks. på min maskine ...

java.sql.Timestamp ts = java.sql.Timestamp.valueOf("2016-12-08 12:34:56.785");  // local
String tsString = formatTimestampForDateTimeOffset(ts);  // (see below)
System.out.printf("             java.sql.TimeStamp value: %s (%d ms since epoch)%n", tsString, ts.getTime());

System.out.println();
System.out.println("Saving via setTimestamp ...");
String sqlUpdate = "UPDATE dtoTable SET dtoCol = ? WHERE id=1";
try (PreparedStatement s = conn.prepareStatement(sqlUpdate)) {
    s.setTimestamp(1, ts);  // pass the Timestamp itself
    s.executeUpdate();
}
String valueRetrieved;
try (
        Statement s = conn.createStatement();
        ResultSet rs = s.executeQuery("SELECT dtoCol FROM dtoTable WHERE id=1")) {
    rs.next();
    valueRetrieved = rs.getString(1);
    System.out.printf("    jTDS saved the TimeStamp value as: %s%n", valueRetrieved);
}

... producerer ...

         java.sql.TimeStamp value: 2016-12-08 12:34:56.785 -07:00 (1481225696785 ms since epoch)

Saving via setTimestamp ...
jTDS saved the TimeStamp value as: 2016-12-08 12:34:56.7870000 +00:00

... som ikke kun forkert indstiller tidszoneforskydningen til +00:00 (uden at ændre selve dato/tidsværdien), den tilføjer også et par millisekunder bare for sjov.

Men hvis vi konverterer tidsstempelværdien til en korrekt formateret streng, f.eks. ...

public static String formatTimestampForDateTimeOffset(java.sql.Timestamp ts) {
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS ZZZZZ");
    String s = sdf.format(new Date(ts.getTime()));
    // T-SQL *requires* the colon in the timezone offset: -07:00, not -0700
    int colonPosition = s.length() - 2;
    return s.substring(0, colonPosition) + ":" + s.substring(colonPosition);
}

... og brug .setString i stedet for .setTimestamp , derefter datetimeoffset værdien er gemt korrekt:

Saving via setString ...
jTDS saved the formatted String as: 2016-12-08 12:34:56.7850000 -07:00
           parsed to ZonedDateTime: 2016-12-08T12:34:56.785-07:00
              converted to Instant: 2016-12-08T19:34:56.785Z
       converted to java.util.Date: Thu Dec 08 12:34:56 MST 2016



  1. LATERAL JOIN bruger ikke trigramindeks

  2. Forlod Deltag den MAX(DATE)

  3. Sådan gemmer du svaret fra min server, og hvordan kan jeg få adgang til disse data

  4. Påstand i MySQL