001/** 002 * Logback: the reliable, generic, fast and flexible logging framework. 003 * Copyright (C) 1999-2015, QOS.ch. All rights reserved. 004 * 005 * This program and the accompanying materials are dual-licensed under 006 * either the terms of the Eclipse Public License v1.0 as published by 007 * the Eclipse Foundation 008 * 009 * or (per the licensee's choosing) 010 * 011 * under the terms of the GNU Lesser General Public License version 2.1 012 * as published by the Free Software Foundation. 013 */ 014package ch.qos.logback.core.util; 015 016import java.util.regex.Matcher; 017import java.util.regex.Pattern; 018 019/** 020 * Duration instances represent a lapse of time. Internally, the duration is 021 * stored in milliseconds. However, whenever a parameter of type Duration is 022 * expected, Joran (logback's configuration system) will automatically convert 023 * strings such as "20 seconds" "3.5 minutes" or "5 hours" into Duration 024 * instances. 025 * 026 * <p> 027 * The recognized units of time are the "millisecond", "second", "minute" "hour" 028 * and "day". The unit name may be followed by an "s". Thus, "2 day" and "2 029 * days" are equivalent. In the absence of a time unit specification, 030 * milliseconds are assumed. 031 * 032 * <p> 033 * Note: the conversion magic is entirely due to the fact that this class 034 * follows the {@link #valueOf} convention. 035 * 036 * @author Ceki Gulcu 037 */ 038public class Duration { 039 040 private final static String DOUBLE_PART = "([0-9]*(.[0-9]+)?)"; 041 private final static int DOUBLE_GROUP = 1; 042 043 private final static String UNIT_PART = "(|milli(second)?|second(e)?|minute|hour|day)s?"; 044 private final static int UNIT_GROUP = 3; 045 046 private static final Pattern DURATION_PATTERN = Pattern.compile(DOUBLE_PART + "\\s*" + UNIT_PART, 047 Pattern.CASE_INSENSITIVE); 048 049 static final long SECONDS_COEFFICIENT = 1000; 050 static final long MINUTES_COEFFICIENT = 60 * SECONDS_COEFFICIENT; 051 static final long HOURS_COEFFICIENT = 60 * MINUTES_COEFFICIENT; 052 static final long DAYS_COEFFICIENT = 24 * HOURS_COEFFICIENT; 053 054 final long millis; 055 056 public Duration(long millis) { 057 this.millis = millis; 058 } 059 060 public static Duration buildByMilliseconds(double value) { 061 return new Duration((long) (value)); 062 } 063 064 public static Duration buildBySeconds(double value) { 065 return new Duration((long) (SECONDS_COEFFICIENT * value)); 066 } 067 068 public static Duration buildByMinutes(double value) { 069 return new Duration((long) (MINUTES_COEFFICIENT * value)); 070 } 071 072 public static Duration buildByHours(double value) { 073 return new Duration((long) (HOURS_COEFFICIENT * value)); 074 } 075 076 public static Duration buildByDays(double value) { 077 return new Duration((long) (DAYS_COEFFICIENT * value)); 078 } 079 080 public static Duration buildUnbounded() { 081 return new Duration(Long.MAX_VALUE); 082 } 083 084 public long getMilliseconds() { 085 return millis; 086 } 087 088 public static Duration valueOf(String durationStr) { 089 Matcher matcher = DURATION_PATTERN.matcher(durationStr); 090 091 if (matcher.matches()) { 092 String doubleStr = matcher.group(DOUBLE_GROUP); 093 String unitStr = matcher.group(UNIT_GROUP); 094 095 double doubleValue = Double.valueOf(doubleStr); 096 if (unitStr.equalsIgnoreCase("milli") || unitStr.equalsIgnoreCase("millisecond") || unitStr.length() == 0) { 097 return buildByMilliseconds(doubleValue); 098 } else if (unitStr.equalsIgnoreCase("second") || unitStr.equalsIgnoreCase("seconde")) { 099 return buildBySeconds(doubleValue); 100 } else if (unitStr.equalsIgnoreCase("minute")) { 101 return buildByMinutes(doubleValue); 102 } else if (unitStr.equalsIgnoreCase("hour")) { 103 return buildByHours(doubleValue); 104 } else if (unitStr.equalsIgnoreCase("day")) { 105 return buildByDays(doubleValue); 106 } else { 107 throw new IllegalStateException("Unexpected " + unitStr); 108 } 109 } else { 110 throw new IllegalArgumentException("String value [" + durationStr + "] is not in the expected format."); 111 } 112 } 113 114 @Override 115 public String toString() { 116 if (millis < SECONDS_COEFFICIENT) { 117 return millis + " milliseconds"; 118 } else if (millis < MINUTES_COEFFICIENT) { 119 return millis / SECONDS_COEFFICIENT + " seconds"; 120 } else if (millis < HOURS_COEFFICIENT) { 121 return millis / MINUTES_COEFFICIENT + " minutes"; 122 } else { 123 return millis / HOURS_COEFFICIENT + " hours"; 124 } 125 126 } 127}