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 }