/* * Copyright (c) 1998-2011 Caucho Technology -- all rights reserved * * This file is part of Resin(R) Open Source * * Each copy or derived work must preserve the copyright notice and this * notice unmodified. * * Resin Open Source is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Resin Open Source 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, or any warranty * of NON-INFRINGEMENT. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with Resin Open Source; if not, write to the * * Free Software Foundation, Inc. * 59 Temple Place, Suite 330 * Boston, MA 02111-1307 USA * * @author Scott Ferguson */ package com.caucho.config.types; import com.caucho.config.ConfigException; import com.caucho.util.L10N; import com.caucho.util.QDate; /** * Representations of time in milliseconds. */ public class Period { static L10N L = new L10N(Period.class); public static final long SECOND = 1000L; public static final long MINUTE = 60L * SECOND; public static final long HOUR = 60L * MINUTE; public static final long DAY = 24L * HOUR; /** 30 days */ public static final long MONTH = DAY * 30L; /** 365 days */ public static final long YEAR = DAY * 365L; public static final long INFINITE = (Long.MAX_VALUE / 2 / 1000) * 1000; public static final long FOREVER = INFINITE; private long _period; public Period() { } public Period(long period) { _period = period; } /** * Returns the default units (default is 1000) */ public long getDefaultUnits() { return 1000; } /** * Sets the text. */ public void addText(String text) throws ConfigException { _period = toPeriod(text, getDefaultUnits()); } /** * Replace with the real path. */ public long getPeriod() { return _period; } /** * Converts a period string to a time. * * <table> * <tr><td>ms<td>milliseconds * <tr><td>s<td>seconds * <tr><td>m<td>minutes * <tr><td>h<td>hours * <tr><td>D<td>days * <tr><td>W<td>weeks * <tr><td>M<td>months * <tr><td>Y<td>years * </table> */ public static long toPeriod(String value) throws ConfigException { return toPeriod(value, 1000); } /** * Converts a period string to a time. * * <table> * <tr><td>ms<td>milliseconds * <tr><td>s<td>seconds * <tr><td>m<td>minutes * <tr><td>h<td>hours * <tr><td>D<td>days * <tr><td>W<td>weeks * <tr><td>M<td>months * <tr><td>Y<td>years * </table> */ public static long toPeriod(String value, long defaultUnits) throws ConfigException { if (value == null) return 0; long sign = 1; long period = 0; int i = 0; int length = value.length(); if (length > 0 && value.charAt(i) == '-') { sign = -1; i++; } while (i < length) { long delta = 0; char ch; for (; i < length && (ch = value.charAt(i)) >= '0' && ch <= '9'; i++) delta = 10 * delta + ch - '0'; if (length <= i) period += defaultUnits * delta; else { ch = value.charAt(i++); switch (ch) { case 's': period += 1000 * delta; break; case 'm': if (i < value.length() && value.charAt(i) == 's') { i++; period += delta; } else period += 60 * 1000 * delta; break; case 'h': period += 60L * 60 * 1000 * delta; break; case 'D': period += DAY * delta; break; case 'W': period += 7L * DAY * delta; break; case 'M': period += 30L * DAY * delta; break; case 'Y': period += 365L * DAY * delta; break; default: throw new ConfigException(L.l("Unknown unit `{0}' in period `{1}'. Valid units are:\n '10ms' milliseconds\n '10s' seconds\n '10m' minutes\n '10h' hours\n '10D' days\n '10W' weeks\n '10M' months\n '10Y' years", String.valueOf(ch), value)); } } } period = sign * period; // server/137w /* if (period < 0) return INFINITE; else return period; */ return period; } /** * Calculates the next period end. The calculation is in local time. * * @param now the current time in GMT ms since the epoch * * @return the time of the next period in GMT ms since the epoch */ public static long periodEnd(long now, long period) { QDate localCalendar = QDate.allocateLocalDate(); long endTime = periodEnd(now, period, localCalendar); QDate.freeLocalDate(localCalendar); return endTime; } /** * Calculates the next period end. The calculation is in local time. * * @param now the current time in GMT ms since the epoch * * @return the time of the next period in GMT ms since the epoch */ private static long periodEnd(long now, long period, QDate cal) { if (period < 0) return Long.MAX_VALUE; else if (period == 0) return now; if (period < 30 * DAY) { cal.setGMTTime(now); long localTime = cal.getLocalTime(); localTime = localTime + (period - (localTime + 4 * DAY) % period); cal.setLocalTime(localTime); return cal.getGMTTime(); } if (period % (30 * DAY) == 0) { int months = (int) (period / (30 * DAY)); cal.setGMTTime(now); long year = cal.getYear(); int month = cal.getMonth(); cal.setLocalTime(0); cal.setDate(year, month + months, 1); return cal.getGMTTime(); } if (period % (365 * DAY) == 0) { long years = (period / (365 * DAY)); cal.setGMTTime(now); long year = cal.getYear(); cal.setLocalTime(0); long newYear = year + (years - year % years); cal.setDate(newYear, 0, 1); return cal.getGMTTime(); } cal.setGMTTime(now); long localTime = cal.getLocalTime(); localTime = localTime + (period - (localTime + 4 * DAY) % period); cal.setLocalTime(localTime); return cal.getGMTTime(); } public String toString() { return "Period[" + _period + "]"; } }