FileDocCategorySizeDatePackage
MailDateFormat.javaAPI DocGlassfish v2 API24646Mon May 14 15:28:50 BST 2007javax.mail.internet

MailDateFormat

public class MailDateFormat extends SimpleDateFormat
Formats and parses date specification based on the draft-ietf-drums-msg-fmt-08 dated January 26, 2000. This is a followup spec to RFC822.

This class does not take pattern strings. It always formats the date based on the specification below.

3.3 Date and Time Specification

Date and time occur in several header fields of a message. This section specifies the syntax for a full date and time specification. Though folding whitespace is permitted throughout the date-time specification, it is recommended that only a single space be used where FWS is required and no space be used where FWS is optional in the date-time specification; some older implementations may not interpret other occurrences of folding whitespace correctly.

date-time = [ day-of-week "," ] date FWS time [CFWS]

day-of-week = ([FWS] day-name) / obs-day-of-week

day-name = "Mon" / "Tue" / "Wed" / "Thu" / "Fri" / "Sat" / "Sun"

date = day month year

year = 4*DIGIT / obs-year

month = (FWS month-name FWS) / obs-month

month-name = "Jan" / "Feb" / "Mar" / "Apr" /
"May" / "Jun" / "Jul" / "Aug" /
"Sep" / "Oct" / "Nov" / "Dec"

day = ([FWS] 1*2DIGIT) / obs-day

time = time-of-day FWS zone

time-of-day = hour ":" minute [ ":" second ]

hour = 2DIGIT / obs-hour

minute = 2DIGIT / obs-minute

second = 2DIGIT / obs-second

zone = (( "+" / "-" ) 4DIGIT) / obs-zone

The day is the numeric day of the month. The year is any numeric year in the common era.

The time-of-day specifies the number of hours, minutes, and optionally seconds since midnight of the date indicated.

The date and time-of-day SHOULD express local time.

The zone specifies the offset from Coordinated Universal Time (UTC, formerly referred to as "Greenwich Mean Time") that the date and time-of-day represent. The "+" or "-" indicates whether the time-of-day is ahead of or behind Universal Time. The first two digits indicate the number of hours difference from Universal Time, and the last two digits indicate the number of minutes difference from Universal Time. (Hence, +hhmm means +(hh * 60 + mm) minutes, and -hhmm means -(hh * 60 + mm) minutes). The form "+0000" SHOULD be used to indicate a time zone at Universal Time. Though "-0000" also indicates Universal Time, it is used to indicate that the time was generated on a system that may be in a local time zone other than Universal Time.

A date-time specification MUST be semantically valid. That is, the day-of-the week (if included) MUST be the day implied by the date, the numeric day-of-month MUST be between 1 and the number of days allowed for the specified month (in the specified year), the time-of-day MUST be in the range 00:00:00 through 23:59:60 (the number of seconds allowing for a leap second; see [STD-12]), and the zone MUST be within the range -9959 through +9959.

author
Max Spivak
since
JavaMail 1.2

Fields Summary
private static final long
serialVersionUID
static boolean
debug
method of what to look for: skip WS skip day "," (this is "Mon", "Tue") skip WS parse number (until WS) ==> 1*2DIGIT (day of month) skip WS parse alpha chars (until WS) ==> find month skip WS parse number (until WS) ==> 2*4DIGIT (year) skip WS // now looking for time parse number (until ':') ==> hours parse number (until ':') ==> minutes parse number (until WS) ==> seconds // now look for Time Zone skip WS if ('+' or '-') then numerical time zone offset if (alpha) then alpha time zone offset
private static TimeZone
tz
private static Calendar
cal
Constructors Summary
public MailDateFormat()


      
	super("EEE, d MMM yyyy HH:mm:ss 'XXXXX' (z)", Locale.US);
    
Methods Summary
public java.lang.StringBufferformat(java.util.Date date, java.lang.StringBuffer dateStrBuf, java.text.FieldPosition fieldPosition)
Formats the given date in the format specified by draft-ietf-drums-msg-fmt-08 in the current TimeZone.

