Java日期类型的解析

从字符串解析出JAVA日期类型java.util.Date是一件相当痛苦的事情,下面就列出了一些被大量使用了的格式,可谓大观:
[table]
|标准/说明|示例|
|valid RFC 822 (2-digit year)|Thu, 01 Jan 04 19:48:21 GMT|
|valid RFC 822 (4-digit year)|Thu, 01 Jan 2004 19:48:21 GMT|
|invalid RFC 822 (no time)|01 Jan 2004|
|invalid RFC 822 (no seconds)|01 Jan 2004 00:00 GMT|
|valid W3CDTF (numeric timezone)|2003-12-31T10:14:55-08:00|
|valid W3CDTF (UTC timezone)|2003-12-31T10:14:55Z|
|valid W3CDTF (yyyy)|2003|
|valid W3CDTF (yyyy-mm)|2003-12|
|valid W3CDTF (yyyy-mm-dd)|2003-12-31|
|valid ISO 8601 (yyyymmdd)|20031231|
|valid ISO 8601 (-yy-mm)|-03-12|
|valid ISO 8601 (-yymm)|-0312|
|valid ISO 8601 (-yy-mm-dd)|-03-12-31|
|valid ISO 8601 (yymmdd)|031231|
|valid ISO 8601 (yyyy-o)|2003-335|
|valid ISO 8601 (yyo)|03335|
|valid asctime|Sun Jan 4 16:29:06 PST 2004|
|bogus RFC 822 (invalid day/month)|Thu, 31 Jun 2004 19:48:21 GMT|
|bogus RFC 822 (invalid month)|Mon, 26 January 2004 16:31:00 EST|
|bogus RFC 822 (invalid timezone)|Mon, 26 Jan 2004 16:31:00 ET|
|bogus W3CDTF (invalid hour)|2003-12-31T25:14:55Z|
|bogus W3CDTF (invalid minute)|2003-12-31T10:61:55Z|
|bogus W3CDTF (invalid second)|2003-12-31T10:14:61Z|
|bogus (MSSQL)|2004-07-08 23:56:58.0|
|bogus (MSSQL-ish, without fractional second)|2004-07-08 23:56:58|
|bogus (Korean)|2004-05-25 ? 11:23:17|
|bogus (Greek)|Κυρ, 11 Ιο?λ 2004 12:00:00 EST|
|bogus (Hungarian)|július-13T9:15-05:00|
[/table]

JodaTime虽然号称时下最流行的java date工具,但是对于这个问题也是爱莫能助,只能乖乖地进行格式匹配了。

