/**
   * Parses a datetime from the given text, at the given position, saving the result into the fields
   * of the given ReadWritableInstant. If the parse succeeds, the return value is the new text
   * position. Note that the parse may succeed without fully reading the text and in this case those
   * fields that were read will be set.
   *
   * <p>Only those fields present in the string will be changed in the specified instant. All other
   * fields will remain unaltered. Thus if the string only contains a year and a month, then the day
   * and time will be retained from the input instant. If this is not the behaviour you want, then
   * reset the fields before calling this method, or use {@link #parseDateTime(String)} or {@link
   * #parseMutableDateTime(String)}.
   *
   * <p>If it fails, the return value is negative, but the instant may still be modified. To
   * determine the position where the parse failed, apply the one's complement operator (~) on the
   * return value.
   *
   * <p>This parse method ignores the {@link #getDefaultYear() default year} and parses using the
   * year from the supplied instant based on the chronology and time-zone of the supplied instant.
   *
   * <p>The parse will use the chronology of the instant.
   *
   * @param instant an instant that will be modified, not null
   * @param text the text to parse
   * @param position position to start parsing from
   * @return new position, negative value means parse failed - apply complement operator (~) to get
   *     position of failure
   * @throws UnsupportedOperationException if parsing is not supported
   * @throws IllegalArgumentException if the instant is null
   * @throws IllegalArgumentException if any field is out of range
   */
  public int parseInto(ReadWritableInstant instant, String text, int position) {
    InternalParser parser = requireParser();
    if (instant == null) {
      throw new IllegalArgumentException("Instant must not be null");
    }

    long instantMillis = instant.getMillis();
    Chronology chrono = instant.getChronology();
    int defaultYear = DateTimeUtils.getChronology(chrono).year().get(instantMillis);
    long instantLocal = instantMillis + chrono.getZone().getOffset(instantMillis);
    chrono = selectChronology(chrono);

    DateTimeParserBucket bucket =
        new DateTimeParserBucket(instantLocal, chrono, iLocale, iPivotYear, defaultYear);
    int newPos = parser.parseInto(bucket, text, position);
    instant.setMillis(bucket.computeMillis(false, text));
    if (iOffsetParsed && bucket.getOffsetInteger() != null) {
      int parsedOffset = bucket.getOffsetInteger();
      DateTimeZone parsedZone = DateTimeZone.forOffsetMillis(parsedOffset);
      chrono = chrono.withZone(parsedZone);
    } else if (bucket.getZone() != null) {
      chrono = chrono.withZone(bucket.getZone());
    }
    instant.setChronology(chrono);
    if (iZone != null) {
      instant.setZone(iZone);
    }
    return newPos;
  }
  /**
   * Parses a date-time from the given text, returning a new MutableDateTime.
   *
   * <p>The parse will use the zone and chronology specified on this formatter.
   *
   * <p>If the text contains a time zone string then that will be taken into account in adjusting
   * the time of day as follows. If the {@link #withOffsetParsed()} has been called, then the
   * resulting DateTime will have a fixed offset based on the parsed time zone. Otherwise the
   * resulting DateTime will have the zone of this formatter, but the parsed zone may have caused
   * the time to be adjusted.
   *
   * @param text the text to parse, not null
   * @return the parsed date-time, never null
   * @throws UnsupportedOperationException if parsing is not supported
   * @throws IllegalArgumentException if the text to parse is invalid
   */
  public MutableDateTime parseMutableDateTime(String text) {
    InternalParser parser = requireParser();

    Chronology chrono = selectChronology(null);
    DateTimeParserBucket bucket =
        new DateTimeParserBucket(0, chrono, iLocale, iPivotYear, iDefaultYear);
    int newPos = parser.parseInto(bucket, text, 0);
    if (newPos >= 0) {
      if (newPos >= text.length()) {
        long millis = bucket.computeMillis(true, text);
        if (iOffsetParsed && bucket.getOffsetInteger() != null) {
          int parsedOffset = bucket.getOffsetInteger();
          DateTimeZone parsedZone = DateTimeZone.forOffsetMillis(parsedOffset);
          chrono = chrono.withZone(parsedZone);
        } else if (bucket.getZone() != null) {
          chrono = chrono.withZone(bucket.getZone());
        }
        MutableDateTime dt = new MutableDateTime(millis, chrono);
        if (iZone != null) {
          dt.setZone(iZone);
        }
        return dt;
      }
    } else {
      newPos = ~newPos;
    }
    throw new IllegalArgumentException(FormatUtils.createErrorMessage(text, newPos));
  }
