Java API времени получает смещение от sql Метка времени с учетом хронологии - PullRequest
0 голосов
/ 16 марта 2020

У меня есть следующий код, который получает смещение от sql объекта Timestamp с использованием библиотеки времени Joda.

public static long getOffset(Chronology chronology_, Timestamp timeStamp_)
  {
    long offset = 0;
    if (chronology_ != null)
      {
        offset = chronology_.getZone().getOffset(new DateTime(timeStamp_).getMillis());
      }
    return offset;
  }

Как этого добиться, используя Java 8 API. Я не уверен, требуется ли хронология больше.

1 Ответ

1 голос
/ 16 марта 2020

Хотя концепция хронологии Joda-Time и концепция хронологии java .time (JSR-310) схожи, в вашей ситуации имеет значение: Joda-Time Chronology может ( по желанию) есть часовой пояс. java.time.chrono.Chronology не может. Поэтому вам нужно указать часовой пояс для использования в операции другим способом, чем в хронологии.

Теперь мы подошли к этому, я мог бы предложить вам указать другой момент времени другим способом. чем через java.sql.Timestamp. Таким образом, один из вариантов:

public static long getOffset(ZoneId zone, Instant when)
{
    long offset = 0;
    if (zone != null)
    {
        int offsetSeconds = zone.getRules()
                .getOffset(when)
                .getTotalSeconds();
        offset = TimeUnit.SECONDS.toMillis(offsetSeconds);
    }
    return offset;
}

Если ваш абонент получил устаревший Timestamp от устаревшего API, который он не может изменить, он должен выполнить преобразование. Таким образом, один из способов вызова вышеуказанного метода может быть следующим:

    long offsetMillis = getOffset(
            ZoneId.of("Africa/Khartoum"), theirTimesatmp.toInstant());
    System.out.println(offsetMillis);

Пример вывода с использованием временной отметки примерно сейчас:

7200000

Класс Timestamp плохо спроектирован, настоящий взлом на фоне уже плохо спроектированного класса java.util.Date, поэтому мы не должны его использовать. Если мы не можем избежать его получения, мы должны немедленно преобразовать его в Instant или LocalDateTime и оттуда выполнить или продолжить работу.

Еще одно приятное улучшение будет, если ваш метод вернет ZoneOffset объект, возвращенный с getOffset(), а не число, которое может вызвать вызывающего абонента, задающего вопрос: секунды, миллисекунды или какой-то другой элемент.

Если вы настаиваете на предоставлении удобного метода, который принимает Timestamp, вы Можно конечно добавить обертку, которая дружелюбна к прошлому. Например:

/** @deprecated use {@link #getOffset(ZoneId, Instant)} instead */
public static long getOffset(ZoneId zone, Timestamp timeStampParam)
{
    return getOffset(zone, timeStampParam.toInstant());
}

Ссылка: Преобразование из Joda-Time в java .time в блоге Стивена Колебурна

...