content: package net.csdn.common.unit;
  
  import net.csdn.common.Strings;
  import net.csdn.common.exception.ParseException;
  import org.joda.time.Period;
  import org.joda.time.PeriodType;
  import org.joda.time.format.PeriodFormat;
  import org.joda.time.format.PeriodFormatter;
  
  import java.io.Serializable;
  import java.util.concurrent.TimeUnit;
  
  /**
   * BlogInfo: william
   * Date: 11-9-1
   * Time: 下午4:18
   */
  public class TimeValue implements Serializable {
  
      public static TimeValue timeValueMillis(long millis) {
          return new TimeValue(millis, TimeUnit.MILLISECONDS);
      }
  
      public static TimeValue timeValueSeconds(long seconds) {
          return new TimeValue(seconds, TimeUnit.SECONDS);
      }
  
      public static TimeValue timeValueMinutes(long minutes) {
          return new TimeValue(minutes, TimeUnit.MINUTES);
      }
  
      public static TimeValue timeValueHours(long hours) {
          return new TimeValue(hours, TimeUnit.HOURS);
      }
  
      private long duration;
  
      private TimeUnit timeUnit;
  
      private TimeValue() {
  
      }
  
      public TimeValue(long millis) {
          this(millis, TimeUnit.MILLISECONDS);
      }
  
      public TimeValue(long duration, TimeUnit timeUnit) {
          this.duration = duration;
          this.timeUnit = timeUnit;
      }
  
      public long nanos() {
          return timeUnit.toNanos(duration);
      }
  
      public long getNanos() {
          return nanos();
      }
  
      public long micros() {
          return timeUnit.toMicros(duration);
      }
  
      public long getMicros() {
          return micros();
      }
  
      public long millis() {
          return timeUnit.toMillis(duration);
      }
  
      public long getMillis() {
          return millis();
      }
  
      public long seconds() {
          return timeUnit.toSeconds(duration);
      }
  
      public long getSeconds() {
          return seconds();
      }
  
      public long minutes() {
          return timeUnit.toMinutes(duration);
      }
  
      public long getMinutes() {
          return minutes();
      }
  
      public long hours() {
          return timeUnit.toHours(duration);
      }
  
      public long getHours() {
          return hours();
      }
  
      public long days() {
          return timeUnit.toDays(duration);
      }
  
      public long getDays() {
          return days();
      }
  
      public double microsFrac() {
          return ((double) nanos()) / C1;
      }
  
      public double getMicrosFrac() {
          return microsFrac();
      }
  
      public double millisFrac() {
          return ((double) nanos()) / C2;
      }
  
      public double getMillisFrac() {
          return millisFrac();
      }
  
      public double secondsFrac() {
          return ((double) nanos()) / C3;
      }
  
      public double getSecondsFrac() {
          return secondsFrac();
      }
  
      public double minutesFrac() {
          return ((double) nanos()) / C4;
      }
  
      public double getMinutesFrac() {
          return minutesFrac();
      }
  
      public double hoursFrac() {
          return ((double) nanos()) / C5;
      }
  
      public double getHoursFrac() {
          return hoursFrac();
      }
  
      public double daysFrac() {
          return ((double) nanos()) / C6;
      }
  
      public double getDaysFrac() {
          return daysFrac();
      }
  
      private final PeriodFormatter defaultFormatter = PeriodFormat.getDefault()
              .withParseType(PeriodType.standard());
  
      public String format() {
          Period period = new Period(millis());
          return defaultFormatter.print(period);
      }
  
      public String format(PeriodType type) {
          Period period = new Period(millis());
          return PeriodFormat.getDefault().withParseType(type).print(period);
      }
  
      @Override
      public String toString() {
          if (duration < 0 && timeUnit == TimeUnit.MILLISECONDS) {
              return Long.toString(duration);
          }
          long nanos = nanos();
          if (nanos == 0) {
              return "0s";
          }
          double value = nanos;
          String suffix = "nanos";
          if (nanos >= C6) {
              value = daysFrac();
              suffix = "d";
          } else if (nanos >= C5) {
              value = hoursFrac();
              suffix = "h";
          } else if (nanos >= C4) {
              value = minutesFrac();
              suffix = "m";
          } else if (nanos >= C3) {
              value = secondsFrac();
              suffix = "s";
          } else if (nanos >= C2) {
              value = millisFrac();
              suffix = "ms";
          } else if (nanos >= C1) {
              value = microsFrac();
              suffix = "micros";
          }
          return Strings.format1Decimals(value, suffix);
      }
  
      public static TimeValue parseTimeValue(String sValue) {
          return parseTimeValue(sValue, null);
      }
  
      public static TimeValue parseTimeValue(String sValue, TimeValue defaultValue) {
          if (sValue == null) {
              return defaultValue;
          }
          try {
              long millis;
              if (sValue.endsWith("S")) {
                  millis = Long.parseLong(sValue.substring(0, sValue.length() - 1));
              } else if (sValue.endsWith("ms")) {
                  millis = (long) (Double.parseDouble(sValue.substring(0, sValue.length() - "ms".length())));
              } else if (sValue.endsWith("s")) {
                  millis = (long) (Double.parseDouble(sValue.substring(0, sValue.length() - 1)) * 1000);
              } else if (sValue.endsWith("m")) {
                  millis = (long) (Double.parseDouble(sValue.substring(0, sValue.length() - 1)) * 60 * 1000);
              } else if (sValue.endsWith("H") || sValue.endsWith("h")) {
                  millis = (long) (Double.parseDouble(sValue.substring(0, sValue.length() - 1)) * 60 * 60 * 1000);
              } else if (sValue.endsWith("d")) {
                  millis = (long) (Double.parseDouble(sValue.substring(0, sValue.length() - 1)) * 24 * 60 * 60 * 1000);
              } else if (sValue.endsWith("w")) {
                  millis = (long) (Double.parseDouble(sValue.substring(0, sValue.length() - 1)) * 7 * 24 * 60 * 60 * 1000);
              } else {
                  millis = Long.parseLong(sValue);
              }
              return new TimeValue(millis, TimeUnit.MILLISECONDS);
          } catch (NumberFormatException e) {
              throw new ParseException("Failed to parse [" + sValue + "]", e);
          }
      }
  
      static final long C0 = 1L;
      static final long C1 = C0 * 1000L;
      static final long C2 = C1 * 1000L;
      static final long C3 = C2 * 1000L;
      static final long C4 = C3 * 60L;
      static final long C5 = C4 * 60L;
      static final long C6 = C5 * 24L;
  
  
      @Override
      public boolean equals(Object o) {
          if (this == o) return true;
          if (o == null || getClass() != o.getClass()) return false;
  
          TimeValue timeValue = (TimeValue) o;
  
          if (duration != timeValue.duration) return false;
          if (timeUnit != timeValue.timeUnit) return false;
  
          return true;
      }
  
      @Override
      public int hashCode() {
          int result = (int) (duration ^ (duration >>> 32));
          result = 31 * result + (timeUnit != null ? timeUnit.hashCode() : 0);
          return result;
      }
  }
  