Convert date in RFC2822 and UTC strings, and to build Date from string of dates in RFC2822 and UTC format : Date « Date Type « Android






Convert date in RFC2822 and UTC strings, and to build Date from string of dates in RFC2822 and UTC format

     
/*
 * Funambol is a mobile platform developed by Funambol, Inc. 
 * Copyright (C) 2003 - 2007 Funambol, Inc.
 * 
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License version 3 as published by
 * the Free Software Foundation with the addition of the following permission 
 * added to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED
 * WORK IN WHICH THE COPYRIGHT IS OWNED BY FUNAMBOL, FUNAMBOL DISCLAIMS THE 
 * WARRANTY OF NON INFRINGEMENT  OF THIRD PARTY RIGHTS.
 * 
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 * details.
 * 
 * You should have received a copy of the GNU Affero General Public License 
 * along with this program; if not, see http://www.gnu.org/licenses or write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301 USA.
 * 
 * You can contact Funambol, Inc. headquarters at 643 Bair Island Road, Suite 
 * 305, Redwood City, CA 94063, USA, or at email address info@funambol.com.
 * 
 * The interactive user interfaces in modified source and object code versions
 * of this program must display Appropriate Legal Notices, as required under
 * Section 5 of the GNU Affero General Public License version 3.
 * 
 * In accordance with Section 7(b) of the GNU Affero General Public License
 * version 3, these Appropriate Legal Notices must retain the display of the
 * "Powered by Funambol" logo. If the display of the logo is not reasonably 
 * feasible for technical reasons, the Appropriate Legal Notices must display
 * the words "Powered by Funambol".
 */

//package com.funambol.util;

import java.util.Calendar;
import java.util.Date;

/**
 * A utility class providing methods to convert date information contained in
 * <code>Date</code> objects into RFC2822 and UTC ('Zulu') strings, and to build
 * <code>Date</code> objects starting from string representations of dates in
 * RFC2822 and UTC format
 */
public class MailDateFormatter {

  /** Format date as: MM/DD */
  public static final int FORMAT_MONTH_DAY = 0;
  /** Format date as: MM/DD/YYYY */
  public static final int FORMAT_MONTH_DAY_YEAR = 1;
  /** Format date as: hh:mm */
  public static final int FORMAT_HOURS_MINUTES = 2;
  /** Format date as: hh:mm:ss */
  public static final int FORMAT_HOURS_MINUTES_SECONDS = 3;
  /** Format date as: DD/MM */
  public static final int FORMAT_DAY_MONTH = 4;
  /** Format date as: DD/MM/YYYY */
  public static final int FORMAT_DAY_MONTH_YEAR = 5;

  /** Device offset, as string */
  private static String deviceOffset = "+0000";
  /** Device offset, in millis */
  private static long millisDeviceOffset = 0;

