content: /*
   * Licensed to the Apache Software Foundation (ASF) under one or more
   * contributor license agreements.  See the NOTICE file distributed with
   * this work for additional information regarding copyright ownership.
   * The ASF licenses this file to you 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
   *
   * http://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 org.apache.calcite.avatica.util;
  
  import java.math.BigDecimal;
  
  /**
   * Enumeration of time units used to construct an interval.
   *
   * <p>Only {@link #YEAR}, {@link #MONTH}, {@link #DAY},
   * {@link #HOUR}, {@link #MINUTE}, {@link #SECOND} can be the unit of a SQL
   * interval.
   *
   * <p>The others ({@link #QUARTER}, {@link #WEEK}, {@link #MILLISECOND},
   * {@link #DOW}, {@link #DOY}, {@link #EPOCH}, {@link #DECADE}, {@link #CENTURY},
   * {@link #MILLENNIUM}, {@link #MICROSECOND}, {@link #NANOSECOND}, {@link #ISODOW}
   * and {@link #ISOYEAR}) are convenient to use internally,
   * when converting to and from UNIX timestamps.
   * And also may be arguments to the {@code EXTRACT}, {@code TIMESTAMPADD} and
   * {@code TIMESTAMPDIFF} functions.
   */
  public enum TimeUnit {
    YEAR(true, ' ', BigDecimal.valueOf(12) /* months */, null),
    MONTH(true, '-', BigDecimal.ONE /* months */, BigDecimal.valueOf(12)),
    DAY(false, '-', BigDecimal.valueOf(DateTimeUtils.MILLIS_PER_DAY), null),
    HOUR(false, ' ', BigDecimal.valueOf(DateTimeUtils.MILLIS_PER_HOUR),
        BigDecimal.valueOf(24)),
    MINUTE(false, ':', BigDecimal.valueOf(DateTimeUtils.MILLIS_PER_MINUTE),
        BigDecimal.valueOf(60)),
    SECOND(false, ':', BigDecimal.valueOf(DateTimeUtils.MILLIS_PER_SECOND),
        BigDecimal.valueOf(60)),
  
    QUARTER(true, '*', BigDecimal.valueOf(3) /* months */, BigDecimal.valueOf(4)),
    ISOYEAR(true, ' ', BigDecimal.valueOf(12) /* months */, null),
    WEEK(false, '*', BigDecimal.valueOf(DateTimeUtils.MILLIS_PER_DAY * 7),
        BigDecimal.valueOf(53)),
    MILLISECOND(false, '.', BigDecimal.ONE, BigDecimal.valueOf(1000)),
    MICROSECOND(false, '.', BigDecimal.ONE.scaleByPowerOfTen(-3),
        BigDecimal.valueOf(1000_000)),
    NANOSECOND(false, '.', BigDecimal.ONE.scaleByPowerOfTen(-6),
        BigDecimal.valueOf(1000_000_000)),
    DOW(false, '-', null, null),
    ISODOW(false, '-', null, null),
    DOY(false, '-', null, null),
    EPOCH(false, '*', null, null),
    DECADE(true, '*', BigDecimal.valueOf(120) /* months */, null),
    CENTURY(true, '*', BigDecimal.valueOf(1200) /* months */, null),
    MILLENNIUM(true, '*', BigDecimal.valueOf(12000) /* months */, null);
  
    public final boolean yearMonth;
    public final char separator;
    public final BigDecimal multiplier;
    private final BigDecimal limit;
  
    private static final TimeUnit[] CACHED_VALUES = values();
  
    TimeUnit(boolean yearMonth, char separator, BigDecimal multiplier,
        BigDecimal limit) {
      this.yearMonth = yearMonth;
      this.separator = separator;
      this.multiplier = multiplier;
      this.limit = limit;
    }
  
    /**
     * Returns the TimeUnit associated with an ordinal. The value returned
     * is null if the ordinal is not a member of the TimeUnit enumeration.
     */
    public static TimeUnit getValue(int ordinal) {
      return ordinal < 0 || ordinal >= CACHED_VALUES.length
          ? null
          : CACHED_VALUES[ordinal];
    }
  
    /**
     * Returns whether a given value is valid for a field of this time unit.
     *
     * @param field Field value
     * @return Whether value
     */
    public boolean isValidValue(BigDecimal field) {
      return field.compareTo(BigDecimal.ZERO) >= 0
          && (limit == null
          || field.compareTo(limit) < 0);
    }
  }
  
  // End TimeUnit.java
  