/** * Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.timeseries.precise.zdt; import org.threeten.bp.Instant; import org.threeten.bp.LocalDateTime; import org.threeten.bp.ZoneId; import org.threeten.bp.ZonedDateTime; import org.threeten.bp.jdk8.Jdk8Methods; /** * An encoder between {@code ZonedDateTime} and {@code long}. * <p> * Any far future or maximum instant must be converted to {@code Long.MAX_VALUE}. * Any far past or minimum instant must be converted to {@code Long.MIN_VALUE}. * Other values are encoded as the number of nanoseconds from 1970-01-01, with * a range of +-292 years. */ public final class ZonedDateTimeToLongConverter { /** * Restricted constructor. */ private ZonedDateTimeToLongConverter() { } //------------------------------------------------------------------------- /** * Converts a {@code ZonedDateTime} to a {@code long}. * <p> * See the class Javadoc for the format of the {@code long}. * * @param instant the instant to convert, not null * @return the {@code long} equivalent * @throws IllegalArgumentException if the instant is too large */ public static long convertToLong(ZonedDateTime instant) { if (instant.getYear() >= 1_000_000) { return Long.MAX_VALUE; } if (instant.getYear() <= -1_000_000) { return Long.MIN_VALUE; } try { long secs = Jdk8Methods.safeMultiply(instant.toEpochSecond(), 1_000_000_000); return Jdk8Methods.safeAdd(secs, instant.getNano()); } catch (RuntimeException ex) { throw new IllegalArgumentException("ZonedDateTime is too large/small: " + instant); } } /** * Converts a {@code long} to an {@code ZonedDateTime}. * <p> * See the class Javadoc for the format of the {@code long}. * * @param instant the {@code long} nanos to convert, not null * @param zone the zone to use, not null * @return the {@code ZonedDateTime} equivalent, not null */ public static ZonedDateTime convertToZonedDateTime(long instant, ZoneId zone) { if (instant == Long.MAX_VALUE) { return LocalDateTime.MAX.atZone(zone); } if (instant == Long.MIN_VALUE) { return LocalDateTime.MIN.atZone(zone); } return Instant.ofEpochSecond(0, instant).atZone(zone); } }