  /** Names of the months */
  private static String[] monthNames = new String[] { "Jan", "Feb", "Mar",
      "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };

  /**
   * Transforms data contained in a <code>Date</code> object (expressed in
   * UTC) in a string formatted as per RFC2822 in local time (par. 3.3)
   * 
   * @return A string representing the date contained in the passed
   *         <code>Date</code> object formatted as per RFC 2822 and in local
   *         time
   */
  public static String dateToRfc2822(final Date date) {

    final Calendar deviceTime = Calendar.getInstance();
    deviceTime.setTime(date);

    String dayweek = "";
    final int dayOfWeek = deviceTime.get(Calendar.DAY_OF_WEEK);
    switch (dayOfWeek) {
    case 1:
      dayweek = "Sun";
      break;
    case 2:
      dayweek = "Mon";
      break;
    case 3:
      dayweek = "Tue";
      break;
    case 4:
      dayweek = "Wed";
      break;
    case 5:
      dayweek = "Thu";
      break;
    case 6:
      dayweek = "Fri";
      break;
    case 7:
      dayweek = "Sat";
      break;
    }

    final int dayOfMonth = deviceTime.get(Calendar.DAY_OF_MONTH);

    final String monthInYear = MailDateFormatter.getMonthName(deviceTime
        .get(Calendar.MONTH));

    final int year = deviceTime.get(Calendar.YEAR);

    final int hourOfDay = deviceTime.get(Calendar.HOUR_OF_DAY);
    final int minutes = deviceTime.get(Calendar.MINUTE);
    final int seconds = deviceTime.get(Calendar.SECOND);

    final String rfc = dayweek + ", " + // Tue
        dayOfMonth + " " + // 7
        monthInYear + " " + // Nov
        year + " " + // 2006
        hourOfDay + ":" + minutes + ":" + seconds + " " + // 14:13:26
        MailDateFormatter.deviceOffset; // +0200
    return rfc;
  }

  /**
   * Converts a <code>Date</code> object into a string in 'Zulu' format
   * 
   * @param d
   *            A <code>Date</code> object to be converted into a string in
   *            'Zulu' format
   * @return A string representing the date contained in the passed
   *         <code>Date</code> object in 'Zulu' format (e.g. yyyyMMDDThhmmssZ)
   */
  public static String dateToUTC(final Date d) {
    final StringBuffer date = new StringBuffer();
    final Calendar cal = Calendar.getInstance();
    cal.setTime(d);

    date.append(cal.get(Calendar.YEAR));

    date.append(
        MailDateFormatter.printTwoDigits(cal.get(Calendar.MONTH) + 1))
        .append(
            MailDateFormatter
                .printTwoDigits(cal.get(Calendar.DATE)))
        .append("T");

    date
        .append(
            MailDateFormatter.printTwoDigits(cal
                .get(Calendar.HOUR_OF_DAY))).append(
            MailDateFormatter.printTwoDigits(cal
                .get(Calendar.MINUTE))).append(
            MailDateFormatter.printTwoDigits(cal
                .get(Calendar.SECOND))).append("Z");

    return date.toString();
  }

  /**
   * A method that returns a string rapresenting a date.
   * 
   * @param date
   *            the date
   * 
   * @param format
   *            the format as one of FORMAT_MONTH_DAY, FORMAT_MONTH_DAY_YEAR,
   *            FORMAT_HOURS_MINUTES, FORMAT_HOURS_MINUTES_SECONDS
   *            FORMAT_DAY_MONTH FORMAT_DAY_MONTH_YEAR constants
   * 
   * @param separator
   *            the separator to be used
   */
  public static String getFormattedStringFromDate(final Date date,
      final int format, final String separator) {

    final Calendar cal = Calendar.getInstance();
    cal.setTime(date);
    final StringBuffer ret = new StringBuffer();

    switch (format) {
    case FORMAT_HOURS_MINUTES:
      // if pm and hour == 0 we want to write 12, not 0
      if (cal.get(Calendar.AM_PM) == Calendar.PM
          && cal.get(Calendar.HOUR) == 0)
        ret.append("12");
      else
        ret.append(cal.get(Calendar.HOUR));
      ret.append(separator).append(
          MailDateFormatter.printTwoDigits(cal.get(Calendar.MINUTE)))
          .append(MailDateFormatter.getAMPM(cal));
      break;

    case FORMAT_HOURS_MINUTES_SECONDS:
      // if pm and hour == 0 we want to write 12, not 0
      if (cal.get(Calendar.AM_PM) == Calendar.PM
          && cal.get(Calendar.HOUR) == 0)
        ret.append("12");
      else
        ret.append(cal.get(Calendar.HOUR));
      ret.append(separator).append(
          MailDateFormatter.printTwoDigits(cal.get(Calendar.MINUTE)))
          .append(separator).append(cal.get(Calendar.SECOND)).append(
              MailDateFormatter.getAMPM(cal));
      break;

    case FORMAT_MONTH_DAY:
      ret.append(cal.get(Calendar.MONTH) + 1).append(separator).append(
          cal.get(Calendar.DAY_OF_MONTH));
      break;

    case FORMAT_DAY_MONTH:
      ret.append(cal.get(Calendar.DAY_OF_MONTH)).append(separator)
          .append(cal.get(Calendar.MONTH) + 1);
      break;

    case FORMAT_MONTH_DAY_YEAR:
      ret.append(cal.get(Calendar.MONTH) + 1).append(separator).append(
          cal.get(Calendar.DAY_OF_MONTH)).append(separator).append(
          cal.get(Calendar.YEAR));
      break;

    case FORMAT_DAY_MONTH_YEAR:
      ret.append(cal.get(Calendar.DAY_OF_MONTH)).append(separator)
          .append(cal.get(Calendar.MONTH) + 1).append(separator)
          .append(cal.get(Calendar.YEAR));
      break;

    default:
    //  Log.error("getFormattedStringFromDate: invalid format (" + format
    //      + ")");
    }

    return ret.toString();
  }

  /**
   * Returns a localized string representation of Date.
   */
  public static String formatLocalTime(final Date d) {
    int dateFormat = MailDateFormatter.FORMAT_MONTH_DAY_YEAR;
    final int timeFormat = MailDateFormatter.FORMAT_HOURS_MINUTES;

    if (!System.getProperty("microedition.locale").equals("en"))
      dateFormat = MailDateFormatter.FORMAT_DAY_MONTH_YEAR;
    return MailDateFormatter.getFormattedStringFromDate(d, dateFormat, "/")
        + " "
        + MailDateFormatter.getFormattedStringFromDate(d, timeFormat,
            ":");
  }

  /**
   * Parses the string in RFC 2822 format and return a <code>Date</code>
   * object.
   * <p>
   * Parse strings like: Thu, 03 May 2007 14:45:38 GMT Thu, 03 May 2007
   * 14:45:38 GMT+0200 Thu, 1 Feb 2007 03:57:01 -0800 Fri, 04 May 2007
   * 13:40:17 PDT
   * 
   * @param d
   *            the date representation to parse
   * @return a date, if valid, or null on error
   * 
   */
  public static Date parseRfc2822Date(String stringDate) {
    if (stringDate == null)
      return null;

    long hourOffset = 0;
    long minOffset = 0;
    final Calendar cal = Calendar.getInstance();

    try {

    //  Log.info("Date original: " + stringDate);

      // Just skip the weekday if present
      int start = stringDate.indexOf(',');
      // put start after ", "
      start = (start == -1) ? 0 : start + 2;

      stringDate = stringDate.substring(start).trim();
      start = 0;

      // Get day of month
      int end = stringDate.indexOf(' ', start);

      int day = 1;
      try {
        day = Integer.parseInt(stringDate.substring(start, end));
      } catch (final NumberFormatException ex) {
        // some phones (Nokia 6111) have a invalid date format,
        // something like Tue10 Jul... instead of Tue, 10
        // so we try to strip (again) the weekday
        day = Integer.parseInt(stringDate.substring(start + 3, end));
      //  Log.info("Nokia 6111 patch applied.");
      }

      cal.set(Calendar.DAY_OF_MONTH, day);

      // Get month
      start = end + 1;
      end = stringDate.indexOf(' ', start);
      cal.set(Calendar.MONTH, MailDateFormatter.getMonthNumber(stringDate
          .substring(start, end)));
      // Get year
      start = end + 1;
      end = stringDate.indexOf(' ', start);
      cal.set(Calendar.YEAR, Integer.parseInt(stringDate.substring(start,
          end)));
      // Get hour
      start = end + 1;
      end = stringDate.indexOf(':', start);
      cal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(stringDate
          .substring(start, end).trim()));
      // Get min
      start = end + 1;
      end = stringDate.indexOf(':', start);
      cal.set(Calendar.MINUTE, Integer.parseInt(stringDate.substring(
          start, end)));
      // Get sec
      start = end + 1;
      end = stringDate.indexOf(' ', start);
      cal.set(Calendar.SECOND, Integer.parseInt(stringDate.substring(
          start, end)));
      // Get OFFSET
      start = end + 1;
      end = stringDate.indexOf('\r', start);

      // Process Timezone, checking first for the actual RFC2822 format,
      // and then for nthe obsolete syntax.

      char sign = '+';
      String hourDiff = "0";
      String minDiff = "0";

      final String offset = stringDate.substring(start).trim();
      if (offset.startsWith("+") || offset.startsWith("-")) {
        if (offset.length() >= 5) {
          sign = offset.charAt(0);
          hourDiff = offset.substring(1, 3);
          minDiff = offset.substring(3, 5);
        } else if (offset.length() == 3) {
          sign = offset.charAt(0);
          hourDiff = offset.substring(1);
          minDiff = "00";
        }
        // Convert offset to int
        hourOffset = Long.parseLong(hourDiff);
        minOffset = Long.parseLong(minDiff);
        if (sign == '-')
          hourOffset = -hourOffset;
      } else if (offset.equals("EDT"))
        hourOffset = -4;
      else if (offset.equals("EST") || offset.equals("CDT"))
        hourOffset = -5;
      else if (offset.equals("CST") || offset.equals("MDT"))
        hourOffset = -6;
      else if (offset.equals("PDT") || offset.equals("MST"))
        hourOffset = -7;
      else if (offset.equals("PST"))
        hourOffset = -8;
      else if (offset.equals("GMT") || offset.equals("UT"))
        hourOffset = 0;
      else if (offset.substring(0, 3).equals("GMT")
          && offset.length() > 3) {
        sign = offset.charAt(3);
        hourDiff = offset.substring(4, 6);
        minDiff = offset.substring(6, 8);
      }

      final long millisOffset = (hourOffset * 3600000)
          + (minOffset * 60000);

      final Date gmtDate = cal.getTime();
      long millisDate = gmtDate.getTime();

      millisDate -= millisOffset;

      gmtDate.setTime(millisDate);
      return gmtDate;

    } catch (final Exception e) {
    //  Log.error("Exception in parseRfc2822Date: " + e.toString()
    //      + " parsing " + stringDate);
      e.printStackTrace();
      return null;
    }
  }

