defaultformatter.java

来自「Struts2 + Spring JPA Hibernate demo.」· Java 代码 · 共 329 行

JAVA
329
字号
/*
 * $Id: DefaultFormatter.java 30 2006-06-08 13:26:40Z wjx $
 */
package com.vegeta.utils.datetime.formatter;

import com.vegeta.utils.datetime.common.DateTimeStamp;
import com.vegeta.utils.datetime.common.JDateTime;
import com.vegeta.utils.datetime.common.JdtFormatter;
import com.vegeta.utils.datetime.common.JdtNames;
import com.vegeta.utils.format.Format;

/**
 * Default formatter used for getting and setting date/time information to and
 * from strings.
 * <p>
 * 
 * For setting date and time, default formatter parses input String against
 * specified template. It extracts parts of input string upon patterns and then
 * each part is converted to a number for a date/time information. It doesn't
 * ignore any non-number charater. If conversion fails, <code>null</code> is
 * returned. Translations from String are done by Java.
 * <p>
 * 
 * Getting date time is also user firendly. Specified template may not only
 * contains patterns but also any text. To remove errors in decoding when text
 * may be reckognized as one of patterns, template text may be quoted with the '
 * sign. Double ' quote in the text will be decoded as single quote.
 * <p>
 * 
 * Bellow is the list of the patterns that may be used in templates. This list
 * enhances ISO 8601 standard. Patterns notted with + sign are used for
 * settings, all patterns are used for gettings.
 * 
 * <ul>
 * <li>YYYY + year</li>
 * <li>MM + month</li>
 * <li>DD + day of month</li>
 * <li>D - day of week</li>
 * <li>MML - month long name</li>
 * <li>MMS - month short name</li>
 * <li>DL - day of week long name</li>
 * <li>DS - day of week short name</li>
 * <li>hh + hour</li>
 * <li>mm + minute</li>
 * <li>ss + seconds (no milliseconds)</li>
 * <li>mss + milliseconds</li>
 * <li>ss.mss + seconds.milliseconds</li>
 * <li></li>DDD - day of year</li>
 * <li>WW - week of year</li>
 * <li>WWW - week of year with 'W' prefix</li>
 * <li>W - week of month</li>
 * </ul>
 * 
 * <p>
 * <a href="DefaultFormatter.java.html"><i>View Source</i></a>
 * </p>
 * 
 * @version $Revision: 30 $ $Date: 2006-06-08 21:26:40 +0800 (星期四, 08
 *          六月 2006) $
 */
public class DefaultFormatter implements JdtFormatter {

	/**
	 * Array of date/time format patterns according to ISO-8601 standard
	 * enhanced with custom patterns.
	 * <p>
	 * 
	 * 'L' suffix is used for long names and 'S' is used for short names text.
	 * <p>
	 * 
	 * Warnings:<br>
	 * 1. order of the array elements is IMPORTANT!<br>
	 * 2. the longest match is returned. 3. patterns that have '+' are used by
	 * set(). all patterns are used by get().
	 */
	private final char[][] formc = { "YYYY".toCharArray(), // 0 + year
			"MM".toCharArray(), // 1 + month
			"DD".toCharArray(), // 2 + day of month
			"D".toCharArray(), // 3 - day of week
			"MML".toCharArray(), // 4 - month long name
			"MMS".toCharArray(), // 5 - month short name
			"DL".toCharArray(), // 6 - day of week long name
			"DS".toCharArray(), // 7 - day of week short name
			"hh".toCharArray(), // 8 + hour
			"mm".toCharArray(), // 9 + minute
			"ss".toCharArray(), // 10 + seconds (no milliseconds)
			"mss".toCharArray(), // 11 + milliseconds
			"ss.mss".toCharArray(), // 12 + seconds.milliseconds
			"DDD".toCharArray(), // 13 - day of year
			"WW".toCharArray(), // 14 - week of year
			"WWW".toCharArray(), // 15 - week of year with 'W' prefix
			"W".toCharArray(), // 16 - week of month
	};

	private int findPattern(char[] frmtc, int i) {
		int frmtc_len = frmtc.length;
		boolean match = false;
		int n, lastn = -1;
		int maxLen = 0;
		for (n = 0; n < formc.length; n++) {
			char[] curr = formc[n]; // current pattern from the pattern list
			if (i > frmtc_len - curr.length) {
				continue;
			}
			match = true;
			int delta = 0;
			while (delta < curr.length) { // match given pattern
				if (curr[delta] != frmtc[i + delta]) {
					match = false; // no match, goto next
					break;
				}
				delta++;
			}
			if (match == true) { // match
				if (formc[n].length > maxLen) { // find longest match
					lastn = n;
					maxLen = formc[n].length;
				}
			}
		}
		return lastn;
	}

	private static final char QUOTE = '\'';

