六狼论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博账号登陆

只需一步,快速开始

搜索
查看: 32|回复: 0

Java日期类型的解析

[复制链接]

升级  92%

10

主题

10

主题

10

主题

童生

Rank: 1

积分
46
 楼主| 发表于 2013-2-3 11:23:41 | 显示全部楼层 |阅读模式
从字符串解析出JAVA日期类型java.util.Date是一件相当痛苦的事情,下面就列出了一些被大量使用了的格式,可谓大观:
标准/说明示例
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 asctimeSun 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


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) {return CUSTOM_DATE_FORMATS.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 = new SimpleDateFormat(possibleDateFormats, Locale.ENGLISH);CUSTOM_DATE_FORMATS.setTimeZone(TIMEZONE);}}}

调用方法:

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


PS:11.11真是个有纪念意义的日子啊
您需要登录后才可以回帖 登录 | 立即注册 新浪微博账号登陆

本版积分规则

快速回复 返回顶部 返回列表