All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.time4j.JSR310DurationAdapter Maven / Gradle / Ivy

There is a newer version: 4.38
Show newest version
/*
 * -----------------------------------------------------------------------
 * Copyright © 2013-2016 Meno Hochschild, 
 * -----------------------------------------------------------------------
 * This file (JSR310DurationAdapter.java) is part of project Time4J.
 *
 * Time4J is free software: You can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published
 * by the Free Software Foundation, either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * Time4J is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with Time4J. If not, see .
 * -----------------------------------------------------------------------
 */

package net.time4j;

import net.time4j.engine.TimeSpan;

import java.io.Serializable;
import java.time.DateTimeException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.temporal.ChronoUnit;
import java.time.temporal.IsoFields;
import java.time.temporal.Temporal;
import java.time.temporal.TemporalAmount;
import java.time.temporal.TemporalUnit;
import java.time.temporal.UnsupportedTemporalTypeException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * 

Bridge between {@code net.time4j.Duration} and a {@code TemporalAmount}.

* * @author Meno Hochschild * @since 3.21/4.17 * @doctags.concurrency {immutable} * @serial include */ final class JSR310DurationAdapter implements TemporalAmount, Serializable { //~ Statische Felder/Initialisierungen -------------------------------- private static final Map MAP; static { Map map = new HashMap<>(); map.put(CalendarUnit.MILLENNIA, ChronoUnit.MILLENNIA); map.put(CalendarUnit.CENTURIES, ChronoUnit.CENTURIES); map.put(CalendarUnit.DECADES, ChronoUnit.DECADES); map.put(CalendarUnit.YEARS, ChronoUnit.YEARS); map.put(CalendarUnit.QUARTERS, IsoFields.QUARTER_YEARS); map.put(CalendarUnit.MONTHS, ChronoUnit.MONTHS); map.put(CalendarUnit.WEEKS, ChronoUnit.WEEKS); map.put(CalendarUnit.DAYS, ChronoUnit.DAYS); map.put(CalendarUnit.weekBasedYears(), IsoFields.WEEK_BASED_YEARS); map.put(ClockUnit.HOURS, ChronoUnit.HOURS); map.put(ClockUnit.MINUTES, ChronoUnit.MINUTES); map.put(ClockUnit.SECONDS, ChronoUnit.SECONDS); map.put(ClockUnit.MILLIS, ChronoUnit.MILLIS); map.put(ClockUnit.MICROS, ChronoUnit.MICROS); map.put(ClockUnit.NANOS, ChronoUnit.NANOS); MAP = Collections.unmodifiableMap(map); } //~ Instanzvariablen -------------------------------------------------- /** * @serial the underlying duration of Time4J */ private final Duration duration; //~ Konstruktoren ----------------------------------------------------- JSR310DurationAdapter(Duration duration) { super(); this.duration = duration; for (TimeSpan.Item item : duration.getTotalLength()) { IsoUnit unit = item.getUnit(); if (!MAP.containsKey(unit)) { throw new UnsupportedOperationException("Cannot be used in any TemporalAmount: " + unit); } } } //~ Methoden ---------------------------------------------------------- @Override public long get(TemporalUnit unit) { for (Map.Entry entry : MAP.entrySet()) { if (entry.getValue().equals(unit)) { long amount = this.duration.getPartialAmount(entry.getKey()); if (this.duration.isNegative()) { amount = Math.negateExact(amount); } return amount; } } if (unit.equals(ChronoUnit.HALF_DAYS)) { long hd = Math.floorDiv(this.duration.getPartialAmount(ClockUnit.HOURS), 12); if (this.duration.isNegative()) { hd = Math.negateExact(hd); } return hd; } throw new UnsupportedTemporalTypeException(unit.toString()); // throws NPE if unit is null } @Override public List getUnits() { List units = new ArrayList<>(); for (TimeSpan.Item item : this.duration.getTotalLength()) { IsoUnit unit = item.getUnit(); units.add(MAP.get(unit)); } return Collections.unmodifiableList(units); } @Override public Temporal addTo(Temporal temporal) { return apply(temporal, this.duration); } @Override public Temporal subtractFrom(Temporal temporal) { return apply(temporal, this.duration.inverse()); } private static Temporal apply( Temporal temporal, Duration duration ) { boolean supported = (temporal instanceof LocalDateTime) || (temporal instanceof LocalDate) || (temporal instanceof LocalTime); if (!supported) { throw new DateTimeException( "Duration is only applicable on LocalDate, LocalTime or LocalDateTime."); } long wy = duration.getPartialAmount(CalendarUnit.weekBasedYears()); long m = Math.multiplyExact(duration.getPartialAmount(CalendarUnit.MILLENNIA), 12L * 1000); m = Math.addExact(m, Math.multiplyExact(duration.getPartialAmount(CalendarUnit.CENTURIES), 12L * 100)); m = Math.addExact(m, Math.multiplyExact(duration.getPartialAmount(CalendarUnit.DECADES), 12L * 10)); m = Math.addExact(m, Math.multiplyExact(duration.getPartialAmount(CalendarUnit.YEARS), 12L)); m = Math.addExact(m, Math.multiplyExact(duration.getPartialAmount(CalendarUnit.QUARTERS), 3L)); m = Math.addExact(m, duration.getPartialAmount(CalendarUnit.MONTHS)); long s = Math.multiplyExact(duration.getPartialAmount(CalendarUnit.WEEKS), 7 * 86400L); s = Math.addExact(s, Math.multiplyExact(duration.getPartialAmount(CalendarUnit.DAYS), 86400L)); s = Math.addExact(s, Math.multiplyExact(duration.getPartialAmount(ClockUnit.HOURS), 3600L)); s = Math.addExact(s, Math.multiplyExact(duration.getPartialAmount(ClockUnit.MINUTES), 60L)); s = Math.addExact(s, duration.getPartialAmount(ClockUnit.SECONDS)); long f = duration.getPartialAmount(ClockUnit.NANOS); if (duration.isNegative()) { if (f > 0) { temporal = temporal.minus(f, ChronoUnit.NANOS); } if (s > 0) { temporal = temporal.minus(s, ChronoUnit.SECONDS); } if (m > 0) { temporal = temporal.minus(m, ChronoUnit.MONTHS); } if (wy > 0) { temporal = temporal.minus(wy, IsoFields.WEEK_BASED_YEARS); } } else { if (wy > 0) { temporal = temporal.plus(wy, IsoFields.WEEK_BASED_YEARS); } if (m > 0) { temporal = temporal.plus(m, ChronoUnit.MONTHS); } if (s > 0) { temporal = temporal.plus(s, ChronoUnit.SECONDS); } if (f > 0) { temporal = temporal.plus(f, ChronoUnit.NANOS); } } return temporal; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy