Skip to content

Commit

Permalink
feat: introduce java.time methods and variables (#2780)
Browse files Browse the repository at this point in the history
This PR introduces `java.time` alternatives to existing `org.threeten.bp.*` methods, as well as switching internal variables (if any) to `java.time`

The main constraint is to keep the changes backwards compatible, so for each existing threeten method "`method1(org.threeten.bp.Duration)`" we will add an alternative with a _Duration_ (or _Timestamp_ when applicable) suffix: "`method1Duration(java.time.Duration)`".

For most cases, the implementation will be held in the `java.time` method and the old threeten method will just delegate the call to it. However, for the case of abstract classes, the implementation will be kept in the threeten method to avoid breaking changes (i.e. users that already overloaded the method in their user code).
  • Loading branch information
diegomarquezp authored Dec 5, 2024
1 parent 7703ab2 commit 8dd66d5
Show file tree
Hide file tree
Showing 40 changed files with 473 additions and 274 deletions.
16 changes: 16 additions & 0 deletions google-cloud-bigquerystorage/clirr-ignored-differences.xml
Original file line number Diff line number Diff line change
Expand Up @@ -212,5 +212,21 @@
<className>com/google/cloud/bigquery/storage/v1/StreamWriter</className>
<method>void setMissingValueInterpretationMap(java.util.Map)</method>
</difference>
<difference>
<!--This class is marked as @InternalApi "public for technical reasons"-->
<differenceType>6004</differenceType>
<className>com/google/cloud/bigquery/storage/*/stub/readrows/ApiResultRetryAlgorithm</className>
<field>DEADLINE_SLEEP_DURATION</field>
<from>org.threeten.bp.Duration</from>
<to>java.time.Duration</to>
</difference>
<difference>
<!--The retryDelay field is used by ApiResultRetryAlgorithm, which is marked as @InternalApi-->
<differenceType>6004</differenceType>
<className>com/google/cloud/bigquery/storage/util/Errors$IsRetryableStatusResult</className>
<field>retryDelay</field>
<from>org.threeten.bp.Duration</from>
<to>java.time.Duration</to>
</difference>
</differences>

Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import io.grpc.Metadata;
import io.grpc.Status;
import io.grpc.protobuf.ProtoUtils;
import org.threeten.bp.Duration;
import java.time.Duration;

/** Static utility methods for working with Errors returned from the service. */
public class Errors {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.google.cloud.bigquery.storage.util;

import com.google.api.core.InternalApi;

/**
* Convenience methods for conversions between {@link java.time} and {@link org.threeten.bp}
* objects. This will be kept until <a
* href="https://github.com/googleapis/sdk-platform-java/issues/3412">this issue</a> is solved.
*/
@InternalApi("https://github.com/googleapis/sdk-platform-java/issues/3412")
public class TimeConversionUtils {
public static java.time.LocalDateTime toJavaTimeLocalDateTime(
org.threeten.bp.LocalDateTime result) {
return java.time.LocalDateTime.of(
result.getYear(),
java.time.Month.of(result.getMonth().getValue()),
result.getDayOfMonth(),
result.getHour(),
result.getMinute(),
result.getSecond(),
result.getNano());
}

public static org.threeten.bp.LocalDateTime toThreetenLocalDateTime(
java.time.LocalDateTime result) {
return org.threeten.bp.LocalDateTime.of(
result.getYear(),
org.threeten.bp.Month.of(result.getMonth().getValue()),
result.getDayOfMonth(),
result.getHour(),
result.getMinute(),
result.getSecond(),
result.getNano());
}

public static java.time.LocalTime toJavaTimeLocalTime(org.threeten.bp.LocalTime result) {
return java.time.LocalTime.of(
result.getHour(), result.getMinute(), result.getSecond(), result.getNano());
}

public static org.threeten.bp.LocalTime toThreetenLocalTime(java.time.LocalTime result) {
return org.threeten.bp.LocalTime.of(
result.getHour(), result.getMinute(), result.getSecond(), result.getNano());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,15 @@
*/
package com.google.cloud.bigquery.storage.v1;

import static com.google.cloud.bigquery.storage.util.TimeConversionUtils.toJavaTimeLocalDateTime;
import static com.google.cloud.bigquery.storage.util.TimeConversionUtils.toJavaTimeLocalTime;
import static com.google.cloud.bigquery.storage.util.TimeConversionUtils.toThreetenLocalDateTime;
import static com.google.cloud.bigquery.storage.util.TimeConversionUtils.toThreetenLocalTime;
import static com.google.common.base.Preconditions.checkArgument;

import org.threeten.bp.DateTimeException;
import org.threeten.bp.LocalDateTime;
import org.threeten.bp.LocalTime;
import org.threeten.bp.temporal.ChronoUnit;
import com.google.api.core.ObsoleteApi;
import java.time.DateTimeException;
import java.time.temporal.ChronoUnit;

/**
* Ported from ZetaSQL CivilTimeEncoder Original code can be found at:
Expand Down Expand Up @@ -89,7 +92,7 @@ public final class CivilTimeEncoder {
* @see #decodePacked32TimeSeconds(int)
*/
@SuppressWarnings("GoodTime-ApiWithNumericTimeUnit")
private static int encodePacked32TimeSeconds(LocalTime time) {
private static int encodePacked32TimeSeconds(java.time.LocalTime time) {
checkValidTimeSeconds(time);
int bitFieldTimeSeconds = 0x0;
bitFieldTimeSeconds |= time.getHour() << HOUR_SHIFT;
Expand All @@ -112,19 +115,29 @@ private static int encodePacked32TimeSeconds(LocalTime time) {
* @see #encodePacked32TimeSeconds(LocalTime)
*/
@SuppressWarnings("GoodTime-ApiWithNumericTimeUnit")
private static LocalTime decodePacked32TimeSeconds(int bitFieldTimeSeconds) {
private static java.time.LocalTime decodePacked32TimeSeconds(int bitFieldTimeSeconds) {
checkValidBitField(bitFieldTimeSeconds, TIME_SECONDS_MASK);
int hourOfDay = getFieldFromBitField(bitFieldTimeSeconds, HOUR_MASK, HOUR_SHIFT);
int minuteOfHour = getFieldFromBitField(bitFieldTimeSeconds, MINUTE_MASK, MINUTE_SHIFT);
int secondOfMinute = getFieldFromBitField(bitFieldTimeSeconds, SECOND_MASK, SECOND_SHIFT);
// LocalTime validates the input parameters.
try {
return LocalTime.of(hourOfDay, minuteOfHour, secondOfMinute);
return java.time.LocalTime.of(hourOfDay, minuteOfHour, secondOfMinute);
} catch (DateTimeException e) {
throw new IllegalArgumentException(e.getMessage(), e);
}
}

/**
* This method is obsolete. Use {@link #encodePacked64TimeMicrosLocalTime(java.time.LocalTime)}
* instead.
*/
@ObsoleteApi("Use encodePacked64TimeMicrosLocalTime(java.time.LocalTime) instead")
@SuppressWarnings("GoodTime")
public static long encodePacked64TimeMicros(org.threeten.bp.LocalTime time) {
return encodePacked64TimeMicrosLocalTime(toJavaTimeLocalTime(time));
}

/**
* Encodes {@code time} as a 8-byte integer with microseconds precision.
*
Expand All @@ -140,13 +153,21 @@ private static LocalTime decodePacked32TimeSeconds(int bitFieldTimeSeconds) {
* @see #encodePacked64TimeMicros(LocalTime)
*/
@SuppressWarnings("GoodTime")
public static long encodePacked64TimeMicros(LocalTime time) {
public static long encodePacked64TimeMicrosLocalTime(java.time.LocalTime time) {
checkValidTimeMicros(time);
return (((long) encodePacked32TimeSeconds(time)) << MICRO_LENGTH) | (time.getNano() / 1_000L);
}

/** This method is obsolete. Use {@link #decodePacked64TimeMicrosLocalTime(long)} instead. */
@ObsoleteApi("Use decodePacked64TimeMicrosLocalTime(long) instead")
@SuppressWarnings("GoodTime-ApiWithNumericTimeUnit")
public static org.threeten.bp.LocalTime decodePacked64TimeMicros(long bitFieldTimeMicros) {
return toThreetenLocalTime(decodePacked64TimeMicrosLocalTime(bitFieldTimeMicros));
}

/**
* Decodes {@code bitFieldTimeMicros} as a {@link LocalTime} with microseconds precision.
* Decodes {@code bitFieldTimeMicros} as a {@link java.time.LocalTime} with microseconds
* precision.
*
* <p>Encoding is as the following:
*
Expand All @@ -159,13 +180,13 @@ public static long encodePacked64TimeMicros(LocalTime time) {
* @see #encodePacked64TimeMicros(LocalTime)
*/
@SuppressWarnings("GoodTime-ApiWithNumericTimeUnit")
public static LocalTime decodePacked64TimeMicros(long bitFieldTimeMicros) {
public static java.time.LocalTime decodePacked64TimeMicrosLocalTime(long bitFieldTimeMicros) {
checkValidBitField(bitFieldTimeMicros, TIME_MICROS_MASK);
int bitFieldTimeSeconds = (int) (bitFieldTimeMicros >> MICRO_LENGTH);
LocalTime timeSeconds = decodePacked32TimeSeconds(bitFieldTimeSeconds);
java.time.LocalTime timeSeconds = decodePacked32TimeSeconds(bitFieldTimeSeconds);
int microOfSecond = getFieldFromBitField(bitFieldTimeMicros, MICRO_MASK, MICRO_SHIFT);
checkValidMicroOfSecond(microOfSecond);
LocalTime time = timeSeconds.withNano(microOfSecond * 1000);
java.time.LocalTime time = timeSeconds.withNano(microOfSecond * 1000);
checkValidTimeMicros(time);
return time;
}
Expand All @@ -184,7 +205,7 @@ public static LocalTime decodePacked64TimeMicros(long bitFieldTimeMicros) {
* @see #decodePacked64DatetimeSeconds(long)
*/
@SuppressWarnings("GoodTime-ApiWithNumericTimeUnit")
private static long encodePacked64DatetimeSeconds(LocalDateTime dateTime) {
private static long encodePacked64DatetimeSeconds(java.time.LocalDateTime dateTime) {
checkValidDateTimeSeconds(dateTime);
long bitFieldDatetimeSeconds = 0x0L;
bitFieldDatetimeSeconds |= (long) dateTime.getYear() << YEAR_SHIFT;
Expand All @@ -208,16 +229,17 @@ private static long encodePacked64DatetimeSeconds(LocalDateTime dateTime) {
* @see #encodePacked64DatetimeSeconds(LocalDateTime)
*/
@SuppressWarnings("GoodTime-ApiWithNumericTimeUnit")
private static LocalDateTime decodePacked64DatetimeSeconds(long bitFieldDatetimeSeconds) {
private static java.time.LocalDateTime decodePacked64DatetimeSeconds(
long bitFieldDatetimeSeconds) {
checkValidBitField(bitFieldDatetimeSeconds, DATETIME_SECONDS_MASK);
int bitFieldTimeSeconds = (int) (bitFieldDatetimeSeconds & TIME_SECONDS_MASK);
LocalTime timeSeconds = decodePacked32TimeSeconds(bitFieldTimeSeconds);
java.time.LocalTime timeSeconds = decodePacked32TimeSeconds(bitFieldTimeSeconds);
int year = getFieldFromBitField(bitFieldDatetimeSeconds, YEAR_MASK, YEAR_SHIFT);
int monthOfYear = getFieldFromBitField(bitFieldDatetimeSeconds, MONTH_MASK, MONTH_SHIFT);
int dayOfMonth = getFieldFromBitField(bitFieldDatetimeSeconds, DAY_MASK, DAY_SHIFT);
try {
LocalDateTime dateTime =
LocalDateTime.of(
java.time.LocalDateTime dateTime =
java.time.LocalDateTime.of(
year,
monthOfYear,
dayOfMonth,
Expand All @@ -231,6 +253,16 @@ private static LocalDateTime decodePacked64DatetimeSeconds(long bitFieldDatetime
}
}

/**
* This method is obsolete. Use {@link
* #encodePacked64DatetimeMicrosLocalDateTime(java.time.LocalDateTime)} instead.
*/
@ObsoleteApi("Use encodePacked64DatetimeMicrosLocalDateTime(java.time.LocalDateTime) instead")
@SuppressWarnings({"GoodTime-ApiWithNumericTimeUnit", "JavaLocalDateTimeGetNano"})
public static long encodePacked64DatetimeMicros(org.threeten.bp.LocalDateTime dateTime) {
return encodePacked64DatetimeMicrosLocalDateTime(toJavaTimeLocalDateTime(dateTime));
}

/**
* Encodes {@code dateTime} as a 8-byte integer with microseconds precision.
*
Expand All @@ -245,14 +277,26 @@ private static LocalDateTime decodePacked64DatetimeSeconds(long bitFieldDatetime
* @see #decodePacked64DatetimeMicros(long)
*/
@SuppressWarnings({"GoodTime-ApiWithNumericTimeUnit", "JavaLocalDateTimeGetNano"})
public static long encodePacked64DatetimeMicros(LocalDateTime dateTime) {
public static long encodePacked64DatetimeMicrosLocalDateTime(java.time.LocalDateTime dateTime) {
checkValidDateTimeMicros(dateTime);
return (encodePacked64DatetimeSeconds(dateTime) << MICRO_LENGTH)
| (dateTime.getNano() / 1_000L);
}

/**
* Decodes {@code bitFieldDatetimeMicros} as a {@link LocalDateTime} with microseconds precision.
* This method is obsolete. Use {@link #decodePacked64DatetimeMicrosLocalDateTime(long)} instead.
*/
@ObsoleteApi("Use decodePacked64DatetimeMicrosLocalDateTime(long) instead")
@SuppressWarnings("GoodTime-ApiWithNumericTimeUnit")
public static org.threeten.bp.LocalDateTime decodePacked64DatetimeMicros(
long bitFieldDatetimeMicros) {
return toThreetenLocalDateTime(
decodePacked64DatetimeMicrosLocalDateTime(bitFieldDatetimeMicros));
}

/**
* Decodes {@code bitFieldDatetimeMicros} as a {@link java.time.LocalDateTime} with microseconds
* precision.
*
* <p>Encoding is as the following:
*
Expand All @@ -265,13 +309,15 @@ public static long encodePacked64DatetimeMicros(LocalDateTime dateTime) {
* @see #encodePacked64DatetimeMicros(LocalDateTime)
*/
@SuppressWarnings("GoodTime-ApiWithNumericTimeUnit")
public static LocalDateTime decodePacked64DatetimeMicros(long bitFieldDatetimeMicros) {
public static java.time.LocalDateTime decodePacked64DatetimeMicrosLocalDateTime(
long bitFieldDatetimeMicros) {
checkValidBitField(bitFieldDatetimeMicros, DATETIME_MICROS_MASK);
long bitFieldDatetimeSeconds = bitFieldDatetimeMicros >> MICRO_LENGTH;
LocalDateTime dateTimeSeconds = decodePacked64DatetimeSeconds(bitFieldDatetimeSeconds);
java.time.LocalDateTime dateTimeSeconds =
decodePacked64DatetimeSeconds(bitFieldDatetimeSeconds);
int microOfSecond = getFieldFromBitField(bitFieldDatetimeMicros, MICRO_MASK, MICRO_SHIFT);
checkValidMicroOfSecond(microOfSecond);
LocalDateTime dateTime = dateTimeSeconds.withNano(microOfSecond * 1_000);
java.time.LocalDateTime dateTime = dateTimeSeconds.withNano(microOfSecond * 1_000);
checkValidDateTimeMicros(dateTime);
return dateTime;
}
Expand All @@ -280,25 +326,25 @@ private static int getFieldFromBitField(long bitField, long mask, int shift) {
return (int) ((bitField & mask) >> shift);
}

private static void checkValidTimeSeconds(LocalTime time) {
private static void checkValidTimeSeconds(java.time.LocalTime time) {
checkArgument(time.getHour() >= 0 && time.getHour() <= 23);
checkArgument(time.getMinute() >= 0 && time.getMinute() <= 59);
checkArgument(time.getSecond() >= 0 && time.getSecond() <= 59);
}

private static void checkValidDateTimeSeconds(LocalDateTime dateTime) {
private static void checkValidDateTimeSeconds(java.time.LocalDateTime dateTime) {
checkArgument(dateTime.getYear() >= 1 && dateTime.getYear() <= 9999);
checkArgument(dateTime.getMonthValue() >= 1 && dateTime.getMonthValue() <= 12);
checkArgument(dateTime.getDayOfMonth() >= 1 && dateTime.getDayOfMonth() <= 31);
checkValidTimeSeconds(dateTime.toLocalTime());
}

private static void checkValidTimeMicros(LocalTime time) {
private static void checkValidTimeMicros(java.time.LocalTime time) {
checkValidTimeSeconds(time);
checkArgument(time.equals(time.truncatedTo(ChronoUnit.MICROS)));
}

private static void checkValidDateTimeMicros(LocalDateTime dateTime) {
private static void checkValidDateTimeMicros(java.time.LocalDateTime dateTime) {
checkValidDateTimeSeconds(dateTime);
checkArgument(dateTime.equals(dateTime.truncatedTo(ChronoUnit.MICROS)));
}
Expand Down
Loading

0 comments on commit 8dd66d5

Please sign in to comment.