锁定老帖子 主题:时间工具类,主要用于sql的时间段查询
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2010-12-28
最后修改:2010-12-28
该类提供如下方法: 1、获取系统按天截取时间 getSystemTranceDay(); 2、根据指定时间提供天、周、旬、月、季度、年的开始时间,结束时间(时间格式采java.util.Date),以Date数组的形式返回开始和结束时间。 3、给定字符串类型的startTime和endTime,工具类负责类型的转换(String转换成Date) 注意: 1、在sql中使用开始时间和最后时间的时候,为了保证统计数据的正确性, sql按给出的例子组织:t.logintime >= startTime and t.loginTime <= entTime 2、时间的字符串格式采用 yyyy-MM-dd 3、使用该类的时候,注意返回结果的正确性,虽然单元测试通过,还是担心有数据不正确的问题。 4、工具类以附件形式提供。 import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.zip.DataFormatException; import org.apache.commons.lang.time.DateUtils; import com.pengsy.commons.stringutil.StringUtil; /** * 该类主要服务于sql中基于时间的统计查询,在写sql的过程中建议不要使用to_char或者to_date等oracle函数 * 这样不利用索引(除非你对to_char进行了类似索引的操作 * ),比如:在表的logintime字段上建立了索引,但是在sql中使用to_char(logintime,'yyyy-MM-dd') * 作为检索条件的时候,数据库在logintime上建立的索引就没用了。在数据量很大的时候会影响检索的速度。 * 提供如下方法: * 1、获取当前时间(按天截取时间) * 2、根据指定时间提供天、周、旬、月、季度、年的开始时间,结束时间(时间格式采java.util.Date) * 3、给定字符串类型的startTime和endTime,工具类负责类型的转换(String转换成Date) * 注意: * 1、在sql中使用开始时间和最后时间的时候,为了保证统计数据的正确性, * sql按给出的例子组织:t.logintime >= startTime and t.loginTime <= entTime * 2、时间的字符串格式采用 yyyy-MM-dd * */ public final class DateUtil { private static SimpleDateFormat sDateFormat = new SimpleDateFormat( "yyyy-MM-dd"); public static final int FIRSTTEN = 1 ; public static final int MIDTEN = 2; public static final int LASTTEN = 3; public static final int FIRSTQUARTER = 1; public static final int SECONDQUARTER = 2; public static final int THIRDQUARTER = 3; public static final int FORTHQUARTER = 4; private static Pattern pattern = Pattern .compile("^[1-9]\\d{3}-[01]?\\d-[0|1|2|3]?\\d$"); // 2010-12-22 /** * 获取当前系统时间按天截取的时间 * @return */ public static Date getSystemTranceDay(){ return DateUtils.truncate(new Date(), Calendar.DATE); } /** * 功能:根据指定时间获取当前天的开始和结束时间,以date数组返回 * 逻辑: * 1、appointDate is null ,set default value sysdate * 2、get date[] * @param appointDate * @return */ public static Date[] getDateArrByDay(Date appointDate){ Date stime = null; Date etime = null; Date[] date = new Date[2]; //未完 if(appointDate == null){ appointDate = new Date(); } stime = DateUtils.truncate(appointDate,Calendar.DATE); etime = DateUtils.addSeconds(DateUtils.truncate(DateUtils.addDays(appointDate, 1), Calendar.DATE),-1); date[0] = stime; date[1] = etime; return date; } /** * 功能:根据指定时间获取当前星期的开始和结束时间,以date数组返回 * @param appointDate * @return */ public static Date[] getDateArrByWeek(Date appointDate){ Date stime = null; Date etime = null; Date[] date = new Date[2]; if(appointDate == null){ appointDate = new Date(); } Calendar calendar = Calendar.getInstance(); calendar.setTime(appointDate); int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK); System.out.println(dayOfWeek); calendar.add(Calendar.DAY_OF_MONTH, -dayOfWeek+2); stime = DateUtils.truncate(calendar.getTime(), Calendar.DATE); calendar.add(Calendar.DAY_OF_MONTH, 7); etime = DateUtils.addSeconds(DateUtils.truncate(calendar.getTime(), Calendar.DATE), -1); date[0] = stime; date[1] = etime; return date; } /** * 功能:根据指定的时间和上中下旬的其中一个,获取开始时间和结束时间 * @param appointDate * @param appointIndex * @return */ public static Date[] getDateArrByTenDays(Date appointDate,int appointIndex ){ Date stime = null; Date etime = null; Date[] date = new Date[2]; if(appointDate == null){ appointDate = new Date(); } //init date Calendar calendar = Calendar.getInstance(); calendar.setTime(appointDate); int dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH); int maxDayOfMonth = calendar.getMaximum(Calendar.DAY_OF_MONTH); Date tempDate = DateUtils.truncate(DateUtils.addDays(appointDate, -dayOfMonth + 1), Calendar.DATE); if(appointIndex == FIRSTTEN){ stime = tempDate; etime = DateUtils.addSeconds(DateUtils.addDays(stime, 10), -1); } if(appointIndex == MIDTEN){ stime = DateUtils.addDays(tempDate, 10); etime = DateUtils.addSeconds(DateUtils.addDays(stime, 10), -1); } if(appointIndex == LASTTEN){ stime = DateUtils.addDays(tempDate, 20); etime = DateUtils.addSeconds(DateUtils.addDays(tempDate, maxDayOfMonth), -1); } date[0] = stime; date[1] = etime; return date; } /** * 功能:根据指定时间获取相应月份的开始时间和结束时间 * @param appointDate * @return */ public static Date[] getDateArrByMonth(Date appointDate){ Date stime = null; Date etime = null; Date[] date = new Date[2]; if(appointDate == null){ appointDate = new Date(); } //init date Calendar calendar = Calendar.getInstance(); calendar.setTime(appointDate); int dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH); int maxDayOfMonth = calendar.getMaximum(Calendar.DAY_OF_MONTH); appointDate = DateUtils.truncate(appointDate, Calendar.DATE); stime = DateUtils.truncate(DateUtils.addDays(appointDate, -dayOfMonth+1), Calendar.DATE); etime = DateUtils.addSeconds(DateUtils.addDays(stime, maxDayOfMonth), -1); date[0] = stime; date[1] = etime; return date; } /** * 功能:根据指定时间所在的当前年,获取指定季度的开始时间和结束时间 * @param appointDate 指定当前年 * @param appointIndex * @return * @throws IllegalArgumentException */ public static Date[] getDateArrByQuarter(Date appointDate,int appointIndex) throws IllegalArgumentException{ Date stime = null; Date etime = null; Date[] date = new Date[2]; if(appointDate == null){ appointDate = new Date(); } int month = appointDate.getMonth(); Date tempDate = DateUtils.truncate(appointDate, Calendar.YEAR); if(appointIndex == FIRSTQUARTER){ stime = tempDate; }else if(appointIndex == SECONDQUARTER){ stime = DateUtils.addMonths(tempDate, 3); }else if(appointIndex == THIRDQUARTER ){ stime = DateUtils.addMonths(tempDate, 6); }else if(appointIndex == FORTHQUARTER){ stime = DateUtils.addMonths(tempDate, 9); } etime = DateUtils.addSeconds(DateUtils.addMonths(stime, 3), -1); date[0] = stime; date[1] = etime; return date; } /** * 功能:根据指定时间,获取年的开始时间和结束时间 * @param appointDate * @return */ public static Date[] getDateArrByYear(Date appointDate){ Date stime = null; Date etime = null; Date[] date = new Date[2]; if(appointDate == null){ appointDate = new Date(); } stime = DateUtils.truncate(appointDate, Calendar.YEAR); etime = DateUtils.addSeconds(DateUtils.addYears(stime, 1), -1); date[0] = stime; date[1] = etime; return date; } /** * 逻辑: 1、检查startTime,endTime的有效性(是否为空,数据格式), 异常处理: 1、两个参数都为空,抛出空指针异常 * 2、数据格式不对,直接抛出 3、一个参数为空,另一个参数格式正确的情况下,为空的参数采用系统时间,为了保证startTime <= * endTime,工具类会做适当的调整 2、转换 3、返回值是个Date[2]数组,date[0] 保存startTime值,date[1] * 保存startTime值,其中startTime <= endTime * * @param startTime * @param endTime * @return */ public static Date[] convertDateClass(String startTime, String endTime) throws NullPointerException, DataFormatException, ParseException { Date stime = null; Date etime = null; Date[] date = new Date[2]; if (StringUtil.isEmpty(startTime) && StringUtil.isEmpty(endTime)) { throw new NullPointerException("两个参数不能同时为空"); } if (StringUtil.isEmpty(startTime) && !StringUtil.isEmpty(endTime)) { // 先判断endTime格式是否正确 Matcher matcher = pattern.matcher(endTime); if (matcher.matches()) { stime = DateUtils.truncate(new Date(), Calendar.DATE); // 当天的开始时间,比如:当前时间为2010-12-27 11:31:30 这里stime的时间是2010-12-27 0:0:0 etime = DateUtils.truncate(sDateFormat.parse(endTime),Calendar.DATE); } else { throw new DataFormatException( "参数endTime的格式不正确!正确的格式 yyyy-MM-dd 比如:2010-12-12!"); } } if (!StringUtil.isEmpty(startTime) && StringUtil.isEmpty(endTime)) { Matcher matcher = pattern.matcher(startTime); if (matcher.matches()) { // 提供转换 etime = DateUtils.truncate(new Date(), Calendar.DATE); // 当天的开始时间,比如:当前时间为2010-12-27 11:31:30 这里stime的时间是2010-12-27 0:0:0 stime = DateUtils.truncate(sDateFormat.parse(startTime),Calendar.DATE); } else { throw new DataFormatException( "参数startTime的格式不正确!正确的格式 yyyy-MM-dd 比如:2010-12-12!"); } } if (!StringUtil.isEmpty(startTime) && !StringUtil.isEmpty(endTime)) { Matcher sMatcher = pattern.matcher(startTime); Matcher eMatcher = pattern.matcher(endTime); if (sMatcher.matches() && eMatcher.matches()) { stime = DateUtils.truncate(sDateFormat.parse(startTime), Calendar.DATE); etime = DateUtils.truncate(sDateFormat.parse(endTime), Calendar.DATE); } else { throw new DataFormatException( "请检查参数startTime、endTime的格式是否正确!正确的格式 yyyy-MM-dd 比如:2010-12-12!"); } } if (!stime.before(etime)) { Date temp = stime; stime = etime; etime = temp; temp = null; } date[0] = stime; date[1] = etime; return date; } } 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2010-12-28
30%~50%的地方可以代码复用
|
|
返回顶楼 | |
发表时间:2010-12-28
SimpleDateFormat这个类不是线程安全的,所以在多线程的时候上面的代码可能会出错!
建议用这个包:joda-time |
|
返回顶楼 | |
发表时间:2010-12-29
changyuxin 写道 SimpleDateFormat这个类不是线程安全的,所以在多线程的时候上面的代码可能会出错!
建议用这个包:joda-time 用 ThreadLocal 这样写: private static ThreadLocal<DateFormat> dateFormat = new ThreadLocal<DateFormat>() { @Override protected DateFormat initialValue() { return new SimpleDateFormat("yyyy-MM-dd"); } }; /** * 格式化日期为 yyyy-MM-dd 格式 * @param date * @return */ public static String formatDate(Date date) { return dateFormat.get().format(date); } 请大牛评论,这样做在WEB程序中的优劣 |
|
返回顶楼 | |
发表时间:2010-12-29
最后修改:2010-12-29
没全部看完。代码质量不高。
执行效率和安全性上都有问题。也多分配了一些多余对象容易引起性能问题。 而且使用了一些第三方类,导致使用你的代码还要引入额外的jar包。 |
|
返回顶楼 | |
发表时间:2010-12-29
changyuxin 写道 SimpleDateFormat这个类不是线程安全的,所以在多线程的时候上面的代码可能会出错!
建议用这个包:joda-time 对,webwork jar包里面的那个过滤器里用到了 SimpleDateFormat ,就出现了这个BUG。 struts2 好像修正了这个问题。 |
|
返回顶楼 | |
发表时间:2010-12-29
pengsuyun 写道 该类主要服务于sql中基于时间的统计查询,在写sql的过程中建议不要使用to_char或者to_date等oracle函数这样不利用索引(除非你对to_char进行了类似索引的操作),比如:在表的logintime字段上建立了索引,但是在sql中使用to_char(logintime,'yyyy-MM-dd')作为检索条件的时候,数据库在logintime上建立的索引就没用了。在数据量很大的时候会影响检索的速度。
该类提供如下方法: 1、获取系统按天截取时间 getSystemTranceDay(); 2、根据指定时间提供天、周、旬、月、季度、年的开始时间,结束时间(时间格式采java.util.Date),以Date数组的形式返回开始和结束时间。 3、给定字符串类型的startTime和endTime,工具类负责类型的转换(String转换成Date) 注意: 1、在sql中使用开始时间和最后时间的时候,为了保证统计数据的正确性, sql按给出的例子组织:t.logintime >= startTime and t.loginTime <= entTime 2、时间的字符串格式采用 yyyy-MM-dd 3、使用该类的时候,注意返回结果的正确性,虽然单元测试通过,还是担心有数据不正确的问题。 4、工具类以附件形式提供。 为什么不可以to_date? logintime > to_date(条件,'yyyy-MM-dd') |
|
返回顶楼 | |
发表时间:2010-12-29
运行结果:
dayOfWeek=2 appointDate=2011-01-03 10:35:43 本周开始 date[0]=2011-01-03 00:00:00 本周结束 date[1]=2011-01-09 23:59:59 dayOfWeek=3 appointDate=2011-01-04 10:35:43 本周开始 date[0]=2011-01-03 00:00:00 本周结束 date[1]=2011-01-09 23:59:59 dayOfWeek=4 appointDate=2011-01-05 10:35:43 本周开始 date[0]=2011-01-03 00:00:00 本周结束 date[1]=2011-01-09 23:59:59 dayOfWeek=5 appointDate=2011-01-06 10:35:43 本周开始 date[0]=2011-01-03 00:00:00 本周结束 date[1]=2011-01-09 23:59:59 dayOfWeek=6 appointDate=2011-01-07 10:35:43 本周开始 date[0]=2011-01-03 00:00:00 本周结束 date[1]=2011-01-09 23:59:59 dayOfWeek=7 appointDate=2011-01-08 10:35:43 本周开始 date[0]=2011-01-03 00:00:00 本周结束 date[1]=2011-01-09 23:59:59 dayOfWeek=1 appointDate=2011-01-09 10:35:43 本周开始 date[0]=2011-01-10 00:00:00 本周结束 date[1]=2011-01-16 23:59:59 这个是不是有问题? 凡是dayOfWeek=1 的话,都会有问题!!! |
|
返回顶楼 | |
发表时间:2010-12-29
能不能哪位大虾给个web应用上 完美点的时间处理类
|
|
返回顶楼 | |
发表时间:2010-12-29
mfkvfn 写道 没全部看完。代码质量不高。
执行效率和安全性上都有问题。也多分配了一些多余对象容易引起性能问题。 而且使用了一些第三方类,导致使用你的代码还要引入额外的jar包。 高手,大体浏览下就知道代码的优缺点。希望达到你的层次~ |
|
返回顶楼 | |