diff --git a/htroot/Bookmarks.java b/htroot/Bookmarks.java index e97cc9ce2..c2460ede2 100644 --- a/htroot/Bookmarks.java +++ b/htroot/Bookmarks.java @@ -276,7 +276,7 @@ public class Bookmarks { prop.put("bookmarks_"+count+"_link",bookmark.getUrl()); prop.putHTML("bookmarks_"+count+"_title", bookmark.getTitle()); prop.putHTML("bookmarks_"+count+"_description", bookmark.getDescription()); - prop.put("bookmarks_"+count+"_date", serverDate.dateToiso8601(new Date(bookmark.getTimeStamp()))); + prop.put("bookmarks_"+count+"_date", serverDate.formatISO8601(new Date(bookmark.getTimeStamp()))); prop.put("bookmarks_"+count+"_rfc822date", httpc.dateString(new Date(bookmark.getTimeStamp()))); prop.put("bookmarks_"+count+"_public", (bookmark.getPublic() ? "1" : "0")); diff --git a/htroot/Supporter.java b/htroot/Supporter.java index 1750659d5..82bc19de1 100644 --- a/htroot/Supporter.java +++ b/htroot/Supporter.java @@ -104,7 +104,7 @@ public class Supporter { //accumulateVotes(negativeHashes, positiveHashes, yacyNewsPool.OUTGOING_DB); //accumulateVotes(negativeHashes, positiveHashes, yacyNewsPool.PUBLISHED_DB); kelondroMScoreCluster ranking = new kelondroMScoreCluster(); // score cluster for url hashes - kelondroRow rowdef = new kelondroRow("String url-255, String title-120, String description-120, String refid-" + (serverDate.shortSecondFormatterPattern.length() + 12), kelondroNaturalOrder.naturalOrder, 0); + kelondroRow rowdef = new kelondroRow("String url-255, String title-120, String description-120, String refid-" + (serverDate.PATTERN_SHORT_SECOND.length() + 12), kelondroNaturalOrder.naturalOrder, 0); HashMap Supporter = new HashMap(); // a mapping from an url hash to a kelondroRow.Entry with display properties accumulateSupporter(Supporter, ranking, rowdef, negativeHashes, positiveHashes, yacyNewsPool.INCOMING_DB); //accumulateSupporter(Supporter, ranking, rowdef, negativeHashes, positiveHashes, yacyNewsPool.OUTGOING_DB); diff --git a/htroot/Surftips.java b/htroot/Surftips.java index 6a1b12509..70878984a 100644 --- a/htroot/Surftips.java +++ b/htroot/Surftips.java @@ -112,7 +112,7 @@ public class Surftips { //accumulateVotes(negativeHashes, positiveHashes, yacyNewsPool.OUTGOING_DB); //accumulateVotes(negativeHashes, positiveHashes, yacyNewsPool.PUBLISHED_DB); kelondroMScoreCluster ranking = new kelondroMScoreCluster(); // score cluster for url hashes - kelondroRow rowdef = new kelondroRow("String url-255, String title-120, String description-120, String refid-" + (serverDate.shortSecondFormatterPattern.length() + 12), kelondroNaturalOrder.naturalOrder, 0); + kelondroRow rowdef = new kelondroRow("String url-255, String title-120, String description-120, String refid-" + (serverDate.PATTERN_SHORT_SECOND.length() + 12), kelondroNaturalOrder.naturalOrder, 0); HashMap surftips = new HashMap(); // a mapping from an url hash to a kelondroRow.Entry with display properties accumulateSurftips(surftips, ranking, rowdef, negativeHashes, positiveHashes, yacyNewsPool.INCOMING_DB); //accumulateSurftips(surftips, ranking, rowdef, negativeHashes, positiveHashes, yacyNewsPool.OUTGOING_DB); diff --git a/htroot/xml/bookmarks/posts/all.java b/htroot/xml/bookmarks/posts/all.java index 68e32ecc3..f44b79c3e 100644 --- a/htroot/xml/bookmarks/posts/all.java +++ b/htroot/xml/bookmarks/posts/all.java @@ -83,7 +83,7 @@ public class all { prop.putHTML("posts_"+count+"_description", bookmark.getDescription()); prop.put("posts_"+count+"_md5", serverCodings.encodeMD5Hex(bookmark.getUrl())); date=new Date(bookmark.getTimeStamp()); - prop.put("posts_"+count+"_time", serverDate.dateToiso8601(date)); + prop.put("posts_"+count+"_time", serverDate.formatISO8601(date)); prop.putHTML("posts_"+count+"_tags", bookmark.getTagsString().replaceAll(","," ")); // additional XML tags diff --git a/htroot/xml/bookmarks/posts/get.java b/htroot/xml/bookmarks/posts/get.java index 2ed0adf75..628ecd2bf 100644 --- a/htroot/xml/bookmarks/posts/get.java +++ b/htroot/xml/bookmarks/posts/get.java @@ -48,7 +48,7 @@ public class get { if(post != null && post.containsKey("date")){ date=(String)post.get("date"); }else{ - date=serverDate.dateToiso8601(new Date(System.currentTimeMillis())); + date=serverDate.formatISO8601(new Date(System.currentTimeMillis())); } // if an extended xml should be used @@ -68,7 +68,7 @@ public class get { bookmarksDB.Bookmark bookmark=null; while(it.hasNext()){ bookmark=switchboard.bookmarksDB.getBookmark((String) it.next()); - if(serverDate.dateToiso8601(new Date(bookmark.getTimeStamp())) == date && + if(serverDate.formatISO8601(new Date(bookmark.getTimeStamp())) == date && tag==null || bookmark.getTags().contains(tag) && isAdmin || bookmark.getPublic()){ prop.put("posts_"+count+"_url", bookmark.getUrl()); diff --git a/source/de/anomic/server/serverDate.java b/source/de/anomic/server/serverDate.java index 1966d1274..8dd07fdcc 100644 --- a/source/de/anomic/server/serverDate.java +++ b/source/de/anomic/server/serverDate.java @@ -56,50 +56,59 @@ import de.anomic.server.logging.serverLog; public final class serverDate { - // standard date formatters - public static final String shortDayFormatterPattern = "yyyyMMdd"; - public static final String shortSecondFormatterPattern = "yyyyMMddHHmmss"; - public static final String PAT_DATE_ANSI = "EEE MMM d HH:mm:ss yyyy"; - public static final String PAT_DATE_RFC1036 = "EEEE, dd-MMM-yy HH:mm:ss zzz"; - public static final String PAT_DATE_RFC1123 = "EEE, dd MMM yyyy HH:mm:ss zzz"; + /** minimal date format without time information */ + public static final String PATTERN_SHORT_DAY = "yyyyMMdd"; + /** minimal date format */ + public static final String PATTERN_SHORT_SECOND = "yyyyMMddHHmmss"; + + /** default HTTP 1.1 header date format pattern */ + public static final String PATTERN_RFC1123 = "EEE, dd MMM yyyy HH:mm:ss zzz"; + /** date pattern used in older HTTP implementations */ + public static final String PATTERN_ANSIC = "EEE MMM d HH:mm:ss yyyy"; + /** date pattern used in older HTTP implementations */ + public static final String PATTERN_RFC1036 = "EEEE, dd-MMM-yy HH:mm:ss zzz"; + + /** 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(shortDayFormatterPattern); - public static final SimpleDateFormat shortSecondFormatter = new SimpleDateFormat(shortSecondFormatterPattern); + 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); - private static TimeZone TZ_GMT = TimeZone.getTimeZone("GMT"); + /** 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); /** * 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[] DATE_PARSERS = new SimpleDateFormat[] { + public static SimpleDateFormat[] FORMATS_HTTP = new SimpleDateFormat[] { // RFC 1123/822 (Standard) "Mon, 12 Nov 2007 10:11:12 GMT" - new SimpleDateFormat(PAT_DATE_RFC1123, Locale.US), + new SimpleDateFormat(PATTERN_RFC1123, Locale.US), // RFC 1036/850 (old) "Monday, 12-Nov-07 10:11:12 GMT" - new SimpleDateFormat(PAT_DATE_RFC1036, Locale.US), + new SimpleDateFormat(PATTERN_RFC1036, Locale.US), // ANSI C asctime() "Mon Nov 12 10:11:12 2007" - new SimpleDateFormat(PAT_DATE_ANSI, Locale.US), + new SimpleDateFormat(PATTERN_ANSIC, Locale.US), }; static { // 2-digit dates are automatically parsed by SimpleDateFormat, // we need to detect the real year by adding 1900 or 2000 to // the year value starting with 1970 - Calendar c = Calendar.getInstance(TZ_GMT, Locale.US); - // 01 Jan 1970 00:00:00 - c.set(1970, 1, 1, 0, 0, 0); + CAL_GMT.setTimeInMillis(0); - for (int i = 0; i < serverDate.DATE_PARSERS.length; i++) { - SimpleDateFormat f = serverDate.DATE_PARSERS[i]; + for (int i = 0; i < serverDate.FORMATS_HTTP.length; i++) { + SimpleDateFormat f = serverDate.FORMATS_HTTP[i]; f.setTimeZone(TZ_GMT); - f.set2DigitYearStart(c.getTime()); + f.set2DigitYearStart(CAL_GMT.getTime()); } } - public static long nowTime() { - return nowDate().getTime(); - } +// public static long nowTime() { +// return nowDate().getTime(); +// } public static Date nowDate() { return new GregorianCalendar(TZ_GMT).getTime(); @@ -114,10 +123,10 @@ public final class serverDate { s = s.trim(); if ((s == null) || (s.length() < 9)) return null; - for(int i = 0; i < DATE_PARSERS.length; i++) { + for(int i = 0; i < FORMATS_HTTP.length; i++) { try { - synchronized (DATE_PARSERS[i]) { - return DATE_PARSERS[i].parse(s); + synchronized (FORMATS_HTTP[i]) { + return FORMATS_HTTP[i].parse(s); } } catch (ParseException e) { // on ParseException try again with next parser @@ -200,9 +209,6 @@ public final class serverDate { // find out time zone and DST offset private static Calendar thisCalendar = Calendar.getInstance(); - //private static long zoneOffsetHours = thisCalendar.get(Calendar.ZONE_OFFSET); - //private static long DSTOffsetHours = thisCalendar.get(Calendar.DST_OFFSET); - //private static long offsetHours = zoneOffsetHours + DSTOffsetHours; // this must be subtracted from current Date().getTime() to produce a GMT Time // pre-calculation of time tables private final static long[] dimnormalacc, dimleapacc; @@ -276,11 +282,6 @@ public final class serverDate { return ((ahead) ? (long) 1 : (long) -1) * (oh * hourMillis + om * minuteMillis); } - /* - public static Date UTC0Date() { - return new Date(UTC0Time()); - } - */ public static long correctedUTCTime() { return System.currentTimeMillis() - UTCDiff(); @@ -423,9 +424,18 @@ public final class serverDate { return date.getTime(); } - public static String dateToiso8601(Date date){ - return new SimpleDateFormat("yyyy-MM-dd").format(date)+"T"+(new SimpleDateFormat("HH:mm:ss")).format(date)+"Z"; - } + /** + * Creates a String representation of a Date using the format defined + * in ISO8601. + * The result will be in UTC/GMT, e.g. "2007-12-19T10:20:30Z" + * @param date The Date instance to transform. + * @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); + } public static String intervalToString(long millis) { try { diff --git a/source/de/anomic/yacy/yacyNewsQueue.java b/source/de/anomic/yacy/yacyNewsQueue.java index bd5662b7d..e878869b1 100644 --- a/source/de/anomic/yacy/yacyNewsQueue.java +++ b/source/de/anomic/yacy/yacyNewsQueue.java @@ -63,7 +63,7 @@ public class yacyNewsQueue { public static final kelondroRow rowdef = new kelondroRow(new kelondroColumn[]{ new kelondroColumn("newsid", kelondroColumn.celltype_string, kelondroColumn.encoder_bytes, yacyNewsRecord.idLength, "id = created + originator"), - new kelondroColumn("last touched", kelondroColumn.celltype_string, kelondroColumn.encoder_bytes, serverDate.shortSecondFormatterPattern.length(), "") + new kelondroColumn("last touched", kelondroColumn.celltype_string, kelondroColumn.encoder_bytes, serverDate.PATTERN_SHORT_SECOND.length(), "") }, kelondroNaturalOrder.naturalOrder, 0 ); diff --git a/source/de/anomic/yacy/yacyNewsRecord.java b/source/de/anomic/yacy/yacyNewsRecord.java index 50be79c81..23c572ccb 100644 --- a/source/de/anomic/yacy/yacyNewsRecord.java +++ b/source/de/anomic/yacy/yacyNewsRecord.java @@ -56,7 +56,7 @@ public class yacyNewsRecord { public static final int maxNewsRecordLength = 512; public static final int categoryStringLength = 8; - public static final int idLength = serverDate.shortSecondFormatterPattern.length() + yacySeedDB.commonHashLength; + public static final int idLength = serverDate.PATTERN_SHORT_SECOND.length() + yacySeedDB.commonHashLength; private String originator; // hash of originating peer private Date created; // Date when news was created by originator @@ -68,13 +68,13 @@ public class yacyNewsRecord { public static final int attributesMaxLength = maxNewsRecordLength - idLength - categoryStringLength - - serverDate.shortSecondFormatterPattern.length() + - serverDate.PATTERN_SHORT_SECOND.length() - 2; public static final kelondroRow rowdef = new kelondroRow( "String idx-" + idLength + " \"id = created + originator\"," + "String cat-" + categoryStringLength + "," + - "String rec-" + serverDate.shortSecondFormatterPattern.length() + "," + + "String rec-" + serverDate.PATTERN_SHORT_SECOND.length() + "," + "short dis-2 {b64e}," + "String att-" + attributesMaxLength, kelondroNaturalOrder.naturalOrder, 0 @@ -136,10 +136,10 @@ public class yacyNewsRecord { if (attributes.toString().length() > attributesMaxLength) throw new IllegalArgumentException("attributes length (" + attributes.toString().length() + ") exceeds maximum (" + attributesMaxLength + ")"); this.attributes = attributes; this.received = received; - this.created = serverDate.parseShortSecondTime(id.substring(0, serverDate.shortSecondFormatterPattern.length()), serverDate.UTCDiffString()); + this.created = serverDate.parseShortSecondTime(id.substring(0, serverDate.PATTERN_SHORT_SECOND.length()), serverDate.UTCDiffString()); this.category = category; this.distributed = distributed; - this.originator = id.substring(serverDate.shortSecondFormatterPattern.length()); + this.originator = id.substring(serverDate.PATTERN_SHORT_SECOND.length()); removeStandards(); }