diff --git a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java index e79b841c9967773c6d5b07b1d12dc1fc505e2fc1..e9180bef40b3539b9c0e66f1739090de18ad205a 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java +++ b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java @@ -803,7 +803,7 @@ public class I2PSnarkServlet extends Default { out.write("<td align=\"center\" class=\"snarkTorrentETA " + rowClass + "\">"); if(isRunning && remainingSeconds > 0) - out.write(DataHelper.formatDuration(remainingSeconds*1000)); // (eta 6h) + out.write(DataHelper.formatDuration2(remainingSeconds*1000)); // (eta 6h) out.write("</td>\n\t"); out.write("<td align=\"right\" class=\"snarkTorrentDownloaded " + rowClass + "\">"); if (remaining > 0) diff --git a/apps/routerconsole/java/bundle-messages.sh b/apps/routerconsole/java/bundle-messages.sh index 548f7f768a7b08c5b14fe4e787f5fad36fbeb150..dd422bf064c0251f0838e7acc51a3f7d31a60b3e 100755 --- a/apps/routerconsole/java/bundle-messages.sh +++ b/apps/routerconsole/java/bundle-messages.sh @@ -32,8 +32,9 @@ then sed 's/..,\(..*\)/_("\1");/' $CFILE >> $JFILE fi -# list specific files in router/ here, so we don't scan the whole tree +# list specific files in core/ and router/ here, so we don't scan the whole tree ROUTERFILES="\ + ../../../core/java/src/net/i2p/data/DataHelper.java \ ../../../router/java/src/net/i2p/router/RouterThrottleImpl.java \ ../../../router/java/src/net/i2p/router/tunnel/pool/BuildHandler.java \ ../../../router/java/src/net/i2p/router/transport/TransportManager.java \ diff --git a/apps/routerconsole/java/src/net/i2p/router/web/ConfigRestartBean.java b/apps/routerconsole/java/src/net/i2p/router/web/ConfigRestartBean.java index aacdfc91a959fd956f724a262d496d7cddbc2fca..ccd96e7a0eb4def70a6dee669d897ea152fc0d12 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/ConfigRestartBean.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/ConfigRestartBean.java @@ -62,12 +62,12 @@ public class ConfigRestartBean { buf.append("</b></center>"); } else if (shuttingDown) { buf.append("<center><b>"); - buf.append(_("Shutdown in {0}", DataHelper.formatDuration(timeRemaining), ctx)); + buf.append(_("Shutdown in {0}", DataHelper.formatDuration2(timeRemaining), ctx)); buf.append("</b></center><br>"); buttons(ctx, buf, urlBase, systemNonce, SET1); } else if (restarting) { buf.append("<center><b>"); - buf.append(_("Restart in {0}", DataHelper.formatDuration(timeRemaining), ctx)); + buf.append(_("Restart in {0}", DataHelper.formatDuration2(timeRemaining), ctx)); buf.append("</b></center><br>"); buttons(ctx, buf, urlBase, systemNonce, SET2); } else { diff --git a/apps/routerconsole/java/src/net/i2p/router/web/ConfigUpdateHandler.java b/apps/routerconsole/java/src/net/i2p/router/web/ConfigUpdateHandler.java index d20524bfb568c89c380ba242b85b5460ac7ee0f1..72acbb5404aa56ba05dca95e94d8c22348c5ff0c 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/ConfigUpdateHandler.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/ConfigUpdateHandler.java @@ -130,7 +130,7 @@ public class ConfigUpdateHandler extends FormHandler { try { oldFreq = Long.parseLong(oldFreqStr); } catch (NumberFormatException nfe) {} if (_refreshFrequency != oldFreq) { _context.router().setConfigSetting(PROP_REFRESH_FREQUENCY, ""+_refreshFrequency); - addFormNotice(_("Updating refresh frequency to") + " " + DataHelper.formatDuration(_refreshFrequency)); + addFormNotice(_("Updating refresh frequency to") + " " + DataHelper.formatDuration2(_refreshFrequency)); } if ( (_updatePolicy != null) && (_updatePolicy.length() > 0) ) { diff --git a/apps/routerconsole/java/src/net/i2p/router/web/ConfigUpdateHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/ConfigUpdateHelper.java index 520c13104e44cde2a304767a34436d146f21d991..2e03ad93f8bf2942331ed700a758c5c41c9f530b 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/ConfigUpdateHelper.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/ConfigUpdateHelper.java @@ -87,7 +87,7 @@ public class ConfigUpdateHelper extends HelperBase { if (PERIODS[i] == -1) buf.append("\">" + _("Never") + "</option>\n"); else - buf.append("\">" + _("Every") + " ").append(DataHelper.formatDuration(PERIODS[i])).append("</option>\n"); + buf.append("\">" + _("Every") + " ").append(DataHelper.formatDuration2(PERIODS[i])).append("</option>\n"); } buf.append("</select>\n"); return buf.toString(); diff --git a/apps/routerconsole/java/src/net/i2p/router/web/GraphHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/GraphHelper.java index 94dc08b98aebcedf84b978bcfcec757751dd00a8..8fc78e7900a6e5e1afaa6d9384ecda9488062380 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/GraphHelper.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/GraphHelper.java @@ -93,7 +93,7 @@ public class GraphHelper extends HelperBase { SummaryListener lsnr = (SummaryListener)iter.next(); Rate r = lsnr.getRate(); // e.g. "statname for 60m" - String title = _("{0} for {1}", r.getRateStat().getName(), DataHelper.formatDuration(_periodCount * r.getPeriod())); + String title = _("{0} for {1}", r.getRateStat().getName(), DataHelper.formatDuration2(_periodCount * r.getPeriod())); _out.write("<a href=\"viewstat.jsp?stat=" + r.getRateStat().getName() + "&showEvents=" + _showEvents diff --git a/apps/routerconsole/java/src/net/i2p/router/web/NetDbRenderer.java b/apps/routerconsole/java/src/net/i2p/router/web/NetDbRenderer.java index a2c5632fa8e0e4d57e750d3f60447b3469f6d605..d2b0a17e903c17308b8d077904826c3f1f66814f 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/NetDbRenderer.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/NetDbRenderer.java @@ -150,9 +150,9 @@ public class NetDbRenderer { buf.append(")</b><br>\n"); long exp = ls.getEarliestLeaseDate()-now; if (exp > 0) - buf.append(_("Expires in {0}", DataHelper.formatDuration(exp))).append("<br>\n"); + buf.append(_("Expires in {0}", DataHelper.formatDuration2(exp))).append("<br>\n"); else - buf.append(_("Expired {0} ago", DataHelper.formatDuration(0-exp))).append("<br>\n"); + buf.append(_("Expired {0} ago", DataHelper.formatDuration2(0-exp))).append("<br>\n"); if (debug) { buf.append("RAP? " + ls.getReceivedAsPublished() + ' '); buf.append("RAR? " + ls.getReceivedAsReply() + ' '); @@ -352,13 +352,13 @@ public class NetDbRenderer { long age = _context.clock().now() - info.getPublished(); if (isUs && _context.router().isHidden()) { buf.append("<b>").append(_("Hidden")).append(", ").append(_("Updated")).append(":</b> ") - .append(_("{0} ago", DataHelper.formatDuration(age))).append("<br>\n"); + .append(_("{0} ago", DataHelper.formatDuration2(age))).append("<br>\n"); } else if (age > 0) { buf.append("<b>").append(_("Published")).append(":</b> ") - .append(_("{0} ago", DataHelper.formatDuration(age))).append("<br>\n"); + .append(_("{0} ago", DataHelper.formatDuration2(age))).append("<br>\n"); } else { // shouldnt happen - buf.append("<b>" + _("Published") + ":</b> in ").append(DataHelper.formatDuration(0-age)).append("???<br>\n"); + buf.append("<b>" + _("Published") + ":</b> in ").append(DataHelper.formatDuration2(0-age)).append("???<br>\n"); } buf.append("<b>" + _("Address(es)") + ":</b> "); String country = _context.commSystem().getCountry(info.getIdentity().getHash()); diff --git a/apps/routerconsole/java/src/net/i2p/router/web/NewsFetcher.java b/apps/routerconsole/java/src/net/i2p/router/web/NewsFetcher.java index df576254c91e9bdae4e15cd2172dc29d8615899d..71cb982c9ab467ecad11f56b63e277fd00dde056 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/NewsFetcher.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/NewsFetcher.java @@ -80,13 +80,13 @@ public class NewsFetcher implements Runnable, EepGet.StatusListener { long now = _context.clock().now(); if (_lastUpdated > 0) { buf.append(Messages.getString("News last updated {0} ago.", - DataHelper.formatDuration(now - _lastUpdated), + DataHelper.formatDuration2(now - _lastUpdated), _context)) .append('\n'); } if (_lastFetch > _lastUpdated) { buf.append(Messages.getString("News last checked {0} ago.", - DataHelper.formatDuration(now - _lastFetch), + DataHelper.formatDuration2(now - _lastFetch), _context)); } return buf.toString(); @@ -136,7 +136,7 @@ public class NewsFetcher implements Runnable, EepGet.StatusListener { return true; } else { if (_log.shouldLog(Log.DEBUG)) - _log.debug("Last fetched " + DataHelper.formatDuration(_context.clock().now() - _lastFetch) + " ago"); + _log.debug("Last fetched " + DataHelper.formatDuration2(_context.clock().now() - _lastFetch) + " ago"); return false; } } catch (NumberFormatException nfe) { diff --git a/apps/routerconsole/java/src/net/i2p/router/web/ProfileOrganizerRenderer.java b/apps/routerconsole/java/src/net/i2p/router/web/ProfileOrganizerRenderer.java index f1824930b7df195f531d92d5003196ebf60ba557..7265578730beb42756aede5e933fada97b4b2bc0 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/ProfileOrganizerRenderer.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/ProfileOrganizerRenderer.java @@ -217,26 +217,26 @@ class ProfileOrganizerRenderer { buf.append("<td align=\"right\">").append(num(prof.getIntegrationValue())).append("</td>"); long time; time = now - prof.getLastHeardAbout(); - buf.append("<td align=\"right\">").append(DataHelper.formatDuration(time)).append("</td>"); + buf.append("<td align=\"right\">").append(DataHelper.formatDuration2(time)).append("</td>"); time = now - prof.getLastHeardFrom(); - buf.append("<td align=\"right\">").append(DataHelper.formatDuration(time)).append("</td>"); + buf.append("<td align=\"right\">").append(DataHelper.formatDuration2(time)).append("</td>"); time = now - prof.getLastSendSuccessful(); - buf.append("<td align=\"right\">").append(DataHelper.formatDuration(time)).append("</td>"); + buf.append("<td align=\"right\">").append(DataHelper.formatDuration2(time)).append("</td>"); time = now - prof.getLastSendFailed(); - buf.append("<td align=\"right\">").append(DataHelper.formatDuration(time)).append("</td>"); + buf.append("<td align=\"right\">").append(DataHelper.formatDuration2(time)).append("</td>"); buf.append("<td align=\"right\">").append(avg(prof, 10*60*1000l)).append("</td>"); buf.append("<td align=\"right\">").append(avg(prof, 60*60*1000l)).append("</td>"); buf.append("<td align=\"right\">").append(avg(prof, 24*60*60*1000l)).append("</td>"); DBHistory dbh = prof.getDBHistory(); if (dbh != null) { time = now - dbh.getLastLookupSuccessful(); - buf.append("<td align=\"right\">").append(DataHelper.formatDuration(time)).append("</td>"); + buf.append("<td align=\"right\">").append(DataHelper.formatDuration2(time)).append("</td>"); time = now - dbh.getLastLookupFailed(); - buf.append("<td align=\"right\">").append(DataHelper.formatDuration(time)).append("</td>"); + buf.append("<td align=\"right\">").append(DataHelper.formatDuration2(time)).append("</td>"); time = now - dbh.getLastStoreSuccessful(); - buf.append("<td align=\"right\">").append(DataHelper.formatDuration(time)).append("</td>"); + buf.append("<td align=\"right\">").append(DataHelper.formatDuration2(time)).append("</td>"); time = now - dbh.getLastStoreFailed(); - buf.append("<td align=\"right\">").append(DataHelper.formatDuration(time)).append("</td>"); + buf.append("<td align=\"right\">").append(DataHelper.formatDuration2(time)).append("</td>"); buf.append("<td align=\"right\">").append(davg(dbh, 60*60*1000l)).append("</td>"); buf.append("<td align=\"right\">").append(davg(dbh, 24*60*60*1000l)).append("</td>"); } else { @@ -323,7 +323,7 @@ class ProfileOrganizerRenderer { if (c == 0) return _(NA); double d = r.getCurrentTotalValue() + r.getLastTotalValue(); - return Math.round(d/c) + "ms"; + return DataHelper.formatDuration2(Math.round(d/c)); } private String davg (DBHistory dbh, long rate) { diff --git a/apps/routerconsole/java/src/net/i2p/router/web/ShitlistRenderer.java b/apps/routerconsole/java/src/net/i2p/router/web/ShitlistRenderer.java index 48af67857a049dd109af3a45585371cc73f4c045..f0b9c910bb25b5ab6964b78a6fd6b9f42bc45c2b 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/ShitlistRenderer.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/ShitlistRenderer.java @@ -52,7 +52,7 @@ public class ShitlistRenderer { buf.append("<li>").append(_context.commSystem().renderPeerHTML(key)); buf.append(' '); long expires = entry.expireOn-_context.clock().now(); - String expireString = DataHelper.formatDuration(expires); + String expireString = DataHelper.formatDuration2(expires); if (expires < 5l*24*60*60*1000) buf.append(_("Temporary ban expiring in {0}", expireString)); else diff --git a/apps/routerconsole/java/src/net/i2p/router/web/SummaryBarRenderer.java b/apps/routerconsole/java/src/net/i2p/router/web/SummaryBarRenderer.java index 8447db4127152e23a95e8f58dd88a0ce5dfecb7b..50fe1f54dfdae1b5962cd6a92d5cd1bf04a6b15c 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/SummaryBarRenderer.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/SummaryBarRenderer.java @@ -366,7 +366,7 @@ public class SummaryBarRenderer { .append(_("Used")) .append(":</b></td><td align=\"right\">") .append(_helper.getInboundTransferred()) - .append(" / ") + .append(" / ") .append(_helper.getOutboundTransferred()) .append("</td></tr></table>\n" + diff --git a/apps/routerconsole/java/src/net/i2p/router/web/SummaryHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/SummaryHelper.java index d5e64a1af41e8861043d4bc36db231a4c98c5fd3..5f2cb891b7e92312dc49ce46a39663b79f7b1faa 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/SummaryHelper.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/SummaryHelper.java @@ -60,7 +60,7 @@ public class SummaryHelper extends HelperBase { if (router == null) return "[not up]"; else - return DataHelper.formatDuration(router.getUptime()); + return DataHelper.formatDuration2(router.getUptime()); } /** @@ -74,7 +74,7 @@ public class SummaryHelper extends HelperBase { long diff = Math.abs(ms); if (diff < 3000) return ""; - return " (" + DataHelper.formatDuration(diff) + " " + _("skew") + ")"; + return " (" + DataHelper.formatDuration2(diff) + " " + _("skew") + ")"; } **/ @@ -105,7 +105,7 @@ public class SummaryHelper extends HelperBase { long skew = _context.commSystem().getFramedAveragePeerClockSkew(33); // Display the actual skew, not the offset if (Math.abs(skew) > 30*1000) - return _("ERR-Clock Skew of {0}", DataHelper.formatDuration(Math.abs(skew))); + return _("ERR-Clock Skew of {0}", DataHelper.formatDuration2(Math.abs(skew))); if (_context.router().isHidden()) return _("Hidden"); @@ -321,7 +321,7 @@ public class SummaryHelper extends HelperBase { fmt = new DecimalFormat("#0.0"); else fmt = new DecimalFormat("#0.00"); - return fmt.format(in) + " / " + fmt.format(out) + + return fmt.format(in) + " / " + fmt.format(out) + " " + (mega ? 'M' : 'K'); } @@ -336,7 +336,7 @@ public class SummaryHelper extends HelperBase { long received = _context.bandwidthLimiter().getTotalAllocatedInboundBytes(); - return DataHelper.formatSize(received) + 'B'; + return DataHelper.formatSize2(received) + 'B'; } /** @@ -349,7 +349,7 @@ public class SummaryHelper extends HelperBase { return "0"; long sent = _context.bandwidthLimiter().getTotalAllocatedOutboundBytes(); - return DataHelper.formatSize(sent) + 'B'; + return DataHelper.formatSize2(sent) + 'B'; } /** @@ -389,7 +389,7 @@ public class SummaryHelper extends HelperBase { long timeToExpire = ls.getEarliestLeaseDate() - _context.clock().now(); if (timeToExpire < 0) { // red or yellow light - buf.append("<td><img src=\"/themes/console/images/local_inprogress.png\" alt=\"").append(_("Rebuilding")).append("…\" title=\"").append(_("Leases expired")).append(" ").append(DataHelper.formatDuration(0-timeToExpire)); + buf.append("<td><img src=\"/themes/console/images/local_inprogress.png\" alt=\"").append(_("Rebuilding")).append("…\" title=\"").append(_("Leases expired")).append(" ").append(DataHelper.formatDuration2(0-timeToExpire)); buf.append(" ").append(_("ago")).append(". ").append(_("Rebuilding")).append("…\"></td></tr>\n"); } else { // green light @@ -510,10 +510,10 @@ public class SummaryHelper extends HelperBase { */ public String getJobLag() { if (_context == null) - return "0ms"; + return "0 ms"; Rate lagRate = _context.statManager().getRate("jobQueue.jobLag").getRate(60*1000); - return ((int)lagRate.getAverageValue()) + "ms"; + return DataHelper.formatDuration2((long)lagRate.getAverageValue()); } /** @@ -523,9 +523,9 @@ public class SummaryHelper extends HelperBase { */ public String getMessageDelay() { if (_context == null) - return "0ms"; + return "0 ms"; - return _context.throttle().getMessageDelay() + "ms"; + return DataHelper.formatDuration2(_context.throttle().getMessageDelay()); } /** @@ -535,9 +535,9 @@ public class SummaryHelper extends HelperBase { */ public String getTunnelLag() { if (_context == null) - return "0ms"; + return "0 ms"; - return _context.throttle().getTunnelLag() + "ms"; + return DataHelper.formatDuration2(_context.throttle().getTunnelLag()); } public String getTunnelStatus() { diff --git a/apps/routerconsole/java/src/net/i2p/router/web/SummaryRenderer.java b/apps/routerconsole/java/src/net/i2p/router/web/SummaryRenderer.java index f26426edca2435b1f62c94280ea6f7a4da96e33c..5e7545ec2485369b05cf24a44de803d08f744391 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/SummaryRenderer.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/SummaryRenderer.java @@ -78,7 +78,12 @@ class SummaryRenderer { def.setBaseValue(1024); if (!hideTitle) { String title; - String p = DataHelper.formatDuration(_listener.getRate().getPeriod()); + String p; + // we want the formatting and translation of formatDuration2(), except not zh, and not the + if ("zh".equals(Messages.getLanguage(_context))) + p = DataHelper.formatDuration(_listener.getRate().getPeriod()); + else + p = DataHelper.formatDuration2(_listener.getRate().getPeriod()).replace(" ", " "); if (showEvents) // Note to translators: all runtime zh translation disabled in this file, no font available in RRD title = name + ' ' + _("events in {0}", p); diff --git a/apps/routerconsole/java/src/net/i2p/router/web/TunnelRenderer.java b/apps/routerconsole/java/src/net/i2p/router/web/TunnelRenderer.java index e9d7d1da68033f9e3385b93cbd54d78aa2daa60d..3d52c653fa313ce673995bb7d4df86df3bf2fad4 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/TunnelRenderer.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/TunnelRenderer.java @@ -102,7 +102,7 @@ public class TunnelRenderer { out.write("<td class=\"cells\"> </td>"); long timeLeft = cfg.getExpiration()-_context.clock().now(); if (timeLeft > 0) - out.write("<td class=\"cells\" align=\"center\">" + DataHelper.formatDuration(timeLeft) + "</td>"); + out.write("<td class=\"cells\" align=\"center\">" + DataHelper.formatDuration2(timeLeft) + "</td>"); else out.write("<td class=\"cells\" align=\"center\">(" + _("grace period") + ")</td>"); out.write("<td class=\"cells\" align=\"center\">" + cfg.getProcessedMessagesCount() + " KB</td>"); @@ -175,7 +175,7 @@ public class TunnelRenderer { out.write("<tr> <td class=\"cells\" align=\"center\"><img src=\"/themes/console/images/inbound.png\" alt=\"Inbound\" title=\"Inbound\"></td>"); else out.write("<tr> <td class=\"cells\" align=\"center\"><img src=\"/themes/console/images/outbound.png\" alt=\"Outbound\" title=\"Outbound\"></td>"); - out.write(" <td class=\"cells\" align=\"center\">" + DataHelper.formatDuration(timeLeft) + "</td>\n"); + out.write(" <td class=\"cells\" align=\"center\">" + DataHelper.formatDuration2(timeLeft) + "</td>\n"); out.write(" <td class=\"cells\" align=\"center\">" + info.getProcessedMessagesCount() + " KB</td>\n"); for (int j = 0; j < info.getLength(); j++) { Hash peer = info.getPeer(j); diff --git a/core/java/src/net/i2p/data/DataHelper.java b/core/java/src/net/i2p/data/DataHelper.java index 5b0ba4b199dda8ad708ae0488744a7678d599e15..5ab6d32fbfa362c802a9f42d0d980d7c79048feb 100644 --- a/core/java/src/net/i2p/data/DataHelper.java +++ b/core/java/src/net/i2p/data/DataHelper.java @@ -37,11 +37,13 @@ import java.util.Properties; import java.util.TreeMap; import java.util.zip.Deflater; +import net.i2p.I2PAppContext; import net.i2p.util.ByteCache; import net.i2p.util.OrderedProperties; import net.i2p.util.ReusableGZIPInputStream; import net.i2p.util.ReusableGZIPOutputStream; import net.i2p.util.SecureFileOutputStream; +import net.i2p.util.Translate; /** * Defines some simple IO routines for dealing with marshalling data structures @@ -543,9 +545,11 @@ public class DataHelper { else return toLong(DATE_LENGTH, date.getTime()); } + public static void toDate(byte target[], int offset, long when) throws IllegalArgumentException { toLong(target, offset, DATE_LENGTH, when); } + public static Date fromDate(byte src[], int offset) throws DataFormatException { if ( (src == null) || (offset + DATE_LENGTH > src.length) ) throw new DataFormatException("Not enough data to read a date"); @@ -1038,6 +1042,9 @@ public class DataHelper { return rv; } + /** + * NOTE: formatDuration2() recommended in most cases for readability + */ public static String formatDuration(long ms) { if (ms < 5 * 1000) { return ms + "ms"; @@ -1054,8 +1061,68 @@ public class DataHelper { } } + /** + * Like formatDuration but with a non-breaking space after the number, + * 0 is unitless, and the unit is translated. + * This seems consistent with most style guides out there. + * Use only in HTML. + * Thresholds are a little lower than in formatDuration() also, + * as precision is less important in the GUI than in logging. + * @since 0.8.2 + */ + public static String formatDuration2(long ms) { + String t; + if (ms == 0) { + return "0"; + } else if (ms < 3 * 1000) { + // NOTE TO TRANSLATORS: Feel free to translate all these as you see fit, there are several options... + // spaces or not, '.' or not, plural or not. Try not to make it too long, it is used in + // a lot of tables. + // milliseconds + // Note to translators, may be negative or zero, 2999 maximum. + // {0,number,####} prevents 1234 from being output as 1,234 in the English locale. + // If you want the digit separator in your locale, translate as {0}. + // alternates: msec, msecs + t = ngettext("1 ms", "{0,number,####} ms", (int) ms); + } else if (ms < 2 * 60 * 1000) { + // seconds + // Note to translators: quantity will always be greater than one. + // alternates: secs, sec. 'seconds' is probably too long. + t = ngettext("1 sec", "{0} sec", (int) (ms / 1000)); + } else if (ms < 120 * 60 * 1000) { + // minutes + // Note to translators: quantity will always be greater than one. + // alternates: mins, min. 'minutes' is probably too long. + t = ngettext("1 min", "{0} min", (int) (ms / (60 * 1000))); + } else if (ms < 2 * 24 * 60 * 60 * 1000) { + // hours + // Note to translators: quantity will always be greater than one. + // alternates: hrs, hr., hrs. + t = ngettext("1 hour", "{0} hours", (int) (ms / (60 * 60 * 1000))); + } else if (ms > 1000l * 24l * 60l * 60l * 1000l) { + return _("n/a"); + } else { + // days + // Note to translators: quantity will always be greater than one. + t = ngettext("1 day", "{0} days", (int) (ms / (24 * 60 * 60 * 1000))); + } + // do it here to keep out of the tags for translator sanity + return t.replace(" ", " "); + } + + private static final String BUNDLE_NAME = "net.i2p.router.web.messages"; + + private static String _(String key) { + return Translate.getString(key, I2PAppContext.getGlobalContext(), BUNDLE_NAME); + } + + private static String ngettext(String s, String p, int n) { + return Translate.getString(n, s, p, I2PAppContext.getGlobalContext(), BUNDLE_NAME); + } + /** * Caller should append 'B' or 'b' as appropriate + * NOTE: formatDuration2() recommended in most cases for readability */ public static String formatSize(long bytes) { double val = bytes; @@ -1079,6 +1146,7 @@ public class DataHelper { /** * Like formatSize but with a non-breaking space after the number + * This seems consistent with most style guides out there. * Use only in HTML * @since 0.7.14 */ diff --git a/router/java/src/net/i2p/router/transport/ntcp/NTCPTransport.java b/router/java/src/net/i2p/router/transport/ntcp/NTCPTransport.java index 0d6f4561d383e5bd14578772564875e007846fbd..3d6d91f5167f1bb3e2509418b44ecf4494289f7e 100644 --- a/router/java/src/net/i2p/router/transport/ntcp/NTCPTransport.java +++ b/router/java/src/net/i2p/router/transport/ntcp/NTCPTransport.java @@ -709,7 +709,7 @@ public class NTCPTransport extends TransportImpl { StringBuilder buf = new StringBuilder(512); buf.append("<h3 id=\"ntcpcon\">").append(_("NTCP connections")).append(": ").append(peers.size()); buf.append(". ").append(_("Limit")).append(": ").append(getMaxConnections()); - buf.append(". ").append(_("Timeout")).append(": ").append(DataHelper.formatDuration(_pumper.getIdleTimeout())); + buf.append(". ").append(_("Timeout")).append(": ").append(DataHelper.formatDuration2(_pumper.getIdleTimeout())); buf.append(".</h3>\n" + "<table>\n" + "<tr><th><a href=\"#def.peer\">").append(_("Peer")).append("</a></th>" + @@ -739,16 +739,16 @@ public class NTCPTransport extends TransportImpl { else buf.append("<img src=\"/themes/console/images/outbound.png\" alt=\"Outbound\" title=\"").append(_("Outbound")).append("\"/>"); buf.append("</td><td class=\"cells\" align=\"right\">"); - buf.append(con.getTimeSinceReceive()/1000); - buf.append("s / ").append(con.getTimeSinceSend()/1000); - buf.append("s</td><td class=\"cells\" align=\"right\">"); + buf.append(DataHelper.formatDuration2(con.getTimeSinceReceive())); + buf.append(" / ").append(DataHelper.formatDuration2(con.getTimeSinceSend())); + buf.append("</td><td class=\"cells\" align=\"right\">"); if (con.getTimeSinceReceive() < 10*1000) { buf.append(formatRate(con.getRecvRate()/1024)); bpsRecv += con.getRecvRate(); } else { buf.append(formatRate(0)); } - buf.append(" / "); + buf.append(" / "); if (con.getTimeSinceSend() < 10*1000) { buf.append(formatRate(con.getSendRate()/1024)); bpsSend += con.getSendRate(); @@ -756,11 +756,11 @@ public class NTCPTransport extends TransportImpl { buf.append(formatRate(0)); } //buf.append(" K/s"); - buf.append("</td><td class=\"cells\" align=\"right\">").append(DataHelper.formatDuration(con.getUptime())); + buf.append("</td><td class=\"cells\" align=\"right\">").append(DataHelper.formatDuration2(con.getUptime())); totalUptime += con.getUptime(); offsetTotal = offsetTotal + con.getClockSkew(); - buf.append("</td><td class=\"cells\" align=\"right\">").append(con.getClockSkew()); - buf.append("s</td><td class=\"cells\" align=\"right\">").append(con.getMessagesSent()); + buf.append("</td><td class=\"cells\" align=\"right\">").append(DataHelper.formatDuration2(1000 * con.getClockSkew())); + buf.append("</td><td class=\"cells\" align=\"right\">").append(con.getMessagesSent()); totalSend += con.getMessagesSent(); buf.append("</td><td class=\"cells\" align=\"right\">").append(con.getMessagesReceived()); totalRecv += con.getMessagesReceived(); @@ -785,9 +785,9 @@ public class NTCPTransport extends TransportImpl { if (!peers.isEmpty()) { // buf.append("<tr> <td colspan=\"11\"><hr></td></tr>\n"); buf.append("<tr class=\"tablefooter\"><td align=\"center\"><b>").append(peers.size()).append(' ').append(_("peers")).append("</b></td><td> </td><td> "); - buf.append("</td><td align=\"center\"><b>").append(formatRate(bpsRecv/1024)).append("/").append(formatRate(bpsSend/1024)).append("</b>"); - buf.append("</td><td align=\"center\"><b>").append(DataHelper.formatDuration(totalUptime/peers.size())); - buf.append("</b></td><td align=\"center\"><b>").append((!peers.isEmpty()) ? DataHelper.formatDuration(offsetTotal*1000/peers.size()) : "0ms"); + buf.append("</td><td align=\"center\"><b>").append(formatRate(bpsRecv/1024)).append(" / ").append(formatRate(bpsSend/1024)).append("</b>"); + buf.append("</td><td align=\"center\"><b>").append(DataHelper.formatDuration2(totalUptime/peers.size())); + buf.append("</b></td><td align=\"center\"><b>").append(DataHelper.formatDuration2(offsetTotal*1000/peers.size())); buf.append("</b></td><td align=\"center\"><b>").append(totalSend).append("</b></td><td align=\"center\"><b>").append(totalRecv); buf.append("</b></td><td> </td><td> </td></tr>\n"); } diff --git a/router/java/src/net/i2p/router/transport/udp/UDPTransport.java b/router/java/src/net/i2p/router/transport/udp/UDPTransport.java index 70aaa1ecc9f10d6d2042b9523cbe02d7509c9c5e..f0e9c9e2e921c3c6a0393397ca0b26dee62a3fbc 100644 --- a/router/java/src/net/i2p/router/transport/udp/UDPTransport.java +++ b/router/java/src/net/i2p/router/transport/udp/UDPTransport.java @@ -1882,7 +1882,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority StringBuilder buf = new StringBuilder(512); buf.append("<h3 id=\"udpcon\">").append(_("UDP connections")).append(": ").append(peers.size()); buf.append(". ").append(_("Limit")).append(": ").append(getMaxConnections()); - buf.append(". ").append(_("Timeout")).append(": ").append(DataHelper.formatDuration(_expireTimeout)); + buf.append(". ").append(_("Timeout")).append(": ").append(DataHelper.formatDuration2(_expireTimeout)); buf.append(".</h3>\n"); buf.append("<table>\n"); buf.append("<tr><th class=\"smallhead\" nowrap><a href=\"#def.peer\">").append(_("Peer")).append("</a><br>"); @@ -1984,17 +1984,17 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority if (idleOut < 0) idleOut = 0; buf.append("<td class=\"cells\" align=\"right\">"); - buf.append(idleIn); - buf.append("s / "); - buf.append(idleOut); - buf.append("s</td>"); + buf.append(DataHelper.formatDuration2(1000 * idleIn)); + buf.append("&thinsp/ "); + buf.append(DataHelper.formatDuration2(1000 * idleOut)); + buf.append("</td>"); int recvBps = (idleIn > 2 ? 0 : peer.getReceiveBps()); int sendBps = (idleOut > 2 ? 0 : peer.getSendBps()); buf.append("<td class=\"cells\" align=\"right\" nowrap>"); buf.append(formatKBps(recvBps)); - buf.append(" / "); + buf.append(" / "); buf.append(formatKBps(sendBps)); //buf.append(" K/s"); //buf.append(formatKBps(peer.getReceiveACKBps())); @@ -2006,12 +2006,12 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority long uptime = now - peer.getKeyEstablishedTime(); buf.append("<td class=\"cells\" align=\"right\">"); - buf.append(DataHelper.formatDuration(uptime)); + buf.append(DataHelper.formatDuration2(uptime)); buf.append("</td>"); buf.append("<td class=\"cells\" align=\"right\">"); - buf.append(peer.getClockSkew() / 1000); - buf.append("s</td>"); + buf.append(DataHelper.formatDuration2(peer.getClockSkew())); + buf.append("</td>"); offsetTotal = offsetTotal + peer.getClockSkew(); long sendWindow = peer.getSendWindowBytes(); @@ -2019,9 +2019,9 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority buf.append("<td class=\"cells\" align=\"right\">"); buf.append(sendWindow/1024); buf.append("K"); - buf.append(" / ").append(peer.getConcurrentSends()); - buf.append(" / ").append(peer.getConcurrentSendWindow()); - buf.append(" / ").append(peer.getConsecutiveSendRejections()); + buf.append(" / ").append(peer.getConcurrentSends()); + buf.append(" / ").append(peer.getConcurrentSendWindow()); + buf.append(" / ").append(peer.getConsecutiveSendRejections()); buf.append("</td>"); buf.append("<td class=\"cells\" align=\"right\">"); @@ -2044,7 +2044,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority buf.append("</td>"); buf.append("<td class=\"cells\" align=\"right\">"); - buf.append(peer.getMTU()).append(" / ").append(peer.getReceiveMTU()); + buf.append(peer.getMTU()).append(" / ").append(peer.getReceiveMTU()); //.append('/'); //buf.append(peer.getMTUIncreases()).append('/'); @@ -2104,10 +2104,12 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority // buf.append("<tr><td colspan=\"16\"><hr></td></tr>\n"); buf.append("<tr class=\"tablefooter\"> <td colspan=\"3\" align=\"left\"><b>").append(_("SUMMARY")).append("</b></td>" + "<td align=\"center\" nowrap><b>"); - buf.append(formatKBps(bpsIn)).append(" / ").append(formatKBps(bpsOut)); + buf.append(formatKBps(bpsIn)).append("thinsp;/ ").append(formatKBps(bpsOut)); + long x = numPeers > 0 ? uptimeMsTotal/numPeers : 0; buf.append("</b></td>" + - "<td align=\"center\"><b>").append(numPeers > 0 ? DataHelper.formatDuration(uptimeMsTotal/numPeers) : "0s"); - buf.append("</b></td><td align=\"center\"><b>").append(numPeers > 0 ? DataHelper.formatDuration(offsetTotal/numPeers) : "0ms").append("</b></td>\n" + + "<td align=\"center\"><b>").append(DataHelper.formatDuration2(x)); + x = numPeers > 0 ? offsetTotal/numPeers : 0; + buf.append("</b></td><td align=\"center\"><b>").append(DataHelper.formatDuration2(x)).append("</b></td>\n" + "<td align=\"center\"><b>"); buf.append(numPeers > 0 ? cwinTotal/(numPeers*1024) + "K" : "0K"); buf.append("</b></td><td> </td>\n" +