Пример #3
0
    @Override
    public boolean equals(Object o) {
      if (this == o) {
        return true;
      }
      if (o == null || getClass() != o.getClass()) {
        return false;
      }

      PeriodGranularity that = (PeriodGranularity) o;

      if (hasOrigin != that.hasOrigin) {
        return false;
      }
      if (origin != that.origin) {
        return false;
      }
      if (!chronology.equals(that.chronology)) {
        return false;
      }
      if (!period.equals(that.period)) {
        return false;
      }

      return true;
    }
Пример #4
0
 private long truncateMillisPeriod(final long t) {
   // toStandardDuration assumes days are always 24h, and hours are always 60 minutes,
   // which may not always be the case, e.g if there are daylight saving changes.
   if (chronology.days().isPrecise() && chronology.hours().isPrecise()) {
     final long millis = period.toStandardDuration().getMillis();
     long offset = t % millis - origin % millis;
     if (offset < 0) {
       offset += millis;
     }
     return t - offset;
   } else {
     throw new UnsupportedOperationException(
         "Period cannot be converted to milliseconds as some fields mays vary in length with chronology "
             + chronology.toString());
   }
 }
Пример #5
0
 private long truncateCompoundPeriod(long t) {
   long current;
   if (t >= origin) {
     long next = origin;
     do {
       current = next;
       next = chronology.add(period, current, 1);
     } while (t >= next);
   } else {
     current = origin;
     do {
       current = chronology.add(period, current, -1);
     } while (t < current);
   }
   return current;
 }
 private void printTo(Appendable appendable, long instant, Chronology chrono) throws IOException {
   InternalPrinter printer = requirePrinter();
   chrono = selectChronology(chrono);
   // Shift instant into local time (UTC) to avoid excessive offset
   // calculations when printing multiple fields in a composite printer.
   DateTimeZone zone = chrono.getZone();
   int offset = zone.getOffset(instant);
   long adjustedInstant = instant + offset;
   if ((instant ^ adjustedInstant) < 0 && (instant ^ offset) >= 0) {
     // Time zone offset overflow, so revert to UTC.
     zone = DateTimeZone.UTC;
     offset = 0;
     adjustedInstant = instant;
   }
   printer.printTo(appendable, adjustedInstant, chrono.withUTC(), offset, zone, iLocale);
 }
  @Override
  public AggregateCount getCounts(String name, Interval interval, DateTimeField resolution) {

    DateTime end = interval.getEnd();
    Chronology c = interval.getChronology();
    DurationField resolutionDuration = resolution.getDurationField();

    long[] counts;

    if (resolutionDuration.getUnitMillis() == DateTimeConstants.MILLIS_PER_MINUTE) {
      // Iterate through each hour in the interval and load the minutes for it
      MutableDateTime dt = new MutableDateTime(interval.getStart());
      dt.setRounding(c.hourOfDay());
      Duration step = Duration.standardHours(1);
      List<long[]> hours = new ArrayList<long[]>();
      while (dt.isBefore(end)) {
        hours.add(getMinCountsForHour(name, dt));
        dt.add(step);
      }
      counts =
          MetricUtils.concatArrays(
              hours,
              interval.getStart().getMinuteOfHour(),
              interval.toPeriod().toStandardMinutes().getMinutes() + 1,
              60);

    } else if (resolutionDuration.getUnitMillis() == DateTimeConstants.MILLIS_PER_HOUR) {
      DateTime cursor = new DateTime(c.dayOfMonth().roundFloor(interval.getStart().getMillis()));
      List<long[]> days = new ArrayList<long[]>();
      Duration step = Duration.standardHours(24);
      while (cursor.isBefore(end)) {
        days.add(getHourCountsForDay(name, cursor));
        cursor = cursor.plus(step);
      }

      counts =
          MetricUtils.concatArrays(
              days,
              interval.getStart().getHourOfDay(),
              interval.toPeriod().toStandardHours().getHours() + 1,
              24);

    } else {
      throw new IllegalArgumentException("Only minute or hour resolution is currently supported");
    }
    return new AggregateCount(name, interval, counts, resolution);
  }
