首页 > 代码库 > jms中唯一的消息id的生成

jms中唯一的消息id的生成

在做消息中间件的开发中常常要生成唯一的消息的标识,可以根据项目部署的服务器加上相应的前缀,然后根据系统的 时间戳,时间戳太长了,可以转成36进制的字符串,便形成了消息的唯一标识:


import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

public class MsgIDUtil {
	private static final int BASE_YEAR = 2013;
	private static final long MILLISECOND_PER_DAY = 86400000L;
	private static long lastTicketTime = 0l;	

	public static synchronized String generateTicketNumber(String prefix) {
		if (prefix != null && prefix.trim().length() > 0) {
			return prefix + generateTicketNumber();
		}
		return generateTicketNumber();
	}
	
	public static synchronized String generateTicketNumber() {
		long givenTime = System.currentTimeMillis();
		if (givenTime <= lastTicketTime) {
			givenTime = lastTicketTime + 1;
		}
		String result = generateTicketNumber(givenTime);
		lastTicketTime = givenTime;
		return result;
	}
	
	protected static synchronized String generateTicketNumber(long givenTime) {

		Calendar cal = Calendar.getInstance();
		cal.setTimeInMillis(givenTime);

		int year = cal.get(Calendar.YEAR);
		int yearIndex = year - BASE_YEAR;
		if (yearIndex < 0 || yearIndex > 36) {
			throw new IllegalArgumentException("Input Time is earlier then " 
		          + BASE_YEAR + " or greater than " + BASE_YEAR + 36);
		}
		int dayOfYear = cal.get(Calendar.DAY_OF_YEAR);
		// get base line of the time of the day
		Calendar cal2 = Calendar.getInstance();
		cal2.clear();
		cal2.set(Calendar.YEAR, year);
		cal2.set(Calendar.DAY_OF_YEAR, dayOfYear);
		long baselineTime = cal2.getTimeInMillis();
		StringBuilder sb = new StringBuilder();
		sb.append(Integer.toString(yearIndex, 36));
		String dayOfYearStr = Integer.toString(dayOfYear, 36);
		for (int i = 0; i < (2 - dayOfYearStr.length()); i++) {
			sb.append(0);
		}
		sb.append(dayOfYearStr);
		String timeOfDayStr = Long.toString(givenTime - baselineTime, 36);
		for (int i = 0; i < (6 - timeOfDayStr.length()); i++) {
			sb.append(0);
		}
		sb.append(timeOfDayStr);
		return sb.toString().toUpperCase();
	}
	

	public static long getTicketTime(String ticketNumber) {
		if (ticketNumber == null || ticketNumber.trim().length() < 9 || ticketNumber.trim().length() > 10) {
			throw new IllegalArgumentException("Input ID is not valid -->" + ticketNumber);
		}

		if (ticketNumber.trim().length() == 10) {
			ticketNumber = ticketNumber.trim().substring(1);

		}

		int yearIndex = Integer.parseInt(ticketNumber.substring(0, 1), 36);
		int dayIndex = Integer.parseInt(ticketNumber.substring(1, 3), 36);
		long millIndex = Long.parseLong(ticketNumber.substring(3), 36);
		if (dayIndex > 365 || millIndex > MILLISECOND_PER_DAY) {
			throw new IllegalArgumentException("Can't parse the input Ticket number " + ticketNumber);
		}

		Calendar result = Calendar.getInstance();

		result.clear();

		result.set(Calendar.YEAR, BASE_YEAR + yearIndex);
		result.set(Calendar.DAY_OF_YEAR, dayIndex);
		return result.getTimeInMillis() + millIndex;
	}

	private static long getTimeFromStr(String dateValue, String dateFormat) throws ParseException {
		SimpleDateFormat sdFormat = new SimpleDateFormat(dateFormat);
		Date output = sdFormat.parse(dateValue);

		return output.getTime();
	}

	protected static synchronized String generateTicketNumber(String dateValue, String dateFormat) throws ParseException {
		long givenTime = getTimeFromStr(dateValue, dateFormat);
		return generateTicketNumber(givenTime);
	}

	

	public static void main(String[] args) {
		String newTicketNumber = generateTicketNumber("A");
		System.out.println(newTicketNumber);
	}

}


jms中唯一的消息id的生成