1 /************************************************************************ 2 * Copyright (c) 2000-2006 The Apache Software Foundation. * 3 * All rights reserved. * 4 * ------------------------------------------------------------------- * 5 * Licensed under the Apache License, Version 2.0 (the "License"); you * 6 * may not use this file except in compliance with the License. You * 7 * may obtain a copy of the License at: * 8 * * 9 * http://www.apache.org/licenses/LICENSE-2.0 * 10 * * 11 * Unless required by applicable law or agreed to in writing, software * 12 * distributed under the License is distributed on an "AS IS" BASIS, * 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * 14 * implied. See the License for the specific language governing * 15 * permissions and limitations under the License. * 16 ***********************************************************************/ 17 18 package org.apache.mailet.dates; 19 20 import java.text.ParseException; 21 import java.util.Date; 22 import java.util.Locale; 23 import java.util.TimeZone; 24 25 /*** 26 * A thread-safe date formatting class to produce dates formatted in accord with the 27 * specifications of RFC 977. 28 * 29 */ 30 public class RFC977DateFormat implements SimplifiedDateFormat { 31 32 /*** 33 * Internal date formatter for long date formats 34 */ 35 private final SynchronizedDateFormat internalLongDateFormat; 36 37 /*** 38 * Internal date formatter for short date formats 39 */ 40 private final SynchronizedDateFormat internalShortDateFormat; 41 42 /*** 43 * Constructor for RFC977DateFormat 44 */ 45 public RFC977DateFormat() { 46 internalLongDateFormat = new SynchronizedDateFormat("yyyyMMdd HHmmss", Locale.ENGLISH); 47 internalShortDateFormat = new SynchronizedDateFormat("yyMMdd HHmmss", Locale.ENGLISH); 48 } 49 50 /*** 51 * This method returns the long form of the RFC977 Date 52 * 53 * @return java.lang.String 54 * @param d Date 55 */ 56 public String format(Date d) { 57 return internalLongDateFormat.format(d); 58 } 59 60 /*** 61 * Parses text from the beginning of the given string to produce a date. 62 * The method may not use the entire text of the given string. 63 * <p> 64 * This method is designed to be thread safe, so we wrap our delegated 65 * parse method in an appropriate synchronized block. 66 * 67 * @param source A <code>String</code> whose beginning should be parsed. 68 * @return A <code>Date</code> parsed from the string. 69 * @throws ParseException if the beginning of the specified string 70 * cannot be parsed. 71 */ 72 public Date parse(String source) throws ParseException { 73 source = source.trim(); 74 if (source.indexOf(' ') == 6) { 75 return internalShortDateFormat.parse(source); 76 } else { 77 return internalLongDateFormat.parse(source); 78 } 79 } 80 81 /*** 82 * Sets the time zone of this SynchronizedDateFormat object. 83 * @param zone the given new time zone. 84 */ 85 public void setTimeZone(TimeZone zone) { 86 synchronized(this) { 87 internalShortDateFormat.setTimeZone(zone); 88 internalLongDateFormat.setTimeZone(zone); 89 } 90 } 91 92 /*** 93 * Gets the time zone. 94 * @return the time zone associated with this SynchronizedDateFormat. 95 */ 96 public TimeZone getTimeZone() { 97 synchronized(this) { 98 return internalShortDateFormat.getTimeZone(); 99 } 100 } 101 102 /*** 103 * Specify whether or not date/time parsing is to be lenient. With 104 * lenient parsing, the parser may use heuristics to interpret inputs that 105 * do not precisely match this object's format. With strict parsing, 106 * inputs must match this object's format. 107 * @param lenient when true, parsing is lenient 108 * @see java.util.Calendar#setLenient 109 */ 110 public void setLenient(boolean lenient) 111 { 112 synchronized(this) { 113 internalShortDateFormat.setLenient(lenient); 114 internalLongDateFormat.setLenient(lenient); 115 } 116 } 117 118 /*** 119 * Tell whether date/time parsing is to be lenient. 120 * @return whether this SynchronizedDateFormat is lenient. 121 */ 122 public boolean isLenient() 123 { 124 synchronized(this) { 125 return internalShortDateFormat.isLenient(); 126 } 127 } 128 129 130 /*** 131 * Overrides equals 132 */ 133 public boolean equals(Object obj) { 134 if (this == obj) { 135 return true; 136 } 137 if (!(obj instanceof RFC977DateFormat)) { 138 return false; 139 } 140 RFC977DateFormat theOtherRFC977DateFormat = (RFC977DateFormat)obj; 141 synchronized (this) { 142 return ((internalShortDateFormat.equals(theOtherRFC977DateFormat.internalShortDateFormat)) && 143 (internalLongDateFormat.equals(theOtherRFC977DateFormat.internalLongDateFormat))); 144 } 145 } 146 147 /*** 148 * Overrides hashCode 149 */ 150 public int hashCode() { 151 return (int)(internalLongDateFormat.hashCode() & internalShortDateFormat.hashCode()); 152 } 153 154 }