Пример #8
0
 @Override
 public int hashCode() {
   int result = period.hashCode();
   result = 31 * result + chronology.hashCode();
   result = 31 * result + (int) (origin ^ (origin >>> 32));
   result = 31 * result + (hasOrigin ? 1 : 0);
   return result;
 }
 /**
  * Determines the correct chronology to use.
  *
  * @param chrono the proposed chronology
  * @return the actual chronology
  */
 private Chronology selectChronology(Chronology chrono) {
   chrono = DateTimeUtils.getChronology(chrono);
   if (iChrono != null) {
     chrono = iChrono;
   }
   if (iZone != null) {
     chrono = chrono.withZone(iZone);
   }
   return chrono;
 }
Пример #10
0
 @Override
 public String toString() {
   return "PeriodGranularity{"
       + "period="
       + period
       + ", timeZone="
       + chronology.getZone()
       + ", origin="
       + (hasOrigin ? origin : "null")
       + '}';
 }
 /**
  * Create a ZonedChronology for any chronology, overriding any time zone it may already have.
  *
  * @param base base chronology to wrap
  * @param zone the time zone
  * @throws IllegalArgumentException if chronology or time zone is null
  */
 public static ZonedChronology getInstance(Chronology base, DateTimeZone zone) {
   if (base == null) {
     throw new IllegalArgumentException("Must supply a chronology");
   }
   base = base.withUTC();
   if (base == null) {
     throw new IllegalArgumentException("UTC chronology must not be null");
   }
   if (zone == null) {
     throw new IllegalArgumentException("DateTimeZone must not be null");
   }
   return new ZonedChronology(base, zone);
 }
  /**
   * Parses only the local date-time from the given text, returning a new LocalDateTime.
   *
   * <p>This will parse the text fully according to the formatter, using the UTC zone. Once parsed,
   * only the local date-time will be used. This means that any parsed time-zone or offset field is
   * completely ignored. It also means that the zone and offset-parsed settings are ignored.
   *
   * @param text the text to parse, not null
   * @return the parsed date-time, never null
   * @throws UnsupportedOperationException if parsing is not supported
   * @throws IllegalArgumentException if the text to parse is invalid
   * @since 2.0
   */
  public LocalDateTime parseLocalDateTime(String text) {
    InternalParser parser = requireParser();

    Chronology chrono = selectChronology(null).withUTC(); // always use UTC, avoiding DST gaps
    DateTimeParserBucket bucket =
        new DateTimeParserBucket(0, chrono, iLocale, iPivotYear, iDefaultYear);
    int newPos = parser.parseInto(bucket, text, 0);
    if (newPos >= 0) {
      if (newPos >= text.length()) {
        long millis = bucket.computeMillis(true, text);
        if (bucket.getOffsetInteger() != null) { // treat withOffsetParsed() as being true
          int parsedOffset = bucket.getOffsetInteger();
          DateTimeZone parsedZone = DateTimeZone.forOffsetMillis(parsedOffset);
          chrono = chrono.withZone(parsedZone);
        } else if (bucket.getZone() != null) {
          chrono = chrono.withZone(bucket.getZone());
        }
        return new LocalDateTime(millis, chrono);
      }
    } else {
      newPos = ~newPos;
    }
    throw new IllegalArgumentException(FormatUtils.createErrorMessage(text, newPos));
  }
Пример #13
0
 public PeriodGranularity(Period period, DateTime origin, DateTimeZone tz) {
   this.period = period;
   this.chronology = tz == null ? ISOChronology.getInstanceUTC() : ISOChronology.getInstance(tz);
   if (origin == null) {
     // default to origin in given time zone when aligning multi-period granularities
     this.origin =
         new DateTime(0, DateTimeZone.UTC)
             .withZoneRetainFields(chronology.getZone())
             .getMillis();
     this.hasOrigin = false;
   } else {
     this.origin = origin.getMillis();
     this.hasOrigin = true;
   }
   this.isCompound = isCompoundPeriod(period);
 }
Пример #14
0
 @Override
 public DateTime toDateTime(long t) {
   return new DateTime(t, chronology.getZone());
 }
Пример #15
0
 @Override
 public long next(long t) {
   return chronology.add(period, t, 1);
 }
