Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
import java.util.Arrays;
import java.util.Calendar;
import java.util.List;
import java.util.TimeZone;
import java.util.concurrent.TimeUnit;

/** Convenience class for converting values between Java, JDBC and Cloud Spanner. */
Expand Down Expand Up @@ -496,10 +497,18 @@ private static java.sql.Timestamp getOrSetTimestampInCalendar(
Calendar newCal = Calendar.getInstance(cal.getTimeZone());
// set the millisecond time on this calendar from the timestamp
newCal.setTimeInMillis(sqlTs.getTime());
newCal.set(Calendar.MILLISECOND, 0);

TimeZone timeZone = newCal.getTimeZone();
long totalMillis = newCal.getTimeInMillis();
// to calculate the offset for DST correctly, we need to add DST savings and check if
// given epoch milli is in daylight savings time.
if (getOrSet == GetOrSetTimestampInCalendar.GET) {
totalMillis += timeZone.getRawOffset() + timeZone.getDSTSavings();
}

// then shift the time of the calendar by the difference between UTC and the timezone of the
// given calendar
int offset = newCal.getTimeZone().getOffset(newCal.getTimeInMillis());
int offset = newCal.getTimeZone().getOffset(totalMillis);
newCal.add(
Calendar.MILLISECOND, getOrSet == GetOrSetTimestampInCalendar.GET ? offset : -offset);
// then use that to create a sql timestamp
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@
import java.sql.Time;
import java.sql.Timestamp;
import java.text.DecimalFormat;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
Expand Down Expand Up @@ -959,6 +961,29 @@ public void testDateToSqlTimestampWithCalendar() {
.toSqlTimestamp());
}

@Test
public void testDateToSqlTimestampWithCalendarWithStartOfDST() {
TimeZone timeZone = TimeZone.getTimeZone("Europe/Oslo");

List<ZonedDateTime> zonedDateTimes =
Arrays.asList(
ZonedDateTime.of(2018, 3, 25, 2, 0, 0, 0, ZoneId.of("+01:00")),
ZonedDateTime.of(2018, 10, 28, 2, 0, 0, 0, ZoneId.of("+01:00")));

zonedDateTimes.forEach(
expected -> {
Timestamp expectedTimestamp = Timestamp.from(expected.toInstant());
Calendar cal = Calendar.getInstance(timeZone);
Timestamp storeTimestamp =
JdbcTypeConverter.setTimestampInCalendar(expectedTimestamp, cal);

Timestamp resultTimestamp = JdbcTypeConverter.getTimestampInCalendar(storeTimestamp, cal);
ZonedDateTime actual = resultTimestamp.toInstant().atZone(timeZone.toZoneId());

assertThat(actual).isEqualTo(expected.withZoneSameInstant(timeZone.toZoneId()));
});
}

@Test
public void testParseSqlTimeWithCalendar() {
assertThat(
Expand Down