为了不重复制造轮子,我从rssowl项目[http://www.rssowl.org/]中抽取了它的日期时间解析工具类,供各位童鞋参考:


import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;

/**
* Utility Class for working with <code>Dates</code>.
*
* @author bpasero
* modified by http://joeblow.iteye.com
* 2010-11-11
*/
public class DateUtils {

/** 1 Day in Millis */
public static final long DAY = 24L * 60L * 60L * 1000L;

/** 1 Week in Millis */
public static final long WEEK = 7 * DAY;

/* An array of custom date formats */
private static final DateFormat[] CUSTOM_DATE_FORMATS;

/* The Default Timezone to be used */
private static final TimeZone TIMEZONE = TimeZone.getTimeZone("UTC"); //$NON-NLS-1$

/**
* Tries different date formats to parse against the given string
* representation to retrieve a valid Date object.
*
* @param strdate
* Date as String
* @return Date The parsed Date
*/
public static Date parseDate(String strdate) {

/* Return in case the string date is not set */
if (strdate == null || strdate.length() == 0) return null;

Date result = null;
strdate = strdate.trim();
if (strdate.length() > 10) {

/* Open: deal with +4:00 (no zero before hour) */
if ((strdate.substring(strdate.length() - 5).indexOf("+") == 0 || strdate.substring(strdate.length() - 5).indexOf("-") == 0) && strdate.substring(strdate.length() - 5).indexOf(":") == 2) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
String sign = strdate.substring(strdate.length() - 5, strdate.length() - 4);
strdate = strdate.substring(0, strdate.length() - 5) + sign + "0" + strdate.substring(strdate.length() - 4); //$NON-NLS-1$
}

String dateEnd = strdate.substring(strdate.length() - 6);

/*
* try to deal with -05:00 or +02:00 at end of date replace with -0500 or
* +0200
*/
if ((dateEnd.indexOf("-") == 0 || dateEnd.indexOf("+") == 0) && dateEnd.indexOf(":") == 3) { //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
if (!"GMT".equals(strdate.substring(strdate.length() - 9, strdate.length() - 6))) { //$NON-NLS-1$
String oldDate = strdate;
String newEnd = dateEnd.substring(0, 3) + dateEnd.substring(4);
strdate = oldDate.substring(0, oldDate.length() - 6) + newEnd;
}
}
}

/* Try to parse the date */
int i = 0;
while (i < CUSTOM_DATE_FORMATS.length) {
try {

/*
* This Block needs to be synchronized, because the parse-Method in
* SimpleDateFormat is not Thread-Safe.
*/
synchronized (CUSTOM_DATE_FORMATS[i]) {
return CUSTOM_DATE_FORMATS[i].parse(strdate);
}
} catch (ParseException e) {
i++;
} catch (NumberFormatException e) {
i++;
}
}
return result;
}

/** Initialize the array of common date formats and formatter */
static {

/* Create Date Formats */
final String[] possibleDateFormats = {
/* RFC 1123 with 2-digit Year */"EEE, dd MMM yy HH:mm:ss z",
/* RFC 1123 with 4-digit Year */"EEE, dd MMM yyyy HH:mm:ss z",
/* RFC 1123 with no Timezone */"EEE, dd MMM yy HH:mm:ss",
/* Variant of RFC 1123 */"EEE, MMM dd yy HH:mm:ss",
/* RFC 1123 with no Seconds */"EEE, dd MMM yy HH:mm z",
/* Variant of RFC 1123 */"EEE dd MMM yyyy HH:mm:ss",
/* RFC 1123 with no Day */"dd MMM yy HH:mm:ss z",
/* RFC 1123 with no Day or Seconds */"dd MMM yy HH:mm z",
/* ISO 8601 slightly modified */"yyyy-MM-dd'T'HH:mm:ssZ",
/* ISO 8601 slightly modified */"yyyy-MM-dd'T'HH:mm:ss'Z'",
/* ISO 8601 slightly modified */"yyyy-MM-dd'T'HH:mm:sszzzz",
/* ISO 8601 slightly modified */"yyyy-MM-dd'T'HH:mm:ss z",
/* ISO 8601 */"yyyy-MM-dd'T'HH:mm:ssz",
/* ISO 8601 slightly modified */"yyyy-MM-dd'T'HH:mm:ss.SSSz",
/* ISO 8601 slightly modified */"yyyy-MM-dd'T'HHmmss.SSSz",
/* ISO 8601 slightly modified */"yyyy-MM-dd'T'HH:mm:ss",
/* ISO 8601 w/o seconds */"yyyy-MM-dd'T'HH:mmZ",
/* ISO 8601 w/o seconds */"yyyy-MM-dd'T'HH:mm'Z'",
/* RFC 1123 without Day Name */"dd MMM yyyy HH:mm:ss z",
/* RFC 1123 without Day Name and Seconds */"dd MMM yyyy HH:mm z",
/* Simple Date Format */"yyyy-MM-dd",
/* Simple Date Format */"MMM dd, yyyy" };

/* Create the dateformats */
CUSTOM_DATE_FORMATS = new SimpleDateFormat[possibleDateFormats.length];

for (int i = 0; i < possibleDateFormats.length; i++) {
CUSTOM_DATE_FORMATS[i] = new SimpleDateFormat(possibleDateFormats[i], Locale.ENGLISH);
CUSTOM_DATE_FORMATS[i].setTimeZone(TIMEZONE);
}
}
}



调用方法:


Date d = DateUtils.parseDate("Tue, 9 Nov 2010 12:45:00 GMT");



PS:11.11真是个有纪念意义的日子啊
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值