1:
44:
45: package ;
46:
47: import ;
48: import ;
49: import ;
50: import ;
51: import ;
52: import ;
53: import ;
54: import ;
55:
56:
62: public class RelativeDateFormat extends DateFormat {
63:
64:
65: private long baseMillis;
66:
67:
70: private boolean showZeroDays;
71:
72:
77: private boolean showZeroHours;
78:
79:
83: private NumberFormat dayFormatter;
84:
85:
91: private String positivePrefix;
92:
93:
96: private String daySuffix;
97:
98:
101: private String hourSuffix;
102:
103:
106: private String minuteSuffix;
107:
108:
111: private NumberFormat secondFormatter;
112:
113:
116: private String secondSuffix;
117:
118:
121: private static long MILLISECONDS_IN_ONE_HOUR = 60 * 60 * 1000L;
122:
123:
126: private static long MILLISECONDS_IN_ONE_DAY = 24 * MILLISECONDS_IN_ONE_HOUR;
127:
128:
131: public RelativeDateFormat() {
132: this(0L);
133: }
134:
135:
140: public RelativeDateFormat(Date time) {
141: this(time.getTime());
142: }
143:
144:
149: public RelativeDateFormat(long baseMillis) {
150: super();
151: this.baseMillis = baseMillis;
152: this.showZeroDays = false;
153: this.showZeroHours = true;
154: this.positivePrefix = "";
155: this.dayFormatter = NumberFormat.getInstance();
156: this.daySuffix = "d";
157: this.hourSuffix = "h";
158: this.minuteSuffix = "m";
159: this.secondFormatter = NumberFormat.getNumberInstance();
160: this.secondFormatter.setMaximumFractionDigits(3);
161: this.secondFormatter.setMinimumFractionDigits(3);
162: this.secondSuffix = "s";
163:
164:
165:
166: this.calendar = new GregorianCalendar();
167: this.numberFormat = new DecimalFormat("0");
168: }
169:
170:
178: public long getBaseMillis() {
179: return this.baseMillis;
180: }
181:
182:
191: public void setBaseMillis(long baseMillis) {
192: this.baseMillis = baseMillis;
193: }
194:
195:
203: public boolean getShowZeroDays() {
204: return this.showZeroDays;
205: }
206:
207:
215: public void setShowZeroDays(boolean show) {
216: this.showZeroDays = show;
217: }
218:
219:
229: public boolean getShowZeroHours() {
230: return this.showZeroHours;
231: }
232:
233:
243: public void setShowZeroHours(boolean show) {
244: this.showZeroHours = show;
245: }
246:
247:
257: public String getPositivePrefix() {
258: return this.positivePrefix;
259: }
260:
261:
271: public void setPositivePrefix(String prefix) {
272: if (prefix == null) {
273: throw new IllegalArgumentException("Null 'prefix' argument.");
274: }
275: this.positivePrefix = prefix;
276: }
277:
278:
285: public String getDaySuffix() {
286: return this.daySuffix;
287: }
288:
289:
296: public void setDaySuffix(String suffix) {
297: if (suffix == null) {
298: throw new IllegalArgumentException("Null 'suffix' argument.");
299: }
300: this.daySuffix = suffix;
301: }
302:
303:
310: public String getHourSuffix() {
311: return this.hourSuffix;
312: }
313:
314:
321: public void setHourSuffix(String suffix) {
322: if (suffix == null) {
323: throw new IllegalArgumentException("Null 'suffix' argument.");
324: }
325: this.hourSuffix = suffix;
326: }
327:
328:
335: public String getMinuteSuffix() {
336: return this.minuteSuffix;
337: }
338:
339:
346: public void setMinuteSuffix(String suffix) {
347: if (suffix == null) {
348: throw new IllegalArgumentException("Null 'suffix' argument.");
349: }
350: this.minuteSuffix = suffix;
351: }
352:
353:
360: public String getSecondSuffix() {
361: return this.secondSuffix;
362: }
363:
364:
371: public void setSecondSuffix(String suffix) {
372: if (suffix == null) {
373: throw new IllegalArgumentException("Null 'suffix' argument.");
374: }
375: this.secondSuffix = suffix;
376: }
377:
378:
383: public void setSecondFormatter(NumberFormat formatter) {
384: if (formatter == null) {
385: throw new IllegalArgumentException("Null 'formatter' argument.");
386: }
387: this.secondFormatter = formatter;
388: }
389:
390:
400: public StringBuffer format(Date date, StringBuffer toAppendTo,
401: FieldPosition fieldPosition) {
402: long currentMillis = date.getTime();
403: long elapsed = currentMillis - this.baseMillis;
404: String signPrefix;
405: if (elapsed < 0) {
406: elapsed *= -1L;
407: signPrefix = "-";
408: }
409: else {
410: signPrefix = this.positivePrefix;
411: }
412:
413: long days = elapsed / MILLISECONDS_IN_ONE_DAY;
414: elapsed = elapsed - (days * MILLISECONDS_IN_ONE_DAY);
415: long hours = elapsed / MILLISECONDS_IN_ONE_HOUR;
416: elapsed = elapsed - (hours * MILLISECONDS_IN_ONE_HOUR);
417: long minutes = elapsed / 60000L;
418: elapsed = elapsed - (minutes * 60000L);
419: double seconds = elapsed / 1000.0;
420:
421: toAppendTo.append(signPrefix);
422: if (days != 0 || this.showZeroDays) {
423: toAppendTo.append(this.dayFormatter.format(days) + getDaySuffix());
424: }
425: if (hours != 0 || this.showZeroHours) {
426: toAppendTo.append(String.valueOf(hours) + getHourSuffix());
427: }
428: toAppendTo.append(String.valueOf(minutes) + getMinuteSuffix());
429: toAppendTo.append(this.secondFormatter.format(seconds)
430: + getSecondSuffix());
431: return toAppendTo;
432: }
433:
434:
442: public Date parse(String source, ParsePosition pos) {
443: return null;
444: }
445:
446:
453: public boolean equals(Object obj) {
454: if (obj == this) {
455: return true;
456: }
457: if (!(obj instanceof RelativeDateFormat)) {
458: return false;
459: }
460: if (!super.equals(obj)) {
461: return false;
462: }
463: RelativeDateFormat that = (RelativeDateFormat) obj;
464: if (this.baseMillis != that.baseMillis) {
465: return false;
466: }
467: if (this.showZeroDays != that.showZeroDays) {
468: return false;
469: }
470: if (this.showZeroHours != that.showZeroHours) {
471: return false;
472: }
473: if (!this.positivePrefix.equals(that.positivePrefix)) {
474: return false;
475: }
476: if (!this.daySuffix.equals(that.daySuffix)) {
477: return false;
478: }
479: if (!this.hourSuffix.equals(that.hourSuffix)) {
480: return false;
481: }
482: if (!this.minuteSuffix.equals(that.minuteSuffix)) {
483: return false;
484: }
485: if (!this.secondSuffix.equals(that.secondSuffix)) {
486: return false;
487: }
488: if (!this.secondFormatter.equals(that.secondFormatter)) {
489: return false;
490: }
491: return true;
492: }
493:
494:
499: public int hashCode() {
500: int result = 193;
501: result = 37 * result
502: + (int) (this.baseMillis ^ (this.baseMillis >>> 32));
503: result = 37 * result + this.positivePrefix.hashCode();
504: result = 37 * result + this.daySuffix.hashCode();
505: result = 37 * result + this.hourSuffix.hashCode();
506: result = 37 * result + this.minuteSuffix.hashCode();
507: result = 37 * result + this.secondSuffix.hashCode();
508: result = 37 * result + this.secondFormatter.hashCode();
509: return result;
510: }
511:
512:
517: public Object clone() {
518: RelativeDateFormat clone = (RelativeDateFormat) super.clone();
519: clone.dayFormatter = (NumberFormat) this.dayFormatter.clone();
520: clone.secondFormatter = (NumberFormat) this.secondFormatter.clone();
521: return clone;
522: }
523:
524:
529: public static void main(String[] args) {
530: GregorianCalendar c0 = new GregorianCalendar(2006, 10, 1, 0, 0, 0);
531: GregorianCalendar c1 = new GregorianCalendar(2006, 10, 1, 11, 37, 43);
532: c1.set(Calendar.MILLISECOND, 123);
533:
534: System.out.println("Default: ");
535: RelativeDateFormat rdf = new RelativeDateFormat(c0.getTime().getTime());
536: System.out.println(rdf.format(c1.getTime()));
537: System.out.println();
538:
539: System.out.println("Hide milliseconds: ");
540: rdf.setSecondFormatter(new DecimalFormat("0"));
541: System.out.println(rdf.format(c1.getTime()));
542: System.out.println();
543:
544: System.out.println("Show zero day output: ");
545: rdf.setShowZeroDays(true);
546: System.out.println(rdf.format(c1.getTime()));
547: System.out.println();
548:
549: System.out.println("Alternative suffixes: ");
550: rdf.setShowZeroDays(false);
551: rdf.setDaySuffix(":");
552: rdf.setHourSuffix(":");
553: rdf.setMinuteSuffix(":");
554: rdf.setSecondSuffix("");
555: System.out.println(rdf.format(c1.getTime()));
556: System.out.println();
557: }
558: }