0

I chose a time for example I have entered Thu Jan 01 16:00:00 WET 1970 and also a timezone for example GMT+1:00. I mean that I want to record this date with this time zone (16:00 already in gmt+1). But after saving the model the value is getting saved as Thu Jan 01 15:00:00 WET 1970 in the database.

The server is in Africa/Casablanca timezone.

I tried to convert this date into String with time zone what I want and it shows me the correct time but when I try to convert this string to Date I still receive the time with one hour less.

      DisplayedTimeZone displayedTimeZone = configuration.getDisplayedTimeZone();
    if(displayedTimeZone != null){
        Date orderCuttOffTime = configuration.getCutOffTime(); // Thu Jan 01 15:00:00 WET 1970
        if(orderCuttOffTime != null){
          SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z");
          sdf.setTimeZone(TimeZone.getTimeZone(displayedTimeZone.getCode()));
          String closingTime = sdf.format(orderCuttOffTime); // 1970-01-01 16:00:00 +0100
          try {
                configuration.setCutOffTime(dateFormat.parse(cuttOffTime)); // returns again Thu Jan 01 15:00:00 WET 1970 and not 16:00:00
          }catch (ParseException e) {
                e.printStackTrace();
            }
        }
    }

Even the cuttofftime contains the time Thu 1970-01-01 16:00:00 +0100 that I want to save in database dateFormat.parse(cuttOffTime) returns the value Thu Jan 01 15:00:00 WET 1970

I want during the parse to send me a date with the same time which is in the string

CHARAFI Saad
  • 1,340
  • 3
  • 16
  • 36

2 Answers2

1

A java.util.Date object simply represents an instant on the timeline — a wrapper around the number of milliseconds since the UNIX epoch (January 1, 1970, 00:00:00 GMT). Since it does not hold any timezone information, its toString function applies the JVM's timezone to return a String in the format, EEE MMM dd HH:mm:ss zzz yyyy, derived from this milliseconds value. To get the String representation of the java.util.Date object in a different format and timezone, you need to use SimpleDateFormat with the desired format and the applicable timezone e.g.

Date date = new Date();

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX", Locale.ENGLISH);

sdf.setTimeZone(TimeZone.getTimeZone("America/New_York"));
String strDateNewYork = sdf.format(date);

sdf.setTimeZone(TimeZone.getTimeZone("Etc/UTC"));
String strDateUtc = sdf.format(date);

java.time

With the release of Java SE 8 in March 2014, the outdated and error-prone legacy Date-Time API (java.util Date-Time types and their formatting type, SimpleDateFormat etc.) was supplanted by java.time, the modern Date-Time API*. The following table depicts the mapping of ANSI SQL types with java.time types:

ANSI SQL Java SE 8
DATE LocalDate
TIME LocalTime
TIMESTAMP LocalDateTime
TIME WITH TIMEZONE OffsetTime
TIMESTAMP WITH TIMEZONE OffsetDateTime

Note that ZonedDateTime and Instant are not supported by any JDBC driver whereas some drivers e.g. PostgreSQL also do not support OffsetTime / TIME [ WITHOUT TIMEZONE ].

How to use it in JDBC?

Given below is a sample code to insert the current OffsetDateTime in UTC, into columnfoo (which is of TIMESTAMP WITH TIMEZONE type):

OffsetDateTime odt = Instant.now().atOffset(ZoneOffset.UTC);
PreparedStatement st = conn.prepareStatement("INSERT INTO mytable (columnfoo) VALUES (?)");
st.setObject(1, odt);
st.executeUpdate();
st.close();

Given below is a sample code to retrieve a OffsetDateTime from columnfoo:

Statement st = conn.createStatement();
ResultSet rs = st.executeQuery("SELECT * FROM mytable WHERE <some condition>");
while (rs.next()) {
    // Assuming the column index of columnfoo is 1
    OffsetDateTime odt = rs.getObject(1, OffsetDateTime.class));
    System.out.println(odt);
}
rs.close();
st.close();

Just in case you need to convert odt to represent the date-time in your timezone:

ZonedDateTime zdt = odt.atZoneSameInstant(ZoneId.of("Africa/Casablanca"));
System.out.println(zdt); // With timezone and timezone offset
System.out.println(zdt.toOffsetDateTime()); // With timezone offset

Learn more about the modern Date-Time API from Trail: Date Time.


* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.

Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110
0

Given that cutOffTime is a java.util.Date, there is nothing you can do, since Date doesn't have a time zone and is always stored in UTC.

The time zone WET that you see is simply the default rendering of the Date value.

If you want to save a time with time zone and without date, use the Java 8+ OffsetTime class instead of Date.

Andreas
  • 154,647
  • 11
  • 152
  • 247