param
date the Date object
param
dateStrBuf the formatted string
param
fieldPosition the current field position
return
StringBuffer the formatted String
since
JavaMail 1.2


	/* How this method works: First format the date with the
	 * format specified in the constructor inserting string 'XXXXX' 
	 * where the timezone offset goes. Find where in the string the
	 * string 'XXXXX' appears and remember that in var "pos". 
	 * Calculate the offset, taking the DST into account and insert
	 * it into the stringbuffer at position pos.
	 */

	int start = dateStrBuf.length();
	super.format(date, dateStrBuf, fieldPosition);
	int pos = 0;
	// find the beginning of the 'XXXXX' string in the formatted date
	// 25 is the first position that we expect to find XXXXX at
	for (pos = start + 25; dateStrBuf.charAt(pos) != 'X"; pos++)
	    ;

	// set the timezone to +HHMM or -HHMM
	calendar.clear();
	calendar.setTime(date);
	int offset = calendar.get(Calendar.ZONE_OFFSET) +
			calendar.get(Calendar.DST_OFFSET);
	// take care of the sign
	if (offset < 0) {
	    dateStrBuf.setCharAt(pos++, '-");
	    offset = (-offset);
	} else
	    dateStrBuf.setCharAt(pos++, '+");

	int rawOffsetInMins = offset / 60 / 1000; // offset from GMT in mins
 	int offsetInHrs = rawOffsetInMins / 60;
	int offsetInMins = rawOffsetInMins % 60;

	dateStrBuf.setCharAt(pos++, Character.forDigit((offsetInHrs/10), 10));
	dateStrBuf.setCharAt(pos++, Character.forDigit((offsetInHrs%10), 10));
	dateStrBuf.setCharAt(pos++, Character.forDigit((offsetInMins/10), 10));
	dateStrBuf.setCharAt(pos++, Character.forDigit((offsetInMins%10), 10));
	// done with timezone
	
	return dateStrBuf;
    
private static synchronized java.util.DateourUTC(int year, int mon, int mday, int hour, int min, int sec, int tzoffset, boolean lenient)

             
					        
					       
	// clear the time and then set all the values
	cal.clear();
	cal.setLenient(lenient);
	cal.set(Calendar.YEAR, year);
	cal.set(Calendar.MONTH, mon);
	cal.set(Calendar.DATE, mday);
	cal.set(Calendar.HOUR_OF_DAY, hour);
	cal.set(Calendar.MINUTE, min + tzoffset);  // adjusted for the timezone
	cal.set(Calendar.SECOND, sec);

	return cal.getTime();
    
public java.util.Dateparse(java.lang.String text, java.text.ParsePosition pos)
Parses the given date in the format specified by draft-ietf-drums-msg-fmt-08 in the current TimeZone.

param
text the formatted date to be parsed
param
pos the current parse position
return
Date the parsed date in a Date object
since
JavaMail 1.2

	return parseDate(text.toCharArray(), pos, isLenient());
    
private static java.util.DateparseDate(char[] orig, java.text.ParsePosition pos, boolean lenient)
create a Date by parsing the char array


                 
          
				  
	try {
	    int day = -1;
	    int month = -1;
	    int year = -1;
	    int hours = 0;
	    int minutes = 0;
	    int seconds = 0;
	    int offset = 0;
		
			
	    MailDateParser p = new MailDateParser(orig);
			
	    // get the day
	    p.skipUntilNumber();
	    day = p.parseNumber();

	    if (!p.skipIfChar('-")) {  // for IMAP internal Date
		p.skipWhiteSpace();
	    }

	    // get the month		
	    month = p.parseMonth();
	    if (!p.skipIfChar('-")) {  // for IMAP internal Date
		p.skipWhiteSpace();
	    }
	    
	    // get the year
	    year = p.parseNumber();	// should not return a negative number
	    if (year < 50) {
		year += 2000;
	    } else if (year < 100) {
		year += 1900;
	    } // otherwise the year is correct (and should be 4 digits)
			
			
	    // get the time
	    // first get hours
	    p.skipWhiteSpace();
	    hours = p.parseNumber();
			
	    // get minutes
	    p.skipChar(':");
	    minutes = p.parseNumber();
	    
	    // get seconds  (may be no seconds)
	    if (p.skipIfChar(':")) {
		seconds = p.parseNumber();
	    }
	    
			
	    // try to get a Time Zone
	    try {
		p.skipWhiteSpace();
		offset = p.parseTimeZone();
	    } catch (ParseException pe) {
		if (debug) {
		    System.out.println("No timezone? : '" +
						new String(orig) + "'");
		}
	    }
			
	    pos.setIndex(p.getIndex());
	    Date d = ourUTC(year, month, day, hours, minutes, seconds, offset,
							lenient);
	    return d;

	} catch (Exception e) {
	    // Catch *all* exceptions, including RuntimeExceptions like
	    // ArrayIndexOutofBoundsException ... we need to be
	    // extra tolerant of all those bogus dates that might screw
	    // up our parser. Sigh.

	    if (debug) {
		System.out.println("Bad date: '" + new String(orig) + "'");
		e.printStackTrace();
	    }
	    pos.setIndex(1); // to prevent DateFormat.parse() from throwing ex
	    return null;
	}
    
public voidsetCalendar(java.util.Calendar newCalendar)
Don't allow setting the calendar

	throw new RuntimeException("Method setCalendar() shouldn't be called");
    
public voidsetNumberFormat(java.text.NumberFormat newNumberFormat)
Don't allow setting the NumberFormat

	throw new RuntimeException("Method setNumberFormat() shouldn't be called");