  /**
   * Convert the given date (GMT) into the local date. NOTE: changes the
   * original date too! Should we change it to a void toLocalDate(Date) that
   * changes the input date only?
   */
  public static Date getDeviceLocalDate(final Date gmtDate) {
    if (null != gmtDate) {
      /*
       * long dateInMillis = gmtDate.getTime(); Date deviceDate = new
       * Date(); deviceDate.setTime(dateInMillis+millisDeviceOffset);
       * return deviceDate;
       */
      gmtDate.setTime(gmtDate.getTime()
          + MailDateFormatter.millisDeviceOffset);
      return gmtDate;
    } else
      return null;
  }

  /**
   * Gets a <code>Date</code> object from a string representing a date in
   * 'Zulu' format (yyyyMMddTHHmmssZ)
   * 
   * @param utc
   *            date in 'Zulu' format (yyyyMMddTHHmmssZ)
   * @return A <code>Date</code> object obtained starting from a time in
   *         milliseconds from the Epoch
   */
  public static Date parseUTCDate(final String utc) {

    int day = 0;
    int month = 0;
    int year = 0;
    int hour = 0;
    int minute = 0;
    int second = 0;
    Calendar calendar = null;

    day = Integer.parseInt(utc.substring(6, 8));
    month = Integer.parseInt(utc.substring(4, 6));
    year = Integer.parseInt(utc.substring(0, 4));
    hour = Integer.parseInt(utc.substring(9, 11));
    minute = Integer.parseInt(utc.substring(11, 13));
    second = Integer.parseInt(utc.substring(13, 15));

    calendar = Calendar.getInstance();

    calendar.set(Calendar.DAY_OF_MONTH, day);
    calendar.set(Calendar.MONTH, month - 1);
    calendar.set(Calendar.YEAR, year);
    calendar.set(Calendar.HOUR_OF_DAY, hour);
    calendar.set(Calendar.MINUTE, minute);
    calendar.set(Calendar.SECOND, second);

    final Date date = calendar.getTime();
    final long dateInMillis = date.getTime();

    date.setTime(dateInMillis + MailDateFormatter.millisDeviceOffset);

    return date;
  }

