Does the time zone matter in timestamp analysis?

I have a timestamp encoded as String& mdash, for example "2012-02-12T09:08:13.123456-0400", coming from an Oracle database.

The only way I can read this timestamp is with Timestamp.valueOf () , and this requires a formatyyyy-[m]m-[d]d hh:mm:ss[.f...]

I am convinced that this is the only way to read time without losing accuracy, because other methods do not support the nanosecond accuracy included in the example above ( ".123456").

With that in mind, I can just trim the required values ​​so that they match the required format. Therefore, the original string will be converted:

  • Before: "2012-02-12T09:08:13.123456-0400"
  • After: "2012-02-12 09:08:13.123456"

If I do this, I will remove the timeline offset "-0400". For me, this is a red flag until I saw this post . One suggested answer says:

I think the correct answer should be java.sql.Timestamp is not a specific time zone. The timestamp is an integral part of java.util.Date and a separate nanosecond. There is no time zone information in this class. Thus, just like Date, this class simply contains the number of milliseconds since January 1, 1970, 00:00:00 GMT + nanos.

To prove to myself that displacement is not required, I wrote a simple integration test.

: "2015-09-08 11:11:12.123457". Java . "2015-09-08 11:11:12.123457", . , JVM Oracle DB .

  • , java.sql.Timestamp?
  • , Java 7?
+4
3

TL;DR

org.threeten.bp.OffsetDateTime odt = 
    OffsetDateTime.parse(
        "2012-02-12T09:08:13.123456-0400",
        org.threeten.bp.format.DateTimeFormatter.ofPattern( "yyyy-MM-dd'T'HH:mm:ssZ" )  // Specify pattern as workaround for Java 8 bug in failing to parse if optional colon is not present.
    )
;

java.time

, , , , java.time.

java.time , java.sql.Timestamp. JDBC JDBC 4.2 , java.time.

Instant

Instant UTC ( (9) ). , java.sql.Timestamp, , .

Instant instant = myResultSet.getObject( … , Instant.class ) ;

instant.toString(): 2012-02-12T13: 08: 13.123456Z

ZonedDateTime

, ZoneId, ZonedDateTime.

ZoneId z = ZoneId.of( "America/St_Thomas" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;

zdt.toString(): 2012-02-12T09: 08: 13.123456-04: 00 [America/St_Thomas]

OffsetDateTime

, 2012-02-12T09:08:13.123456-0400 , OffsetDateTime.

continent/region , , , (DST). , OffsetDateTime, ZonedDateTime.

OffsetDateTime odt = OffsetDateTime.parse( "2012-02-12T09:08:13.123456-0400" ) ;

, , Java 8 , COLON . , -04:00 Java 8 , -0400. ​​ Java 9. ISO 8601 , java.time. . , , - , .

Java 9, , , .

OffsetDateTime odt = 
    OffsetDateTime.parse(
        "2012-02-12T09:08:13.123456-0400",
        DateTimeFormatter.ofPattern( "yyyy-MM-dd'T'HH:mm:ssZ" )  // Specify pattern as workaround for Java 8 bug in failing to parse if optional colon is not present.
    )
;

JDBC- JDBC 4.2, java.sql.Timestamp, . java.time, , .

java.sql.Timestamp ts = myResultSet.getTimestamp( … ) ;
Instant instant = ts.toInstant();

- java.time. - , Instant java.sql.Timestamp.

myPreparedStatement.setTimestamp( … , java.sql.Timestamp.from( instant ) ) ;

Java 6 7

Java 6 7 - , java.time . ThreeTen-Backport. , . .

Java 7 JDBC 4.2. , java.time JDBC. , java.sql.Timestamp Instant. DateTimeUtils.toInstant(Timestamp sqlTimestamp) DateTimeUtils.toSqlTimestamp(Instant instant).

java.sql.Timestamp ts = myResultSet.getTimestamp( … ) ;
Instant instant = DateTimeUtils.toInstant( ts ) ;

... ...

java.sql.Timestamp ts = DateTimeUtils.toSqlTimestamp( instant ) ;
myPreparedStatement.setTimestamp( … , ts ) ;

java.time

java.time Java 8 . legacy , java.util.Date, Calendar SimpleDateFormat.

Joda-Time, , java.time.

, . Oracle. Qaru . JSR 310.

java.time?

ThreeTen-Extra java.time . java.time. , Interval, YearWeek, YearQuarter .

+2

java.sql.Timestamp.valueOf(String) . , , Timestamp(int year, int month, int date, int hour, int minute, int second, int nano), public Date(int year, int month, int date, int hrs, int min, int sec), ( ):

Date , , year, month, date, hrs, min sec, .

, Timestamp ( GMT + ), Timestamp JDBC ( ), .

, 10:00 SQL TIMESTAMP 10:00, , , - 08:00, 2 GMT; .

0

, java.sql.Timestamp . , , , , 0, 1 1970 , 00:00:00 GMT.

, , , " ", ISO-8601 Java 8 java.time. , , . , , ; 8 , . , Java8 DateTimeFormatter -0000 ISO-8601, , "", .

public void java8TimeWTF() {
  OffsetDateTime odt = OffsetDateTime.parse(
    "2012-02-12T09:08:13.123456-0400",
    DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.nZ"));
  Instant i = odt.toInstant();
  System.out.printf("odt: %s, i: %s\n", odt, i);
}

odt: 2012-02-12T09:08:13.000123456-04:00, i: 2012-02-12T13:08:13.000123456Z

, ISO-8601, .

import org.testng.annotations.Test;
import java.time.Instant;
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import static org.testng.Assert.assertEquals;

public class Java8Time8601 {
  private final long EXPECTED_MILLIS = 1493397412000L;

  public Instant iso8601ToInstant(String s) {
    DateTimeFormatter[] dateTimeFormatters = {
            DateTimeFormatter.ISO_INSTANT,
            DateTimeFormatter.ISO_OFFSET_DATE_TIME,
            DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssZ")
    };
    for (DateTimeFormatter dtf : dateTimeFormatters) {
      try {
        OffsetDateTime odt = OffsetDateTime.parse(s, dtf);
        Instant i = odt.toInstant();
        return i;
      } catch (DateTimeParseException dtpe) {
        ;
      }
    }
    throw new IllegalArgumentException(String.format("failed to parse %s", s));
  }

  @Test
  public void testInstantParse8601_Z() throws Exception {
    String[] candidates = {
            "2017-04-28T16:36:52.000Z",
            "2017-04-28T16:36:52.00Z",
            "2017-04-28T16:36:52.0Z",
            "2017-04-28T16:36:52Z",
            "2017-04-28T16:36:52+00:00",
            "2017-04-28T16:36:52-00:00",
            "2017-04-28T09:36:52-07:00",
            "2017-04-28T09:36:52-0700",
    };
    for (String candidate : candidates) {
      Instant i = iso8601ToInstant(candidate);
      assertEquals(i.toEpochMilli(), EXPECTED_MILLIS, String.format("failed candidate %s", candidate));
      System.out.println(i.toString());
    }
  }
}

.

-1

Source: https://habr.com/ru/post/1679373/


All Articles