From 33ee6745f6a8d2ed003ca9eefbfd4b32f41d3192 Mon Sep 17 00:00:00 2001 From: fuchsi Date: Wed, 19 Dec 2007 19:39:19 +0000 Subject: [PATCH] more cleanup in serverDate - remove direct accesses to SimpleDateFormat fields in serverDate and use the static parse... methods instead - remove nowDate() as a Date doesn't store timezone information and a new Date() is always faster - default formatter methods use a GMT timezone by default now, this is important for interchangability as some date formats we use don't include a timezone offset. - continued renaming and rearanging (formatter) methods. all should follow the general naming scheme formatWHAT(...) git-svn-id: https://svn.berlios.de/svnroot/repos/yacy/trunk@4285 6c8d7289-2bf4-0310-a012-ef5d649a1542 --- htroot/IndexControlRWIs_p.java | 2 +- htroot/yacy/transferURL.java | 2 +- source/de/anomic/data/blogBoard.java | 8 +- source/de/anomic/index/indexURLEntry.java | 12 +- .../de/anomic/plasma/plasmaWebStructure.java | 2 +- source/de/anomic/server/serverDate.java | 157 ++++++++++++------ source/yacy.java | 2 +- 7 files changed, 124 insertions(+), 61 deletions(-) diff --git a/htroot/IndexControlRWIs_p.java b/htroot/IndexControlRWIs_p.java index 57a259eeb..e526c2dc8 100644 --- a/htroot/IndexControlRWIs_p.java +++ b/htroot/IndexControlRWIs_p.java @@ -420,7 +420,7 @@ public class IndexControlRWIs_p { prop.putNum("genUrlList_urlList_"+i+"_urlExists_domlength", yacyURL.domLengthEstimation(entry.hash())); prop.putNum("genUrlList_urlList_"+i+"_urlExists_ybr", plasmaSearchRankingProcess.ybr(entry.hash())); prop.putNum("genUrlList_urlList_"+i+"_urlExists_authority", ranked.getOrder().authority(entry.hash())); - prop.put("genUrlList_urlList_"+i+"_urlExists_date", serverDate.shortDayTime(new Date(entry.word().lastModified()))); + prop.put("genUrlList_urlList_"+i+"_urlExists_date", serverDate.formatShortDay(new Date(entry.word().lastModified()))); prop.putNum("genUrlList_urlList_"+i+"_urlExists_wordsintitle", entry.word().wordsintitle()); prop.putNum("genUrlList_urlList_"+i+"_urlExists_wordsintext", entry.word().wordsintext()); prop.putNum("genUrlList_urlList_"+i+"_urlExists_phrasesintext", entry.word().phrasesintext()); diff --git a/htroot/yacy/transferURL.java b/htroot/yacy/transferURL.java index e401ae8de..a15df1f0c 100644 --- a/htroot/yacy/transferURL.java +++ b/htroot/yacy/transferURL.java @@ -66,7 +66,7 @@ public final class transferURL { public static serverObjects respond(httpHeader header, serverObjects post, serverSwitch env) throws InterruptedException { long start = System.currentTimeMillis(); long freshdate = 0; - try {freshdate = serverDate.shortDayFormatter.parse("20061101").getTime();} catch (ParseException e1) {} + try {freshdate = serverDate.parseShortDayTime("20061101").getTime();} catch (ParseException e1) {} // return variable that accumulates replacements final plasmaSwitchboard sb = (plasmaSwitchboard) env; diff --git a/source/de/anomic/data/blogBoard.java b/source/de/anomic/data/blogBoard.java index 31fd42f49..08570d363 100644 --- a/source/de/anomic/data/blogBoard.java +++ b/source/de/anomic/data/blogBoard.java @@ -122,7 +122,7 @@ public class blogBoard { record = new HashMap(); key = nkey; if (key.length() > keyLength) key = key.substring(0, keyLength); - if(date == null) date = serverDate.nowDate(); + if(date == null) date = new Date(); record.put("date", serverDate.shortSecondTime(date)); if (subject == null) record.put("subject",""); else record.put("subject", kelondroBase64Order.enhancedCoder.encode(subject)); @@ -167,7 +167,7 @@ public class blogBoard { System.out.println("DEBUG - ERROR: date field missing in blogBoard"); return new Date(); } - return serverDate.shortSecondFormatter.parse(c); + return serverDate.parseShortSecondTime(c); } catch (ParseException e) { return new Date(); } @@ -254,7 +254,7 @@ public class blogBoard { key = normalize(key); if (key.length() > keyLength) key = key.substring(0, keyLength); Map record = base.getMap(key); - if (record == null) return newEntry(key, "".getBytes(), "anonymous".getBytes(), "127.0.0.1", serverDate.nowDate(), "".getBytes(), null, null); + if (record == null) return newEntry(key, "".getBytes(), "anonymous".getBytes(), "127.0.0.1", new Date(), "".getBytes(), null, null); return new entry(key, record); } @@ -305,7 +305,7 @@ public class blogBoard { } try { - date = serverDate.shortSecondFormatter.parse(StrDate); + date = serverDate.parseShortSecondTime(StrDate); } catch (ParseException e1) { date = new Date(); } diff --git a/source/de/anomic/index/indexURLEntry.java b/source/de/anomic/index/indexURLEntry.java index 2d487f392..359e904ef 100644 --- a/source/de/anomic/index/indexURLEntry.java +++ b/source/de/anomic/index/indexURLEntry.java @@ -212,17 +212,17 @@ public class indexURLEntry { this.entry.setCol(col_hash, url.hash(), null); this.entry.setCol(col_comp, encodeComp(url, descr, author, tags, ETag)); try { - encodeDate(col_mod, serverDate.shortDayFormatter.parse(prop.getProperty("mod", "20000101"))); + encodeDate(col_mod, serverDate.parseShortDayTime(prop.getProperty("mod", "20000101"))); } catch (ParseException e) { encodeDate(col_mod, new Date()); } try { - encodeDate(col_load, serverDate.shortDayFormatter.parse(prop.getProperty("load", "20000101"))); + encodeDate(col_load, serverDate.parseShortDayTime(prop.getProperty("load", "20000101"))); } catch (ParseException e) { encodeDate(col_load, new Date()); } try { - encodeDate(col_fresh, serverDate.shortDayFormatter.parse(prop.getProperty("fresh", "20000101"))); + encodeDate(col_fresh, serverDate.parseShortDayTime(prop.getProperty("fresh", "20000101"))); } catch (ParseException e) { encodeDate(col_fresh, new Date()); } @@ -261,9 +261,9 @@ public class indexURLEntry { s.append(",author=").append(crypt.simpleEncode(comp.author())); s.append(",tags=").append(crypt.simpleEncode(comp.tags())); s.append(",ETag=").append(crypt.simpleEncode(comp.ETag())); - s.append(",mod=").append(serverDate.shortDayFormatter.format(moddate())); - s.append(",load=").append(serverDate.shortDayFormatter.format(loaddate())); - s.append(",fresh=").append(serverDate.shortDayFormatter.format(freshdate())); + s.append(",mod=").append(serverDate.formatShortDay(moddate())); + s.append(",load=").append(serverDate.formatShortDay(loaddate())); + s.append(",fresh=").append(serverDate.formatShortDay(freshdate())); s.append(",referrer=").append(referrerHash()); s.append(",md5=").append(md5()); s.append(",size=").append(size()); diff --git a/source/de/anomic/plasma/plasmaWebStructure.java b/source/de/anomic/plasma/plasmaWebStructure.java index 78c640917..febfa4f49 100644 --- a/source/de/anomic/plasma/plasmaWebStructure.java +++ b/source/de/anomic/plasma/plasmaWebStructure.java @@ -198,7 +198,7 @@ public class plasmaWebStructure { private static String map2refstr(Map map) { StringBuffer s = new StringBuffer(map.size() * 10); - s.append(serverDate.shortDayFormatter.format(new Date())); + s.append(serverDate.formatShortDay(new Date())); Iterator i = map.entrySet().iterator(); Map.Entry entry; String h; diff --git a/source/de/anomic/server/serverDate.java b/source/de/anomic/server/serverDate.java index 8dd07fdcc..7d1cdb561 100644 --- a/source/de/anomic/server/serverDate.java +++ b/source/de/anomic/server/serverDate.java @@ -44,11 +44,11 @@ package de.anomic.server; +import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; -import java.util.GregorianCalendar; import java.util.Locale; import java.util.TimeZone; @@ -56,10 +56,12 @@ import de.anomic.server.logging.serverLog; public final class serverDate { - /** minimal date format without time information */ - public static final String PATTERN_SHORT_DAY = "yyyyMMdd"; - /** minimal date format */ + /** minimal date format without time information (fixed width: 8) */ + public static final String PATTERN_SHORT_DAY = "yyyyMMdd"; + /** minimal date format (fixed width: 14) */ public static final String PATTERN_SHORT_SECOND = "yyyyMMddHHmmss"; + /** minimal date format including milliseconds (fixed width: 17) */ + public static final String PATTERN_SHORT_MILSEC = "yyyyMMddHHmmssSSS"; /** default HTTP 1.1 header date format pattern */ public static final String PATTERN_RFC1123 = "EEE, dd MMM yyyy HH:mm:ss zzz"; @@ -71,28 +73,39 @@ public final class serverDate { /** pattern for a W3C datetime variant of a non-localized ISO8601 date */ public static final String PATTERN_ISO8601 = "yyyy-MM-dd'T'HH:mm:ss'Z'"; - public static final SimpleDateFormat shortDayFormatter = new SimpleDateFormat(PATTERN_SHORT_DAY); - public static final SimpleDateFormat shortSecondFormatter = new SimpleDateFormat(PATTERN_SHORT_SECOND); - public static final SimpleDateFormat longFullFormatter = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss 'GMT'", Locale.US); - /** predefined GMT TimeZone object */ private static final TimeZone TZ_GMT = TimeZone.getTimeZone("GMT"); + /** predefined non-localized Calendar object for generic GMT dates */ private static final Calendar CAL_GMT = Calendar.getInstance(TZ_GMT, Locale.US); + /** Date formatter/parser for minimal yyyyMMdd pattern */ + public static final SimpleDateFormat FORMAT_SHORT_DAY = new SimpleDateFormat(PATTERN_SHORT_DAY); + /** Date formatter/parser for minimal yyyyMMddHHmmss pattern */ + public static final SimpleDateFormat FORMAT_SHORT_SECOND = new SimpleDateFormat(PATTERN_SHORT_SECOND); + /** Date formatter/parser for minimal yyyyMMddHHmmssSSS pattern */ + public static final SimpleDateFormat FORMAT_SHORT_MILSEC = new SimpleDateFormat(PATTERN_SHORT_MILSEC); + + /** Date formatter/non-sloppy parser for W3C datetime (ISO8601) in GMT/UTC */ + public static final SimpleDateFormat FORMAT_ISO8601 = new SimpleDateFormat(PATTERN_ISO8601); + + /** Date formatter/parser for standard compliant HTTP header dates (RFC 1123) */ + public static final SimpleDateFormat FORMAT_RFC1123 = new SimpleDateFormat(PATTERN_RFC1123, Locale.US); + /** * RFC 2616 requires that HTTP clients are able to parse all 3 different * formats. All times MUST be in GMT/UTC, but ... */ public static SimpleDateFormat[] FORMATS_HTTP = new SimpleDateFormat[] { // RFC 1123/822 (Standard) "Mon, 12 Nov 2007 10:11:12 GMT" - new SimpleDateFormat(PATTERN_RFC1123, Locale.US), + FORMAT_RFC1123, // RFC 1036/850 (old) "Monday, 12-Nov-07 10:11:12 GMT" new SimpleDateFormat(PATTERN_RFC1036, Locale.US), // ANSI C asctime() "Mon Nov 12 10:11:12 2007" new SimpleDateFormat(PATTERN_ANSIC, Locale.US), }; + /** Initialization of static formats */ static { // 2-digit dates are automatically parsed by SimpleDateFormat, // we need to detect the real year by adding 1900 or 2000 to @@ -104,16 +117,14 @@ public final class serverDate { f.setTimeZone(TZ_GMT); f.set2DigitYearStart(CAL_GMT.getTime()); } + + // we want GMT times on the SHORT formats as well as they don't support any timezone + FORMAT_SHORT_DAY.setTimeZone(TZ_GMT); + FORMAT_SHORT_SECOND.setTimeZone(TZ_GMT); + FORMAT_SHORT_MILSEC.setTimeZone(TZ_GMT); + FORMAT_ISO8601.setTimeZone(TZ_GMT); } -// public static long nowTime() { -// return nowDate().getTime(); -// } - - public static Date nowDate() { - return new GregorianCalendar(TZ_GMT).getTime(); - } - /** * Parse a HTTP string representation of a date into a Date instance. * @param s The date String to parse. @@ -133,46 +144,67 @@ public final class serverDate { } } - // the method didn't return a Date, so we got an illegal + // the method didn't return a Date, so we got an illegal String serverLog.logSevere("HTTPC-header", "DATE ERROR (Parse): " + s); return null; } - - /* - * Synchronization of formatters is needed because SimpleDateFormat is not thread-safe. - * See: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6231579 + /** + * Note: The short day format doesn't include any timezone information. This method + * transforms the date into the GMT/UTC timezone. Example: If the local system time is, + * 2007-12-18 01:15:00 +0200, then the resulting String will be "2007-12-17". + * In case you need a format with a timezon offset, use {@link #formatShortDay(TimeZone)} + * @return a String representation of the current system date in GMT using the + * short day format, e.g. "20071218". */ - - public static String shortDayTime() { - return shortDayTime(nowDate()); + public static String formatShortDay() { + return format(FORMAT_SHORT_DAY, new Date()); } - public static String shortDayTime(Date date) { - synchronized (serverDate.shortDayFormatter) { - return shortDayFormatter.format(date); - } + /** + * @see #formatShortDay() + * @param tz a TimeZone the resulting date is aligned to. + */ + public static String formatShortDay(TimeZone tz) { + return format(FORMAT_SHORT_DAY, new Date(), tz); } - + + /** + * @see #formatShortDay() + * @param date the Date to transform + */ + public static String formatShortDay(Date date) { + return format(FORMAT_SHORT_DAY, date); + } + + /** + * @see #formatShortDay() + * @param date the Date to transform + * @param tz a TimeZone the resulting date String should be aligned to. + */ + public static String formatShortDay(Date date, TimeZone tz) { + return format(FORMAT_SHORT_DAY, date); + } + public static Date parseShortDayTime(String timeString) throws ParseException { - synchronized (serverDate.shortDayFormatter) { - return serverDate.shortDayFormatter.parse(timeString); + synchronized (serverDate.FORMAT_SHORT_DAY) { + return serverDate.FORMAT_SHORT_DAY.parse(timeString); } } public static String shortSecondTime() { - return shortSecondTime(nowDate()); + return shortSecondTime(new Date()); } public static String shortSecondTime(Date date) { - synchronized (serverDate.shortSecondFormatter) { - return serverDate.shortSecondFormatter.format(date); + synchronized (serverDate.FORMAT_SHORT_SECOND) { + return serverDate.FORMAT_SHORT_SECOND.format(date); } } public static Date parseShortSecondTime(String timeString) throws ParseException { - synchronized (serverDate.shortSecondFormatter) { - return serverDate.shortSecondFormatter.parse(timeString); + synchronized (serverDate.FORMAT_SHORT_SECOND) { + return serverDate.FORMAT_SHORT_SECOND.parse(timeString); } } @@ -180,8 +212,8 @@ public final class serverDate { if (remoteTimeString == null || remoteTimeString.length() == 0) { return new Date(); } if (remoteUTCOffset == null || remoteUTCOffset.length() == 0) { return new Date(); } try { - synchronized(serverDate.shortSecondFormatter) { - return new Date(serverDate.shortSecondFormatter.parse(remoteTimeString).getTime() - serverDate.UTCDiff() + serverDate.UTCDiff(remoteUTCOffset)); + synchronized(serverDate.FORMAT_SHORT_SECOND) { + return new Date(serverDate.FORMAT_SHORT_SECOND.parse(remoteTimeString).getTime() - serverDate.UTCDiff() + serverDate.UTCDiff(remoteUTCOffset)); } } catch (java.text.ParseException e) { serverLog.logFinest("parseUniversalDate", e.getMessage() + ", remoteTimeString=[" + remoteTimeString + "]"); @@ -192,6 +224,36 @@ public final class serverDate { } } + /** + * called by all public format...(..., TimeZone) methods + */ + private static String format(SimpleDateFormat format, Date date, TimeZone tz) { + TimeZone bakTZ = format.getTimeZone(); + String result; + + synchronized (format) { + format.setTimeZone(tz == null ? TZ_GMT : tz); + result = format.format(date); + format.setTimeZone(bakTZ); + } + + return result; + } + + /** + * called by all public format...(...) methods + */ + private static String format(SimpleDateFormat format, Date date) { + String result; + + synchronized (format) { + result = format.format(date); + } + + return result; + } + + // statics public final static long secondMillis = 1000; public final static long minuteMillis = 60 * secondMillis; @@ -432,9 +494,9 @@ public final class serverDate { * @return A fixed width (20 chars) ISO8601 date String. */ public static String formatISO8601(Date date){ - SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); - df.setTimeZone(TZ_GMT); - return df.format(date); + synchronized (FORMAT_ISO8601) { + return FORMAT_ISO8601.format(date); + } } public static String intervalToString(long millis) { @@ -473,11 +535,11 @@ public final class serverDate { System.out.println("serverDate : " + new serverDate().toShortString(false)); System.out.println(" javaDate : " + shortSecondTime()); System.out.println("serverDate : " + new serverDate().toString()); - System.out.println(" JavaDate : " + longFullFormatter.format(new Date())); + System.out.println(" JavaDate : " + DateFormat.getDateInstance().format(new Date())); System.out.println("serverDate0: " + new serverDate(0).toShortString(false)); - System.out.println(" JavaDate0: " + shortSecondFormatter.format(new Date(0))); + System.out.println(" JavaDate0: " + FORMAT_SHORT_SECOND.format(new Date(0))); System.out.println("serverDate0: " + new serverDate(0).toString()); - System.out.println(" JavaDate0: " + longFullFormatter.format(new Date(0))); + System.out.println(" JavaDate0: " + DateFormat.getDateInstance().format(new Date(0))); // parse test try { System.out.println("serverDate re-parse short: " + new serverDate(new serverDate().toShortString(false)).toShortString(true)); @@ -489,12 +551,13 @@ public final class serverDate { int cycles = 10000; long start; + String[] testresult = new String[10000]; start = System.currentTimeMillis(); - for (int i = 0; i < cycles; i++) /*testresult =*/ new serverDate().toShortString(false); + for (int i = 0; i < cycles; i++) testresult[i] = new serverDate().toShortString(false); System.out.println("time for " + cycles + " calls to serverDate:" + (System.currentTimeMillis() - start) + " milliseconds"); start = System.currentTimeMillis(); - for (int i = 0; i < cycles; i++) /*testresult =*/ shortSecondTime(); + for (int i = 0; i < cycles; i++) testresult[i] = FORMAT_SHORT_SECOND.format(new Date()); System.out.println("time for " + cycles + " calls to javaDate:" + (System.currentTimeMillis() - start) + " milliseconds"); } } diff --git a/source/yacy.java b/source/yacy.java index 6e673e53a..9bff2ed04 100644 --- a/source/yacy.java +++ b/source/yacy.java @@ -262,7 +262,7 @@ public final class yacy { sb.setConfig("version", Double.toString(version)); sb.setConfig("vString", yacyVersion.combined2prettyVersion(Double.toString(version))); - sb.setConfig("vdate", (vDATE.startsWith("@")) ? serverDate.shortDayTime() : vDATE); + sb.setConfig("vdate", (vDATE.startsWith("@")) ? serverDate.formatShortDay() : vDATE); sb.setConfig("applicationRoot", homePath); serverLog.logConfig("STARTUP", "YACY Version: " + version + ", Built " + sb.getConfig("vdate", "00000000")); yacyVersion.latestRelease = version;