  public static void setTimeZone(final String timeZone) {

    if (timeZone == null || timeZone.length() < 5)
      //Log.error("setTimeZone: invalid timezone " + timeZone);

    try {
      MailDateFormatter.deviceOffset = timeZone;
      final String hstmz = MailDateFormatter.deviceOffset.substring(1, 3);
      final String mstmz = MailDateFormatter.deviceOffset.substring(3, 5);

      final long hhtmz = Long.parseLong(hstmz);
      final long mmtmz = Long.parseLong(mstmz);
      MailDateFormatter.millisDeviceOffset = (hhtmz * 3600000)
          + (mmtmz * 60000);
      if (MailDateFormatter.deviceOffset.charAt(0) == '-')
        MailDateFormatter.millisDeviceOffset *= -1;

    } catch (final Exception e) {
      //Log.error("setTimeZone: " + e.toString());
      e.printStackTrace();
    }
  }

  // ------------------------------------------------------------- Private
  // methods

  /**
   * Get the number of the month, given the name.
   */
  private static int getMonthNumber(final String name) {
    for (int i = 0, l = MailDateFormatter.monthNames.length; i < l; i++)
      if (MailDateFormatter.monthNames[i].equals(name))
        return i;
    return -1;
  }

  /**
   * Get the name of the month, given the number.
   */
  private static String getMonthName(final int number) {
    if (number > 0 && number < MailDateFormatter.monthNames.length)
      return MailDateFormatter.monthNames[number];
    else
      return null;
  }

