1 /* 2 * Created on 27 juin 2003 3 * Copyright (C) Azureus Software, Inc, All Rights Reserved. 4 * 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU General Public License 7 * as published by the Free Software Foundation; either version 2 8 * of the License, or (at your option) any later version. 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * You should have received a copy of the GNU General Public License 14 * along with this program; if not, write to the Free Software 15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 16 * 17 */ 18 package org.gudy.azureus2.core3.util; 19 20 import java.text.SimpleDateFormat; 21 import java.util.Date; 22 import java.util.Locale; 23 import java.util.TimeZone; 24 25 /** 26 * @author Olivier 27 * 28 */ 29 public class TimeFormatter { 30 // XXX should be i18n'd 31 static final String[] TIME_SUFFIXES = { "s", "m", "h", "d", "y" }; 32 33 public static final String[] DATEFORMATS_DESC = new String[] { 34 "EEEE, MMMM d, yyyy GG", 35 "EEEE, MMMM d, yyyy", 36 "EEE, MMMM d, yyyy", 37 "MMMM d, ''yy", 38 "EEE, MMM d, ''yy", 39 "MMM d, yyyy", 40 "MMM d, ''yy", 41 "yyyy/MM/dd", 42 "''yy/MM/dd", 43 "MMM dd", 44 "MM/dd", 45 }; 46 47 private static final SimpleDateFormat http_date_format = 48 new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US ); 49 50 static{ 51 // see http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.3.1 52 53 http_date_format.setTimeZone(TimeZone.getTimeZone("GMT")); 54 } 55 56 private static final SimpleDateFormat cookie_date_format = 57 new SimpleDateFormat("EEE, dd-MMM-yyyy HH:mm:ss z", Locale.US ); 58 59 static{ 60 // see http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.3.1 61 62 cookie_date_format.setTimeZone(TimeZone.getTimeZone("GMT")); 63 } 64 65 /** 66 * Format time into two time sections, the first chunk trimmed, the second 67 * with always with 2 digits. Sections are *d, **h, **m, **s. Section 68 * will be skipped if 0. 69 * 70 * @param time time in seconds 71 * @return Formatted time string 72 */ format(long time_secs)73 public static String format(long time_secs) { 74 if (time_secs == Constants.CRAPPY_INFINITY_AS_INT || time_secs >= Constants.CRAPPY_INFINITE_AS_LONG) 75 return Constants.INFINITY_STRING; 76 77 if (time_secs < 0) 78 return ""; 79 80 // secs, mins, hours, days 81 int[] vals = { 82 (int) time_secs % 60, 83 (int) (time_secs / 60) % 60, 84 (int) (time_secs / 3600) % 24, 85 (int) (time_secs / 86400) % 365, 86 (int) (time_secs / 31536000) 87 }; 88 89 int end = vals.length - 1; 90 while (vals[end] == 0 && end > 0) { 91 end--; 92 } 93 94 String result = vals[end] + TIME_SUFFIXES[end]; 95 96 /* old logic removed to prefer showing consecutive units 97 // skip until we have a non-zero time section 98 do { 99 end--; 100 } while (end >= 0 && vals[end] == 0); 101 */ 102 103 end--; 104 105 if (end >= 0) 106 result += " " + twoDigits(vals[end]) + TIME_SUFFIXES[end]; 107 108 return result; 109 } 110 111 /** 112 * format seconds into significant y d h m s (e.g. 12d 02h 03m 23s) and drop secs if wanted 113 * @param time_secs 114 * @param do_seconds 115 * @return 116 */ 117 public static String format2( long time_secs, boolean do_seconds )118 format2( 119 long time_secs, 120 boolean do_seconds ) 121 { 122 if (time_secs == Constants.CRAPPY_INFINITY_AS_INT || time_secs >= Constants.CRAPPY_INFINITE_AS_LONG) 123 return Constants.INFINITY_STRING; 124 125 if (time_secs < 0) 126 return ""; 127 128 // secs, mins, hours, days 129 int[] vals = { 130 (int) time_secs % 60, 131 (int) (time_secs / 60) % 60, 132 (int) (time_secs / 3600) % 24, 133 (int) (time_secs / 86400) % 365, 134 (int) (time_secs / 31536000) 135 }; 136 137 int start = vals.length - 1; 138 while (vals[start] == 0 && start > 0) { 139 start--; 140 } 141 142 int end = do_seconds?0:1; 143 144 if ( start==0&&!do_seconds ){ 145 start=1; 146 } 147 148 String result = ""; 149 150 for ( int i=start;i>=end;i--){ 151 152 result += (i==start?vals[i]:(" " + twoDigits(vals[i]))) + TIME_SUFFIXES[i]; 153 } 154 155 return result; 156 } 157 format100ths(long time_millis)158 public static String format100ths(long time_millis) { 159 160 long time_secs = time_millis / 1000; 161 162 int hundredths = (int)(time_millis - time_secs*1000)/10; 163 164 if ( time_millis == 0 || time_secs >= 60 ){ 165 166 return( format( time_secs )); 167 } 168 169 return( time_secs + "." + twoDigits( hundredths) + TIME_SUFFIXES[0]); 170 } 171 172 /** 173 * @param time millis 174 */ 175 formatColonMillis( long time )176 public static String formatColonMillis( long time ) 177 { 178 if ( time > 0 ){ 179 if ( time < 1000 ){ 180 time = 1; 181 }else{ 182 time = time / 1000; 183 } 184 } 185 186 String str = formatColon( time ); 187 188 if ( str.startsWith( "00:" )){ 189 190 str = str.substring( 3 ); 191 } 192 193 return( str ); 194 } 195 196 /** 197 * Format time into "[[# y] # d] 00:00:00" format 198 * 199 * @param time time in seconds 200 * @return 201 */ 202 formatColon(long time)203 public static String formatColon(long time) 204 { 205 if (time == Constants.CRAPPY_INFINITY_AS_INT || time >= Constants.CRAPPY_INFINITE_AS_LONG) return Constants.INFINITY_STRING; 206 if (time < 0) return ""; 207 208 int secs = (int) time % 60; 209 int mins = (int) (time / 60) % 60; 210 int hours = (int) (time /3600) % 24; 211 int days = (int) (time / 86400) % 365; 212 int years = (int) (time / 31536000); 213 214 String result = ""; 215 if (years > 0) result += years + "y "; 216 if (years > 0 || days > 0) result += days + "d "; 217 result += twoDigits(hours) + ":" + twoDigits(mins) + ":" + twoDigits(secs); 218 219 return result; 220 } 221 twoDigits(int i)222 private static String twoDigits(int i) { 223 return (i < 10) ? "0" + i : String.valueOf(i); 224 } 225 226 /** 227 * parse time in h:m:s format to SECONDS 228 * @param str 229 * @return 230 */ 231 232 public static int parseColon( String str )233 parseColon( 234 String str ) 235 { 236 final int[] multipliers = { 1, 60, 3600, 86400, 31536000 }; 237 238 String[] bits = str.split( ":" ); 239 240 int result = 0; 241 242 for (int i=0;i<bits.length;i++){ 243 244 String bit = bits[bits.length-(i+1)].trim(); 245 246 if ( bit.length() > 0 ){ 247 248 result += multipliers[i] * Integer.parseInt( bit ); 249 } 250 } 251 252 return( result ); 253 } 254 255 public static String formatNanoAsMilli( long nanos )256 formatNanoAsMilli( 257 long nanos ) 258 { 259 final long truncator = 60*1000000000L; 260 261 nanos = nanos - ((nanos/truncator) * truncator); 262 263 return( String.valueOf(((double)nanos)/1000000) + " ms" ); 264 } 265 266 public static String getHTTPDate( long millis )267 getHTTPDate( 268 long millis ) 269 { 270 synchronized( http_date_format ){ 271 272 return( http_date_format.format(new Date( millis ))); 273 } 274 } 275 276 public static long parseHTTPDate( String date )277 parseHTTPDate( 278 String date ) 279 { 280 try{ 281 synchronized( http_date_format ){ 282 283 return( http_date_format.parse( date ).getTime()); 284 } 285 }catch( Throwable e ){ 286 287 Debug.out("Failed to parse HTTP date '" + date + "'" ); 288 289 return( 0 ); 290 } 291 } 292 293 public static String getCookieDate( long millis )294 getCookieDate( 295 long millis ) 296 { 297 synchronized( cookie_date_format ){ 298 299 return( cookie_date_format.format(new Date( millis ))); 300 } 301 } 302 303 public static String milliStamp()304 milliStamp() 305 { 306 long nanos = SystemTime.getHighPrecisionCounter(); 307 308 final long truncator = 60*1000000000L; 309 310 nanos = nanos - ((nanos/truncator) * truncator); 311 312 String str = String.valueOf( nanos/1000000 ); 313 314 while( str.length() < 5 ){ 315 316 str = "0" + str; 317 } 318 319 return( str + ": " ); 320 } 321 322 public static void milliTrace( String str )323 milliTrace( 324 String str ) 325 { 326 System.out.println( milliStamp() + str ); 327 } 328 } 329