001/* 002 * #%L 003 * Netarchivesuite - common 004 * %% 005 * Copyright (C) 2005 - 2014 The Royal Danish Library, the Danish State and University Library, 006 * the National Library of France and the Austrian National Library. 007 * %% 008 * This program is free software: you can redistribute it and/or modify 009 * it under the terms of the GNU Lesser General Public License as 010 * published by the Free Software Foundation, either version 2.1 of the 011 * License, or (at your option) any later version. 012 * 013 * This program is distributed in the hope that it will be useful, 014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 016 * GNU General Lesser Public License for more details. 017 * 018 * You should have received a copy of the GNU General Lesser Public 019 * License along with this program. If not, see 020 * <http://www.gnu.org/licenses/lgpl-2.1.html>. 021 * #L% 022 */ 023package dk.netarkivet.common.utils; 024 025import java.util.Calendar; 026 027import dk.netarkivet.common.exceptions.ArgumentNotValid; 028 029/** 030 * Various utilities for waiting some time. 031 */ 032public class TimeUtils { 033 034 /** Constant for the number of milliseconds per second: 1000. */ 035 public static final long SECOND_IN_MILLIS = 1000; 036 /** Constant for the number of seconds per minute: 60. */ 037 public static final long MINUTE_IN_SECONDS = 60; 038 /** Constant for the number of minutes per hour: 60. */ 039 public static final long HOUR_IN_MINUTES = 60; 040 /** Constant for the number of hours per day: 24. */ 041 public static final long DAY_IN_HOURS = 24; 042 /** Constant for the number of days per week: 7. */ 043 public static final long WEEK_IN_DAYS = 7; 044 045 /** 046 * Sleep for an exponentially backing off amount of time, in milliseconds. Thus the first attempt will sleep for 1 047 * ms, the second for 2, the third for 4, etc. 048 * 049 * @param attempt The attempt number, which is the log2 of the number of milliseconds spent asleep. 050 */ 051 public static void exponentialBackoffSleep(int attempt) { 052 exponentialBackoffSleep(attempt, Calendar.MILLISECOND); 053 } 054 055 /** 056 * Sleep for an exponentially backing off amount of time. The mode describes the unit of time as defined by @see 057 * java.util.Calendar 058 * 059 * @param attempt The attempt number, which is the log2 of the number of timeunits spent asleep. 060 * @param timeunit the specified timeunit in miliseconds 061 * @throws ArgumentNotValid if timeunit is unsupported. 062 */ 063 public static void exponentialBackoffSleep(int attempt, int timeunit) { 064 ArgumentNotValid.checkNotNegative(attempt, "int attempt"); 065 ArgumentNotValid.checkTrue(timeunit >= 0 && timeunit < Calendar.FIELD_COUNT, 066 "Time unit must be one of the fields defined" + " by Calendar, not " + timeunit); 067 068 Calendar now = Calendar.getInstance(); 069 long startTime = now.getTimeInMillis(); 070 now.add(timeunit, 1); 071 long endTime = now.getTimeInMillis(); 072 long multiplyBy = endTime - startTime; 073 074 try { 075 Thread.sleep((long) (Math.pow(2, attempt)) * multiplyBy); 076 } catch (InterruptedException e) { 077 // Early wake-up is not a problem 078 } 079 } 080 081 /** 082 * Method for translating a time in milliseconds to a human readable String. E.g. the argument "604800000" should 083 * result in "7 days". 084 * 085 * @param millis The amount of milliseconds. 086 * @return The human readable string. 087 */ 088 public static String readableTimeInterval(long millis) { 089 // check whether it is in seconds (if not return in milliseconds). 090 if ((millis % SECOND_IN_MILLIS) != 0) { 091 if (millis == 1) { 092 return millis + " millisecond"; 093 } 094 return millis + " milliseconds"; 095 } 096 long seconds = millis / SECOND_IN_MILLIS; 097 098 // check whether it is in minutes (if not return in seconds). 099 if ((seconds % MINUTE_IN_SECONDS) != 0) { 100 if (seconds == 1) { 101 return seconds + " second"; 102 } 103 return seconds + " seconds"; 104 } 105 long minutes = seconds / MINUTE_IN_SECONDS; 106 107 // check whether it is in hours (if not return in minutes). 108 if ((minutes % HOUR_IN_MINUTES) != 0) { 109 if (minutes == 1) { 110 return minutes + " minute"; 111 } 112 return minutes + " minutes"; 113 } 114 long hours = minutes / HOUR_IN_MINUTES; 115 116 // check whether it is in days (if not return in hours). 117 if ((hours % DAY_IN_HOURS) != 0) { 118 if (hours == 1) { 119 return hours + " hour"; 120 } 121 return hours + " hours"; 122 } 123 long days = hours / DAY_IN_HOURS; 124 125 if ((days % WEEK_IN_DAYS) != 0) { 126 if (days == 1) { 127 return days + " day"; 128 } 129 return days + " days"; 130 } 131 long weeks = days / WEEK_IN_DAYS; 132 133 if (weeks == 1) { 134 return weeks + " week"; 135 } 136 return weeks + " weeks"; 137 } 138 139}