Пример #16
0
    @Override
    public long truncate(long t) {
      if (isCompound) {
        try {
          return truncateMillisPeriod(t);
        } catch (UnsupportedOperationException e) {
          return truncateCompoundPeriod(t);
        }
      }

      final int years = period.getYears();
      if (years > 0) {
        if (years > 1 || hasOrigin) {
          int y = chronology.years().getDifference(t, origin);
          y -= y % years;
          long tt = chronology.years().add(origin, y);
          // always round down to the previous period (for timestamps prior to origin)
          if (t < tt) t = chronology.years().add(tt, -years);
          else t = tt;
          return t;
        } else {
          return chronology.year().roundFloor(t);
        }
      }

      final int months = period.getMonths();
      if (months > 0) {
        if (months > 1 || hasOrigin) {
          int m = chronology.months().getDifference(t, origin);
          m -= m % months;
          long tt = chronology.months().add(origin, m);
          // always round down to the previous period (for timestamps prior to origin)
          if (t < tt) t = chronology.months().add(tt, -months);
          else t = tt;
          return t;
        } else {
          return chronology.monthOfYear().roundFloor(t);
        }
      }

      final int weeks = period.getWeeks();
      if (weeks > 0) {
        if (weeks > 1 || hasOrigin) {
          // align on multiples from origin
          int w = chronology.weeks().getDifference(t, origin);
          w -= w % weeks;
          long tt = chronology.weeks().add(origin, w);
          // always round down to the previous period (for timestamps prior to origin)
          if (t < tt) t = chronology.weeks().add(tt, -weeks);
          else t = tt;
          return t;
        } else {
          t = chronology.dayOfWeek().roundFloor(t);
          // default to Monday as beginning of the week
          return chronology.dayOfWeek().set(t, 1);
        }
      }

      final int days = period.getDays();
      if (days > 0) {
        if (days > 1 || hasOrigin) {
          // align on multiples from origin
          int d = chronology.days().getDifference(t, origin);
          d -= d % days;
          long tt = chronology.days().add(origin, d);
          // always round down to the previous period (for timestamps prior to origin)
          if (t < tt) t = chronology.days().add(tt, -days);
          else t = tt;
          return t;
        } else {
          t = chronology.hourOfDay().roundFloor(t);
          return chronology.hourOfDay().set(t, 0);
        }
      }

      final int hours = period.getHours();
      if (hours > 0) {
        if (hours > 1 || hasOrigin) {
          // align on multiples from origin
          long h = chronology.hours().getDifferenceAsLong(t, origin);
          h -= h % hours;
          long tt = chronology.hours().add(origin, h);
          // always round down to the previous period (for timestamps prior to origin)
          if (t < tt) t = chronology.hours().add(tt, -hours);
          else t = tt;
          return t;
        } else {
          t = chronology.minuteOfHour().roundFloor(t);
          return chronology.minuteOfHour().set(t, 0);
        }
      }

      final int minutes = period.getMinutes();
      if (minutes > 0) {
        // align on multiples from origin
        if (minutes > 1 || hasOrigin) {
          long m = chronology.minutes().getDifferenceAsLong(t, origin);
          m -= m % minutes;
          long tt = chronology.minutes().add(origin, m);
          // always round down to the previous period (for timestamps prior to origin)
          if (t < tt) t = chronology.minutes().add(tt, -minutes);
          else t = tt;
          return t;
        } else {
          t = chronology.secondOfMinute().roundFloor(t);
          return chronology.secondOfMinute().set(t, 0);
        }
      }

      final int seconds = period.getSeconds();
      if (seconds > 0) {
        // align on multiples from origin
        if (seconds > 1 || hasOrigin) {
          long s = chronology.seconds().getDifferenceAsLong(t, origin);
          s -= s % seconds;
          long tt = chronology.seconds().add(origin, s);
          // always round down to the previous period (for timestamps prior to origin)
          if (t < tt) t = chronology.seconds().add(tt, -seconds);
          else t = tt;
          return t;
        } else {
          return chronology.millisOfSecond().set(t, 0);
        }
      }

      final int millis = period.getMillis();
      if (millis > 0) {
        if (millis > 1) {
          long ms = chronology.millis().getDifferenceAsLong(t, origin);
          ms -= ms % millis;
          long tt = chronology.millis().add(origin, ms);
          // always round down to the previous period (for timestamps prior to origin)
          if (t < tt) t = chronology.millis().add(tt, -millis);
          else t = tt;
          return t;
        } else {
          return t;
        }
      }

      return t;
    }
Пример #17
0
 /** Serialization singleton. */
 private Object readResolve() {
   Chronology base = getBase();
   return base == null ? getInstanceUTC() : getInstance(base.getZone());
 }
 /**
  * Get this object as a MutableDateTime using the same chronology but a different zone.
  *
  * @param zone time zone to apply, or default if null
  * @return a MutableDateTime using the same millis
  */
 public MutableDateTime toMutableDateTime(DateTimeZone zone) {
   Chronology chrono = DateTimeUtils.getChronology(getChronology());
   chrono = chrono.withZone(zone);
   return new MutableDateTime(getMillis(), chrono);
 }
Пример #19
0
  /**
   * Parses a UDUNITS time string (of the form "1992-10-8 15:15:42.5 -6:00") and returns a DateTime
   * in the given Chronology.
   *
   * @param baseDateTimeString UDUNITS-formatted time string
   * @param chronology The Chronology (calendar system) in which the time string is to be
   *     interpreted. This must have a time zone of UTC, otherwise an IllegalArgumentException will
   *     be thrown. If this is null, the ISOChronology (in the UTC time zone) will be assumed.
   * @return a DateTime in the given Chronology, with the time zone set to UTC.
   */
  public static DateTime parseUdunitsTimeString(String baseDateTimeString, Chronology chronology) {
    if (chronology == null) chronology = ISOChronology.getInstanceUTC();
    if (!chronology.getZone().equals(DateTimeZone.UTC)) {
      throw new IllegalArgumentException("The time zone of the Chronology must be UTC");
    }

    // Set the defaults for any values that are not specified
    int year = 0;
    int month = 1;
    int day = 1;
    int hour = 0;
    int minute = 0;
    double second = 0.0;

    // We parse the string using a tokenizer to allow for partial strings
    // (e.g. those that contain only the date and not the time)
    StringTokenizer tokenizer = new StringTokenizer(baseDateTimeString, " ");
    try {
      // Parse the date if present
      if (tokenizer.hasMoreTokens()) {
        StringTokenizer dateTokenizer = new StringTokenizer(tokenizer.nextToken(), "-");
        if (dateTokenizer.hasMoreTokens()) year = Integer.parseInt(dateTokenizer.nextToken());
        if (baseDateTimeString.startsWith("-")) {
          /*
           * A '-' was used to denote a negative year.
           */
          year *= -1;
        }
        if (dateTokenizer.hasMoreTokens()) month = Integer.parseInt(dateTokenizer.nextToken());
        if (dateTokenizer.hasMoreTokens()) day = Integer.parseInt(dateTokenizer.nextToken());
      }

      // Parse the time if present
      if (tokenizer.hasMoreTokens()) {
        StringTokenizer timeTokenizer = new StringTokenizer(tokenizer.nextToken(), ":");
        if (timeTokenizer.hasMoreTokens()) hour = Integer.parseInt(timeTokenizer.nextToken());
        if (timeTokenizer.hasMoreTokens()) minute = Integer.parseInt(timeTokenizer.nextToken());
        if (timeTokenizer.hasMoreTokens()) second = Double.parseDouble(timeTokenizer.nextToken());
      }

      // Get a DateTime object in this Chronology
      DateTime dt = new DateTime(year, month, day, hour, minute, 0, 0, chronology);
      // Add the seconds
      dt = dt.plus((long) (1000 * second));

      // Parse the time zone if present
      if (tokenizer.hasMoreTokens()) {
        StringTokenizer zoneTokenizer = new StringTokenizer(tokenizer.nextToken(), ":");
        int hourOffset =
            zoneTokenizer.hasMoreTokens() ? Integer.parseInt(zoneTokenizer.nextToken()) : 0;
        int minuteOffset =
            zoneTokenizer.hasMoreTokens() ? Integer.parseInt(zoneTokenizer.nextToken()) : 0;
        DateTimeZone dtz = DateTimeZone.forOffsetHoursMinutes(hourOffset, minuteOffset);

        // Apply the time zone offset, retaining the field values.  This
        // manipulates the millisecond instance.
        dt = dt.withZoneRetainFields(dtz);
        // Now convert to the UTC time zone, retaining the millisecond instant
        dt = dt.withZone(DateTimeZone.UTC);
      }

      return dt;
    } catch (NumberFormatException nfe) {
      throw new IllegalArgumentException("Illegal base time specification " + baseDateTimeString);
    }
  }
Пример #20
0
 /** Tests the dayOfMonth DateTimeField */
 @Test
 public void testDayOfMonthField() {
   DateTimeField dayOfMonthField = CHRON_NOLEAP.dayOfMonth();
   assertEquals(1, dayOfMonthField.getMinimumValue());
   assertEquals(31, dayOfMonthField.getMaximumValue());
 }