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 | | |