浏览 2990 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (1) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2010-01-13
最后修改:2010-01-15
在写Web程序中,往往要处理大量的时间日期显示的工作,一个灵活的格式化输出日期的工具必不可少。之前在网上找了好一会儿,没找到满意的,苦恼不已。索性,自己写个算了。
在这里跟大家共享。 这个是1.13的有错误的代码:
package cn.lhx.taglib.toolkit; import java.util.Calendar; import java.util.Date; import java.util.HashMap; import java.util.Map; import java.util.regex.Pattern; public class TimeFunction { private final static String wtb_en[] = { "am", "pm", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday", "january", "february", "march", "april", "may", "june", "july", "august", "september", "october", "november", "december", "gmt", "ut", "utc", "est", "edt", "cst", "cdt", "mst", "mdt", "pst", "pdt" }; private final static String wtb_cn[] = { "上午", "下午", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期天", "一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月", "gmt", "ut", "utc", "est", "edt", "cst", "cdt", "mst", "mdt", "pst", "pdt" }; //profile缓存 private final static Map<Date, Map<String, String>> proBuf=new HashMap<Date, Map<String,String>>(10); private final static Map<String,String> init(Date date){ Map<String,String> profile =(HashMap<String, String>)proBuf.get(date); //查找缓存,有解析过的就直接返回 if(profile!=null)return profile; date.toString(); //new 一个Map profile=new HashMap<String, String>(); //解析日期 Calendar calendar=Calendar.getInstance(); calendar.setTime(date); int year=calendar.get(Calendar.YEAR); int month=calendar.get(Calendar.MONTH);//月重0开始 int day=calendar.get(Calendar.DAY_OF_MONTH); int weekDay=calendar.get(Calendar.DAY_OF_WEEK); weekDay=(weekDay==Calendar.SUNDAY)? 7:(weekDay-1); int hour=calendar.get(Calendar.HOUR_OF_DAY); int minute=calendar.get(Calendar.MINUTE); int am_pm=calendar.get(Calendar.AM_PM);//0 AM 1 PM //年 profile.put("%Yc", year+"年"); profile.put("%Ye", year+""); profile.put("%Y", year+""); //月 profile.put("%Mc", wtb_cn[month+9]); profile.put("%Me", wtb_en[month+9]); profile.put("%M", (month+1)+""); //日 profile.put("%D",day+""); String dayDix="th"; //day调整1st、2nd、3rd dayDix=(day%10==1?"st":(day%10==2?"nd":(day%10==3?"rd":dayDix))); profile.put("%De",day+dayDix); profile.put("%Dc",day+"日"); //星期 profile.put("%W",weekDay+""); profile.put("%We",wtb_en[weekDay+1]); profile.put("%Wc",wtb_cn[weekDay+1]); //时间 int hour12=hour>12?hour-12:hour;//转换成12小时格式 profile.put("%T12",(hour12)+":"+minute); profile.put("%T24",hour+":"+minute); //上下午 profile.put("%N",wtb_en[am_pm]); profile.put("%Ne",wtb_en[am_pm]); profile.put("%Nc",wtb_cn[am_pm]); //放入缓存 proBuf.put(date, profile); return profile; } /** * 将日期转换成格式化字符串 * @param str 带有给事标识符的字符串 * @param date 日期对象 * @return * %Y[?]:年<br/> * %M[?]:月<br/> * %D[?]:日<br/> * %T[12|24]:时间,12表示十二小时制,24表示... * <br/>详细参数列表 * <table border=1px> * <tr><td>格式符</td><td>形式,示例</td><td>格式符</td><td>形式,示例</td></tr> * <tr><td>%Y</td><td>数字,2010</td><td>%D</td><td>日,数字</td></tr> * <tr><td>%Yc</td><td>数字+年,2010年</td><td>%Dc</td><td>数字+日,23日</td></tr> * <tr><td>%Ye</td><td>数字,2009</td><td>%De</td><td>数字+th,23th</td></tr> * <tr><td>%M</td><td>数字,12</td><td>%W</td><td>星期,数字,7</td></tr> * <tr><td>%Mc</td><td>中文+月,十二月</td><td>%We</td><td>英文,sunday</td></tr> * <tr><td>%Me</td><td>英文,dec</td><td>%Wc</td><td>中文,星期天</td></tr> * <tr><td>%N</td><td>英文,am</td><td>%Ne</td><td>中文,星期天</td></tr> * <tr><td>%Nc</td><td>中文,上午</td><td>%T[12|24]</td><td>数字,12:30</td></tr> * </table> * Example:<br/> * str="今天是%Yc,%Mc,%Dc,%Wc"<br/> * 输出:今天是2010年,一月,13日,星期三<br/> * str=""今天是%Yc,%Me,%De,%We""<br/> * 输出:今天是2010年,january,13rd,wednesday<br/> */ public static String getFormateTimeStr(String str,Date date){ //获得参数 Map<String, String> profile=init(date); //正则解析 java.util.regex.Pattern pattern=Pattern.compile("\\%[M,D,Y,T,N,W]([ce~]|[124]{0,2})"); java.util.regex.Matcher matcher=pattern.matcher(str); boolean isFind=matcher.find(); StringBuffer sb=new StringBuffer(); while (isFind) { String findStr=matcher.group(); // System.out.println("findStr =="+findStr); // System.out.println("group1== "+matcher.group(1)); // System.out.println("StartIndex== "+matcher.start()); // System.out.println("EndIndex== "+matcher.end()); if(profile.get(findStr)!=null){ //如果找到了就用profile里格式化串替换标记 matcher.appendReplacement(sb, profile.get(findStr)); } isFind=matcher.find(); } matcher.appendTail(sb); return sb.toString(); } //测试 public static void main(String[] args) { Date date=new Date(); System.out.println(TimeFunction.getFormateTimeStr("今天是%Yc,%Mc,%Dc,%Wc", date)); System.out.println(TimeFunction.getFormateTimeStr("今天是%Yc,%Me,%De,%We", date)); } } 使用到了java正则表达式库,和HashMap,其他的看代码应该不用过多解释了。 去掉代码中的一些system.out,可以观察解析过程。 1.14:修正了缓存的错误实现,以下是更新后的TimeFunction中的init方法,和静态量,对照旧版本,你会发现旧版本存在严重问题 //缓存容量 private final static int maxCapacity = 10; //profile缓存 private final static Map<Date, Map<String, String>> proBuf = new HashMap<Date, Map<String, String>>(maxCapacity); private final static Map<String, String> init(Date date) { //查找缓存 Date lastDate = date; for (Iterator it = proBuf.keySet().iterator(); it.hasNext();) { lastDate = (Date) it.next(); if (lastDate.equals(date)) { return proBuf.get(lastDate); } } //缓存中没有找到,new 一个Map Map<String, String> profile = new HashMap<String, String>(); //解析日期 Calendar calendar = Calendar.getInstance(); calendar.setTime(date); int year = calendar.get(Calendar.YEAR); int month = calendar.get(Calendar.MONTH);//月重0开始 int day = calendar.get(Calendar.DAY_OF_MONTH); int weekDay = calendar.get(Calendar.DAY_OF_WEEK); weekDay = (weekDay == Calendar.SUNDAY) ? 7 : (weekDay - 1); int hour = calendar.get(Calendar.HOUR_OF_DAY); int minute = calendar.get(Calendar.MINUTE); int am_pm = calendar.get(Calendar.AM_PM);//0 AM 1 PM //年 profile.put("%Yc", year + "年"); profile.put("%Ye", year + ""); profile.put("%Y", year + ""); //月 profile.put("%Mc", wtb_cn[month + 9]); profile.put("%Me", wtb_en[month + 9]); profile.put("%M", (month + 1) + ""); //日 profile.put("%D", day + ""); String dayDix = "th"; //day调整1st、2nd、3rd dayDix = (day % 10 == 1 ? "st" : (day % 10 == 2 ? "nd" : (day % 10 == 3 ? "rd" : dayDix))); profile.put("%De", day + dayDix); profile.put("%Dc", day + "日"); //星期 profile.put("%W", weekDay + ""); profile.put("%We", wtb_en[weekDay + 1]); profile.put("%Wc", wtb_cn[weekDay + 1]); //时间 int hour12 = hour > 12 ? hour - 12 : hour;//转换成12小时格式 profile.put("%T12", (hour12) + ":" + minute); profile.put("%T24", hour + ":" + minute); //上下午 profile.put("%N", wtb_en[am_pm]); profile.put("%Ne", wtb_en[am_pm]); profile.put("%Nc", wtb_cn[am_pm]); if (proBuf.size() < maxCapacity) { //放入缓存 proBuf.put(date, profile); } else { //移除最旧的日期profile proBuf.remove(lastDate); proBuf.put(date, profile); } // System.out.println("proBuf.size= "+proBuf.size()); return profile; } 标签定义文件:timefunction.tld <?xml version="1.0" encoding="UTF-8"?> <taglib xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd" version="2.0"> <description>MyTag 1.0</description> <tlib-version>1.0</tlib-version> <jsp-version>1.2</jsp-version> <short-name>tmf</short-name> <uri>/timefunction</uri> <function> <description> </description> <name>getFormateTimeStr</name> <function-class>cn.lhx.taglib.toolkit.TimeFunction</function-class> <function-signature>java.lang.String getFormateTimeStr(java.lang.String,java.util.Date)</function-signature> <example> </example> </function> </taglib> 标签的使用: 1.在web.xml中加入: <taglib> <taglib-uri>/timefunction</taglib-uri> <taglib-location>/WEB-INF/timefunction.tld</taglib-location> </taglib> 2.在jsp页面中加入: <%@ taglib uri="/timefunction" prefix="tmf"%> 3.在想要格式转换的地方加入自己的字符串,实例: <div class="postDate"> ${tmf:getFormateTimeStr( '<p> %Mc </p> <p class=day>%D</p> <p> %Y</p>' ,article.postTime) } </div> OK,不出意外的话,你应该看到结果了 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2010-02-01
轮子,jstl就可以
|
|
返回顶楼 | |
发表时间:2010-02-01
汗~是我孤陋寡闻了,确实有jstl的格式时间标签
|
|
返回顶楼 | |