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

org.threeten.bp.chrono.JapaneseEra.scala Maven / Gradle / Ivy

/*
 * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *  * Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 *  * Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 *  * Neither the name of JSR-310 nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package org.threeten.bp.chrono

import java.io.Serializable
import java.util.{ Arrays, Objects }
import java.util.concurrent.atomic.AtomicReference

import org.threeten.bp.DateTimeException
import org.threeten.bp.LocalDate
import org.threeten.bp.temporal.ChronoField
import org.threeten.bp.temporal.TemporalField
import org.threeten.bp.temporal.ValueRange

import scala.annotation.meta.field

object JapaneseEra {
  private[chrono] val ERA_OFFSET: Int                  = 2
  private[chrono] val ERA_NAMES: Array[String]         = Array("Meiji", "Taisho", "Showa", "Heisei")
  private[chrono] val ERA_ABBREVIATIONS: Array[String] = Array("M", "T", "S", "H")

  /**
   * The singleton instance for the 'Meiji' era (1868-09-08 - 1912-07-29) which has the value -1.
   */
  lazy val MEIJI: JapaneseEra = new JapaneseEra(-1, LocalDate.of(1868, 9, 8), "Meiji")

  /**
   * The singleton instance for the 'Taisho' era (1912-07-30 - 1926-12-24) which has the value 0.
   */
  lazy val TAISHO: JapaneseEra = new JapaneseEra(0, LocalDate.of(1912, 7, 30), "Taisho")

  /**
   * The singleton instance for the 'Showa' era (1926-12-25 - 1989-01-07) which has the value 1.
   */
  lazy val SHOWA: JapaneseEra = new JapaneseEra(1, LocalDate.of(1926, 12, 25), "Showa")

  /**
   * The singleton instance for the 'Heisei' era (1989-01-08 - current) which has the value 2.
   */
  lazy val HEISEI: JapaneseEra = new JapaneseEra(2, LocalDate.of(1989, 1, 8), "Heisei")

  /**
   * The singleton instance for the 'Reiwa' era (2019-05-01 - current) which has the value 3.
   */
  lazy val REIWA = new JapaneseEra(3, LocalDate.of(2019, 5, 1), "Reiwa")

  /**
   * The value of the additional era.
   */
  private[chrono] val ADDITIONAL_VALUE: Int = 4

  private[chrono] lazy val KNOWN_ERAS: AtomicReference[Array[JapaneseEra]] = new AtomicReference(
    Array(MEIJI, TAISHO, SHOWA, HEISEI, REIWA)
  )

  /**
   * Obtains an instance of {@code JapaneseEra} from an {@code int} value.
   *
   * The {@link #SHOWA} era that contains 1970-01-01 (ISO calendar system) has the value 1 Later era
   * is numbered 2 ({@link #HEISEI}). Earlier eras are numbered 0 ({@link #TAISHO}),
   * -1 ({@link #MEIJI}), only Meiji and later eras are supported.
   *
   * @param japaneseEra
   *   the era to represent
   * @return
   *   the { @code JapaneseEra} singleton, not null
   * @throws DateTimeException
   *   if the value is invalid
   */
  def of(japaneseEra: Int): JapaneseEra = {
    val known = KNOWN_ERAS.get
    if (japaneseEra < MEIJI.eraValue || japaneseEra > known(known.length - 1).eraValue)
      throw new DateTimeException("japaneseEra is invalid")
    known(ordinal(japaneseEra))
  }

  /**
   * Returns the {@code JapaneseEra} with the name.
   *
   * The string must match exactly the name of the era. (Extraneous whitespace characters are not
   * permitted.)
   *
   * @param japaneseEra
   *   the japaneseEra name; non-null
   * @return
   *   the { @code JapaneseEra} singleton, never null
   * @throws IllegalArgumentException
   *   if there is not JapaneseEra with the specified name
   */
  def valueOf(japaneseEra: String): JapaneseEra = {
    Objects.requireNonNull(japaneseEra, "japaneseEra")
    for (era <- KNOWN_ERAS.get)
      if (japaneseEra == era.name)
        return era
    throw new IllegalArgumentException(s"Era not found: $japaneseEra")
  }

  /**
   * Returns an array of JapaneseEras.
   *
   * This method may be used to iterate over the JapaneseEras as follows: 
 for (JapaneseEra c :
   * JapaneseEra.values()) System.out.println(c); 
* * @return * an array of JapaneseEras */ def values: Array[JapaneseEra] = Arrays.copyOf(KNOWN_ERAS.get, KNOWN_ERAS.get.length) /** * Obtains an instance of {@code JapaneseEra} from a date. * * @param date * the date, not null * @return * the Era singleton, never null */ private[chrono] def from(date: LocalDate): JapaneseEra = { if (date.isBefore(MEIJI.since)) throw new DateTimeException(s"Date too early: $date") var i: Int = KNOWN_ERAS.get.length - 1 while (i >= 0) { val era: JapaneseEra = KNOWN_ERAS.get.apply(i) if (date.compareTo(era.since) >= 0) return era i -= 1 } null } /** * Returns the index into the arrays from the Era value. the eraValue is a valid Era number, -999, * -1..2. * @param eraValue * the era value to convert to the index * @return * the index of the current Era */ private def ordinal(eraValue: Int): Int = eraValue + 1 } /** * An era in the Japanese Imperial calendar system. * * This class defines the valid eras for the Japanese chronology. Japan introduced the Gregorian * calendar starting with Meiji 6. Only Meiji and later eras are supported; dates before Meiji 6, * January 1 are not supported.

The four supported eras are hard-coded. A single additional era * may be registered using {@link #registerEra(LocalDate, String)}. * *

Specification for implementors

This class is immutable and thread-safe. * * @constructor * Creates an instance. * * @param eraValue * the era value, validated * @param since * the date representing the first date of the era, validated not null */ final class JapaneseEra private[chrono] ( private val eraValue: Int, @(transient @field) private[chrono] val since: LocalDate, @(transient @field) private val name: String ) extends Era with Serializable { /** * Returns the start date of the era. * @return * the start date */ private[chrono] def startDate: LocalDate = since /** * Returns the end date of the era. * @return * the end date */ private[chrono] def endDate: LocalDate = { val ordinal: Int = JapaneseEra.ordinal(eraValue) val eras: Array[JapaneseEra] = JapaneseEra.values if (ordinal >= eras.length - 1) LocalDate.MAX else eras(ordinal + 1).startDate.minusDays(1) } /** * Returns the numeric value of this {@code JapaneseEra}. * * The {@link #SHOWA} era that contains 1970-01-01 (ISO calendar system) has the value 1. Later * eras are numbered from 2 ({@link #HEISEI}). Earlier eras are numbered 0 ({@link #TAISHO}) and * -1 ({@link #MEIJI}). * * @return * the era value */ def getValue: Int = eraValue override def range(field: TemporalField): ValueRange = if (field eq ChronoField.ERA) JapaneseChronology.INSTANCE.range(ChronoField.ERA) else super.range(field) override def toString: String = name }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy