/* * * * RHQ Management Platform * * Copyright (C) 2005-2012 Red Hat, Inc. * * All rights reserved. * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License, version 2, as * * published by the Free Software Foundation, and/or the GNU Lesser * * General Public License, version 2.1, also as published by the Free * * Software Foundation. * * * * This program 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 General Public License and the GNU Lesser General Public License * * for more details. * * * * You should have received a copy of the GNU General Public License * * and the GNU Lesser General Public License along with this program; * * if not, write to the Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * */ package org.rhq.server.metrics; import org.joda.time.DateTime; import org.joda.time.DateTimeComparator; import org.joda.time.DateTimeZone; import org.joda.time.Duration; import org.joda.time.Period; /** * Provides common DateTime utility functions. * * @author John Sanda */ public class DateTimeService { static { //[BZ 1161806] // Force the timezone to UTC to avoid any problems due to transitions // from DST to non-DST // This also solves the problem where an HA environment is distributed // in two different timezones DateTimeZone.setDefault(DateTimeZone.UTC); } private DateTimeComparator dateTimeComparator = DateTimeComparator.getInstance(); protected MetricsConfiguration configuration; public void setConfiguration(MetricsConfiguration configuration) { this.configuration = configuration; } /** * This method is preferred over DateTime.now() and System.currentTimeMillis() because it provides a hook for tests. * * @return a DateTime object set to milliseconds. */ public DateTime now() { return new DateTime(nowInMillis()); } public long nowInMillis() { return System.currentTimeMillis(); } public DateTime getTimeSlice(long timestamp, Duration duration) { return getTimeSlice(new DateTime(timestamp), duration); } public DateTime getTimeSlice(DateTime dt, Duration duration) { Period p = duration.toPeriod(); if (p.getYears() != 0) { return dt.yearOfEra().roundFloorCopy().minusYears(dt.getYearOfEra() % p.getYears()); } else if (p.getMonths() != 0) { return dt.monthOfYear().roundFloorCopy().minusMonths((dt.getMonthOfYear() - 1) % p.getMonths()); } else if (p.getWeeks() != 0) { return dt.weekOfWeekyear().roundFloorCopy().minusWeeks((dt.getWeekOfWeekyear() - 1) % p.getWeeks()); } else if (p.getDays() != 0) { return dt.dayOfMonth().roundFloorCopy().minusDays((dt.getDayOfMonth() - 1) % p.getDays()); } else if (p.getHours() != 0) { return dt.hourOfDay().roundFloorCopy().minusHours(dt.getHourOfDay() % p.getHours()); } else if (p.getMinutes() != 0) { return dt.minuteOfHour().roundFloorCopy().minusMinutes(dt.getMinuteOfHour() % p.getMinutes()); } else if (p.getSeconds() != 0) { return dt.secondOfMinute().roundFloorCopy().minusSeconds(dt.getSecondOfMinute() % p.getSeconds()); } return dt.millisOfSecond().roundCeilingCopy().minusMillis(dt.getMillisOfSecond() % p.getMillis()); } public boolean isInRawDataRange(DateTime dateTime) { return dateTimeComparator.compare(now().minus(configuration.getRawRetention()), dateTime) < 0; } public boolean isIn1HourDataRange(DateTime dateTime) { return dateTimeComparator.compare(now().minus(configuration.getOneHourRetention()), dateTime) < 0; } public boolean isIn6HourDataRange(DateTime dateTime) { return dateTimeComparator.compare(now().minus(configuration.getSixHourRetention()), dateTime) < 0; } public boolean isIn24HourDataRange(DateTime dateTime) { return dateTimeComparator.compare(now().minus(configuration.getTwentyFourHourRetention()), dateTime) < 0; } /** * @return A DateTime object rounded down to the start of the current hour. For example, if the current time is * 17:21:09, then 17:00:00 is returned. */ public DateTime currentHour() { return getTimeSlice(now(), configuration.getRawTimeSliceDuration()); } /** * The six hour time slices for a day are fixed - 00:00 to 06:00, 06:00 to 12:00, 12:00 to 18:00, 18:00 to 24:00. * This method determines the six hour time slice based on {@link #currentHour()} and returns the start of the time * slice. * * @return A DateTime object rounded down to the start of the current six hour time slice. */ public DateTime current6HourTimeSlice() { return get6HourTimeSlice(currentHour()); } /** * The 24 hour time slices are fix - 00:00 to 24:00. This method determines the 24 hour time slice based on * {@link #currentHour()} and returns the start of the time slice. * * @return A DateTime object rounded down to the start of the current 24 hour time slice. */ public DateTime current24HourTimeSlice() { return get24HourTimeSlice(currentHour()); } /** * This method determines the 24 hour time slice for the specified time and returns the start of that time slice. * * @param time The DateTime to be rounded down * @return A DateTime rounded down to the start of the 24 hour time slice in which the time parameter falls. * @see #current24HourTimeSlice() */ public DateTime get24HourTimeSlice(DateTime time) { return getTimeSlice(time, configuration.getSixHourTimeSliceDuration()); } public DateTime get24HourTimeSliceEnd(DateTime time) { return get24HourTimeSlice(time).plus(configuration.getSixHourTimeSliceDuration()); } /** * @see #get24HourTimeSlice(org.joda.time.DateTime) */ public DateTime get24HourTimeSlice(long timestamp) { return get24HourTimeSlice(new DateTime(timestamp)); } /** * This method determines the six hour time slice for the specified time and returns the start of that time slice. * * @param time The DateTime to be rounded down * @return A DateTime rounded down to the start of the six hour time slice in which the time parameter falls. * @see #current6HourTimeSlice() */ public DateTime get6HourTimeSlice(DateTime time) { return getTimeSlice(time, configuration.getOneHourTimeSliceDuration()); } /** * @see #get6HourTimeSlice(org.joda.time.DateTime) */ public DateTime get6HourTimeSlice(long timestamp) { return get6HourTimeSlice(new DateTime(timestamp)); } public DateTime get6HourTimeSliceEnd(DateTime time) { return get6HourTimeSlice(time).plus(configuration.getOneHourTimeSliceDuration()); } /** * Determines the one hour time slice for the specified time and returns the start of that time slice * * @param time The DateTime to be rounded down * @return A DateTime rounded down to the start of the hour. */ public DateTime get1HourTimeSlice(DateTime time) { return getTimeSlice(time, configuration.getRawTimeSliceDuration()); } /** * Determines if the current six hour time slice for the specified time has completed. * <p> * Suppose that the current time is 14:23 and that the specified time is 13:15:00 which falls into the * 12:00 - 18:00 time slice. In this case the time slice has not yet finished. * </p> * <p> * Now suppose that the current time is 12:24 and the specified time is 11:34 which falls into the 06:00 - 12:00 * time slice. In this case the time slice has finished. * </p> * * @param time The DateTime to evaluate * @return true if the six hour time slice for the specified time has completed, false otherwise. */ public boolean is6HourTimeSliceFinished(DateTime time) { return hasTimeSliceEnded(get6HourTimeSlice(time), configuration.getOneHourTimeSliceDuration()); } /** * @see #is6HourTimeSliceFinished(org.joda.time.DateTime) */ public boolean is6HourTimeSliceFinished(long timestamp) { return is6HourTimeSliceFinished(new DateTime(timestamp)); } /** * Determines if the current 24 hour time slice for the specified time has completed. * <p> * Suppose that the current time 22:12 Monday and that the specified time is 21:48. The current time slice, i.e., * Monday, has not yet finished. * </p> * <p> * Now suppose that the current time is 01:13 Tuesday and that the specified time is 23:19 Monday. The time slice * for the specified time has finished. * </p> * * @param time The DateTime to evaluate * @return true if the 24 hour time slice for the specified time has completed, false otherwise. */ public boolean is24HourTimeSliceFinished(DateTime time) { return hasTimeSliceEnded(get24HourTimeSlice(time), configuration.getSixHourTimeSliceDuration()); } /** * @see #is24HourTimeSliceFinished(org.joda.time.DateTime) */ public boolean is24HourTimeSliceFinished(long timestamp) { return is24HourTimeSliceFinished(new DateTime(timestamp)); } private boolean hasTimeSliceEnded(DateTime startTime, Duration duration) { DateTime endTime = startTime.plus(duration); return DateTimeComparator.getInstance().compare(currentHour(), endTime) >= 0; } public DateTime hour0() { DateTime rightNow = now(); return rightNow.hourOfDay().roundFloorCopy().minusHours( rightNow.hourOfDay().roundFloorCopy().hourOfDay().get()); } }