	/**
	 * Returns date as String in given format. Used by JDateTime for formatting
	 * the string that represents date/time information.
	 * 
	 * @param jdt
	 *            JDateTime instance
	 * @param frmt
	 *            format
	 * 
	 * @return date string in given format
	 */
	public String get(JDateTime jdt, String frmt) {
		char[] frmtc = frmt.toCharArray();
		int frmtc_len = frmtc.length;
		StringBuffer result = new StringBuffer(frmtc_len);

		int i = 0;
		while (i < frmtc_len) {

			if (frmtc[i] == QUOTE) { // quote founded
				int end = i + 1;
				while (end < frmtc_len) {
					if (frmtc[end] == QUOTE) { // second quote founded
						if (end + 1 < frmtc_len) {
							end++;
							if (frmtc[end] == QUOTE) { // skip double quotes
								result.append(QUOTE); // and continue
							} else {
								break;
							}
						}
					} else {
						result.append(frmtc[end]);
					}
					end++;
				}
				i = end;
				continue; // end of quoted string, continue the main loop
			}

			int n = findPattern(frmtc, i);
			if (n != -1) { // pattern founded
				JdtNames gds = jdt.getNames();
				switch (n) {
				case 0:
					result.append(Format.sprintf("%~04i", jdt.getYear()));
					break;
				case 1:
					result.append(Format.sprintf("%02i", jdt.getMonth()));
					break;
				case 2:
					result.append(Format.sprintf("%02i", jdt.getDay()));
					break;
				case 3:
					result.append(jdt.getDayOfWeek());
					break;
				case 4:
					result.append(gds.getMonths()[jdt.getMonth() - 1]);
					break;
				case 5:
					result.append(gds.getShortMonths()[jdt.getMonth() - 1]);
					break;
				case 6:
					result.append(gds.getDaysOfWeek()[jdt.getDayOfWeek() - 1]);
					break;
				case 7:
					result.append(gds.getShortDaysOfWeek()[jdt.getDayOfWeek() - 1]);
					break;
				case 8:
					result.append(Format.sprintf("%02d", jdt.getHour()));
					break;
				case 9:
					result.append(Format.sprintf("%02d", jdt.getMinute()));
					break;
				case 10:
					result.append(Format.sprintf("%02d", (int) jdt.getSecond()));
					break;
				case 11:
					result.append(Format.sprintf("%02d", jdt.getMillisecond()));
					break;
				case 12:
					result.append(Format.sprintf("%06.3f", jdt.getSecond()));
					break;
				case 13:
					result.append(Format.sprintf("%03d", jdt.getDayOfYear()));
					break;
				case 14:
					result.append(Format.sprintf("%02d", jdt.getWeekOfYear()));
					break;
				case 15:
					result.append(Format.sprintf("W%02d", jdt.getWeekOfYear()));
					break;
				case 16:
					result.append(jdt.getWeekOfMonth());
					break;
				}
				i += formc[n].length;
			} else {
				result.append(frmtc[i]);
				i++;
			}
		}
		return result.toString();
	}

	/**
	 * Sets time from the string using template. Used by JDateTime for setting
	 * new date/time from the string. But it is also used for validating if some
	 * string represents a valid date.
	 * <p>
	 * 
	 * @param s
	 *            String that contains time
	 * @param t
	 *            template
	 * 
	 * @return DateTimeStamp instance or <code>null</code> if error during
	 *         conversion occured
	 */
	public DateTimeStamp set(String s, String t) {
		char[] sc = s.toCharArray();
		char[] tc = t.toCharArray();

		int i = 0;
		int j = 0;
		int slen = s.length();
		int tlen = t.length();

		int year = 0, hour = 0, minute = 0;
		int month = 1, day = 1;
		double second = 0.0;

		while (true) {
			int n = findPattern(tc, i);
			if (n != -1) { // pattern founded
				i += formc[n].length;
				StringBuffer w = new StringBuffer();
				char next = 0xFFFF;
				if (i < tlen) {
					next = tc[i]; // next = delimeter
				}
				while ((j < slen) && (sc[j] != next)) {
					w.append(sc[j]);
					j++;
				}
				try {
					String ws = w.toString();
					int v = 0;
					double vd = 0;
					if (n != 12) { // not double
						v = Integer.parseInt(ws);
						if (n == 11) {
							vd = 1.0;
							for (int u = 0; u < ws.length(); u++) {
								vd *= 10.0;
							}
						}
					} else { // double
						vd = Double.parseDouble(ws);
						vd += 1e-9;
					}
					switch (n) {
					case 0:
						year = v;
						break;
					case 1:
						month = v;
						break;
					case 2:
						day = v;
						break;
					case 8:
						hour = v;
						break;
					case 9:
						minute = v;
						break;
					case 10:
						second += v;
						break;
					case 11:
						second += v / vd;
						break;
					case 12:
						second = vd;
						break;
					}
				} catch (NumberFormatException nfe) {
					return null;
				}
			} else {
				if (tc[i] == sc[j]) {
					j++;
				}
				i++;
			}
			if ((i == tlen) || (j == slen)) {
				break;
			}
		}
		return new DateTimeStamp(year, month, day, hour, minute, second);
	}
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?