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