  private static String getAMPM(final Calendar cal) {
    return (cal.get(Calendar.AM_PM) == Calendar.AM) ? "a" : "p";
  }

  /**
   * Returns a string representation of number with at least 2 digits
   */
  private static String printTwoDigits(final int number) {
    if (number > 9)
      return String.valueOf(number);
    else
      return "0" + number;
  }

}

   
    
    
    
    
  








Related examples in the same category

1.Write Date to AudioTrack
2.Represents a date using an integer, in a similar fashion to the implementation in Microsoft Excel.
3.A formatter that formats dates to show the elapsed time relative to some base date.
4.Iso Date
5.Get the string of the date using format "yyyy-MM-dd HH:mm:ss"
6.Parse a string that contains date, return a date object using format "yyyy-MM-dd HH:mm:ss"
7.Create Date from timestamp
8.Gets a "HH:mm:ss.SSS EEE dd MMM yyyy" representation of a Date
9.Gets a "yyyy MMM dd, HH:mm:ss.SSS" representation of a Date
10.Gets a "EEE, dd MMM yyyy hh:mm:ss 'GMT'" representation of a Date
11.Parses a String for a "EEE, dd MMM yyyy hh:mm:ss 'GMT'" formatted Date
12.Formatting and parsing the various date formats we expect to encounter.
13.ISO8601, ISO8601, RFC822 Date format
14.Easter Date
15.Parse Date
16.compare Two dates with Day value
17.compare Two dates with Second value
18.Get start of a date
19.Get start date of a Month
20.Get start date of a year
21.Create date from year, month and day value
22.Create Date from year, month, day, hour, minute, second
23.Get year value from Date
24.Get Month value from Date
25.Get Day value from Date
26.Get now in Date and Millis-seconds
27.Add day, Month and year to a Date
28.Parse date in format of yyyyMMddHHmmss or yyyyMMdd
29.String to Date
30.Convert date value in long to YYYYMMDDHHMMSS format
31.Convert Date to Number
32.Get short and long date String
33.Convert Java Date To Xml Time
34.Convert dates to Julian dates.
35.Parse an RFC 822 date string.
36.Format a date into a format suitable for SQLite
37.Dot String to Date
38.Parses an RFC822 formatted date string.
39.Formats a Date according to RFC822.
40.DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT).format(date);
41.yyyy-MM-dd HH:mm:ss date format
42.Utility class for formatting and parsing the various date formats we expect to encounter.
43.Get a string representation of a date as it relates to the current time.
44.get Date String from milliseconds
45.Generate a ISO 8601 date
46.Generate a Calendar from ISO 8601 date
47.parse Date for list of possible formats
48.date To String
49.Get date string for Locale tr
50.RFC3339 Date
51.Date formats
52.build Date Format day-of-week Short
53.Get end of each day
54.Get the end of each Month
55.Get end of a year
56.calculate Month Distance
57.calculate Day Distance
58.The month, and just the month, is zero-based. Add 1 for display.
59.Get hour different
60.format Millis Into Human Readable