2019-12-24 14:58:51 +08:00

408 lines
12 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.amarsoft.app.base.util;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import com.amarsoft.app.base.businessobject.BusinessObject;
import com.amarsoft.app.base.businessobject.BusinessObjectCache;
import com.amarsoft.app.base.businessobject.BusinessObjectManager;
import com.amarsoft.app.base.exception.ALSException;
import com.amarsoft.are.jbo.BizObject;
import com.amarsoft.are.jbo.BizObjectManager;
import com.amarsoft.are.jbo.JBOFactory;
import com.amarsoft.are.lang.DateX;
import com.amarsoft.are.lang.StringX;
import com.amarsoft.are.util.Arith;
/**
* 日期处理
*
* @author 核算团队
*
* xjzhao@amarsoft.com 修改三个静态变量对于代码将010、020、030分别修改为D、M、Y便于大家理解数值代码不太直观
*
*/
public final class DateHelper{
//日期格式
public static final String AMR_NOMAL_TIME_FORMAT = "HH:mm:ss";
public static final String AMR_NOMAL_DATE_FORMAT = "yyyy/MM/dd";
public static final String AMR_NOMAL_DATETIME_FORMAT = "yyyy/MM/dd HH:mm:ss";
public static final String AMR_NOMAL_FULLDATETIME_FORMAT = "yyyy/MM/dd HH:mm:ss.SSS";
public static final String AMR_NOMAL_FULLTIME_FORMAT = "HH:mm:ss.SSS";
public static final String TERM_UNIT_DAY = "D";// 期限天
public static final String TERM_UNIT_MONTH = "M";// 期限月
public static final String TERM_UNIT_YEAR = "Y";// 期限年
private static BusinessObjectCache dateCache = new BusinessObjectCache(1000);
private static String businessDate;
/**
* 获取当前营业日期
* @return
* @throws Exception
*/
public static String getBusinessDate() throws Exception{
if(businessDate==null||"".equals(businessDate) || businessDate.length() != 10)
{
BizObjectManager bm = JBOFactory.getBizObjectManager("jbo.sys.SYSTEM_SETUP");
List<?> boList = bm.createQuery("O.BusinessDate is not null").getResultList(false);
if(boList == null||boList.isEmpty())
throw new Exception("系统日期未定义,请联系系统管理员设置!");
businessDate = ((BizObject)boList.get(0)).getAttribute("BusinessDate").toString();
if(StringX.isEmpty(businessDate))
throw new Exception("系统日期未定义,请联系系统管理员设置!");
}
return businessDate;
}
public static String getBusinessTime() throws Exception{
return getBusinessDate()+" "+DateX.format(new Date(),AMR_NOMAL_TIME_FORMAT);
}
/**
* 直接设置系统营业日期
* @param BusinessDate
* @throws Exception
*/
public static void setBusinessDate(String BusinessDate) throws Exception{
DateHelper.businessDate = BusinessDate;
}
public static String getRelativeDate(String date, String termUnit, String term) throws Exception {
return DateHelper.getRelativeDate(date, date, termUnit, Integer.parseInt(term));
}
public static String getRelativeDate(String date, String termUnit, int term) throws Exception {
return DateHelper.getRelativeDate(date, date, termUnit, term);
}
public static String getRelativeDate(String baseDate, boolean endOfMonth, String date, String termUnit, int term)
throws Exception {
if (term == 0) {
return date;
}
if (!TERM_UNIT_DAY.equals(termUnit) && !TERM_UNIT_MONTH.equals(termUnit) && !TERM_UNIT_YEAR.equals(termUnit)) {
throw new ALSException("ED1027",termUnit);
}
Calendar cal = Calendar.getInstance();
SimpleDateFormat formatter = new SimpleDateFormat(AMR_NOMAL_DATE_FORMAT);
cal.setTime(formatter.parse(date));
if (termUnit.equals(DateHelper.TERM_UNIT_DAY)) {
cal.add(Calendar.DATE, term);
} else if (termUnit.equals(DateHelper.TERM_UNIT_MONTH)) {
cal.add(Calendar.MONTH, term);
if (DateHelper.monthEnd(baseDate) && endOfMonth) {
String s = formatter.format(cal.getTime());
return DateHelper.getEndDateOfMonth(s);
}
} else if (termUnit.equals(DateHelper.TERM_UNIT_YEAR)) {
cal.add(Calendar.YEAR, term);
}
return formatter.format(cal.getTime());
}
public static String getRelativeDate(String baseDate, String date, String termUnit, int step) throws Exception {
return DateHelper.getRelativeDate(baseDate, false, date, termUnit, step);
}
/**
* 获得和给定日期BeginDate和EndDate相差的期数取整直接抛掉小数位
*/
public static double getTermPeriod(String BeginDate, String EndDate, String termUnit, int step) throws Exception {
if (step <= 0) {
throw new ALSException("ED1028");
}
if (!TERM_UNIT_DAY.equals(termUnit) && !TERM_UNIT_MONTH.equals(termUnit) && !TERM_UNIT_YEAR.equals(termUnit)) {
throw new ALSException("ED1027",termUnit);
}
double result=0d;
Calendar cal = Calendar.getInstance();
SimpleDateFormat formatter = new SimpleDateFormat(AMR_NOMAL_DATE_FORMAT);
cal.setTime(formatter.parse(BeginDate));
if (termUnit.equals(DateHelper.TERM_UNIT_DAY)) {
result = getDays(BeginDate, EndDate) / (step*1.0);
} else if (termUnit.equals(DateHelper.TERM_UNIT_MONTH)) {
result = getMonths(BeginDate, EndDate) / (step*1.0);
} else {
result = getYears(BeginDate, EndDate) / (step*1.0);
}
return Arith.round(result,5);
}
public static boolean monthEnd(String date) throws ParseException {
return date.equals(getEndDateOfMonth(date));
}
/**
* 得到月底
*/
public static String getEndDateOfMonth(String curDate) throws ParseException {
if (curDate == null || curDate.length() != 10) {
return null;
}
curDate = curDate.substring(0, 8) + "01";
Calendar cal = Calendar.getInstance();
SimpleDateFormat formatter = new SimpleDateFormat(AMR_NOMAL_DATE_FORMAT);
cal.setTime(formatter.parse(curDate));
int maxDays = cal.getActualMaximum(Calendar.DATE);// 得到该月的最大天数
cal.set(Calendar.DATE, maxDays);
return formatter.format(cal.getTime());
}
public static Date getDate(String curDate) throws ParseException {
Calendar cal = Calendar.getInstance();
SimpleDateFormat formatter = new SimpleDateFormat(AMR_NOMAL_DATE_FORMAT);
cal.setTime(formatter.parse(curDate));
return cal.getTime();
}
/**
* @param date yyyy/MM/dd
* @param type 1 返回数字 2 返回中文 3 返回英文 返回星期 1 星期一 、2 星期二 、3星期三、4 星期四、5 星期五、6
* 星期六、7 星期日
*/
public static String getWeekDay(String date, String format) throws ParseException {
String[] sWeekDates = { "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六" };
String[] sWeekDatesE = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };
Calendar cal = Calendar.getInstance();
SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM/dd");
cal.setTime(formatter.parse(date));
if (format.equals("2")) {
return sWeekDates[cal.get(Calendar.DAY_OF_WEEK) - 1];
} else if (format.equals("3")) {
return sWeekDatesE[cal.get(Calendar.DAY_OF_WEEK) - 1];
} else {
return String.valueOf(cal.get(Calendar.DAY_OF_WEEK) - 1);
}
}
/**
* @param beginDate
* @param endDate
* @return
* @throws ParseException 获取两个日期之间的天数
*/
public static int getDays(String sBeginDate, String sEndDate) {
Date startDate = java.sql.Date.valueOf(sBeginDate.replace('/', '-'));
Date endDate = java.sql.Date.valueOf(sEndDate.replace('/', '-'));
int iDays = (int) ((endDate.getTime() - startDate.getTime()) / 86400000L);
return iDays;
}
/**
* 获取两个日期之间的月数,采用小数表示。
* 用户可根据使用场景确定是向上、向下取整,取整时请注意正负数
*
* @param beginDate
* @param endDate
* @return
* @throws ParseException
* @author xjzhao@amarsoft.com
*/
public static double getMonths(String beginDate1, String endDate1) throws ParseException {
Date beginDate = getDate(beginDate1);
Date endDate = getDate(endDate1);
Calendar former = Calendar.getInstance();
Calendar latter = Calendar.getInstance();
former.setTime(beginDate);
latter.setTime(endDate);
int monthCounter = (latter.get(Calendar.YEAR) - former.get(Calendar.YEAR)) * 12 + latter.get(Calendar.MONTH) - former.get(Calendar.MONTH);
former.add(Calendar.MONTH, monthCounter);
int dayCounter = latter.get(Calendar.DAY_OF_MONTH)-former.get(Calendar.DAY_OF_MONTH);
int maxDays = latter.getActualMaximum(Calendar.DATE);
return monthCounter*1.0 + dayCounter*1.0/maxDays*1.0;
}
/**
* 获取两个日期之间的年数 add by xjzhao 2011/04/06
*
* @param beginDate
* @param endDate
* @return
* @throws ParseException
* @throws ParseException
*
*/
public static int getYears(String beginDate1, String endDate1) throws ParseException {
Date beginDate = getDate(beginDate1);
Date endDate = getDate(endDate1);
Calendar former = Calendar.getInstance();
Calendar latter = Calendar.getInstance();
former.clear();
latter.clear();
boolean positive = true;
if (beginDate.after(endDate)) {
former.setTime(endDate);
latter.setTime(beginDate);
positive = false;
} else {
former.setTime(beginDate);
latter.setTime(endDate);
}
int yearCounter = 0;
while (former.get(Calendar.YEAR) != latter.get(Calendar.YEAR)) {
former.add(Calendar.YEAR, 1);
yearCounter++;
}
if (positive)
return yearCounter;
else
return -yearCounter;
}
/**
* 判断是否为闰年
*
* @param year (int)
* @return
*/
public static boolean isLeapYear(int year) {
if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
return true;
} else {
return false;
}
}
/**
* 判断是否为闰年
*
* @param date Stringyyyy/mm/dd
* @return
*/
public static boolean isLeapYear(String date) throws Exception {
return isLeapYear(Integer.parseInt(date.split("/")[0]));
}
/**
* 按照是否周末判断工作日
* @param date
* @return
* @throws Exception
*/
private static boolean isWorkingDate(String date) throws Exception{
Calendar cal = Calendar.getInstance();
SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM/dd");
cal.setTime(formatter.parse(date));
int i = cal.get(Calendar.DAY_OF_WEEK);
if(i <= 5)//1到5为工作日
return true;
else return false;
}
/**
* 传入日期和 区域标志 返回是否工作日
* @param date 日期
* @param matchsql 匹配条件
* @return
* @throws Exception
*/
public static boolean isWorkingDate(String date,String matchSql) throws Exception{
List<BusinessObject> dates = (List<BusinessObject>)dateCache.getCacheObject(date);
if(dates == null || dates.isEmpty())
{
//获取当年的工作日信息
BusinessObjectManager bomanager = BusinessObjectManager.createBusinessObjectManager();
List<BusinessObject> datetemps = bomanager.loadBusinessObjects("jbo.sys.SYS_CALENDAR.CLASS_NAME", "CurDate like :CurYear", "CurYear",date.substring(0, 4)+"%");
synchronized(dateCache){
for(BusinessObject datetemp:datetemps)
{
dates = (List<BusinessObject>)dateCache.getCacheObject(datetemp.getString("CurDate"));
if(dates == null)
dates = new ArrayList<BusinessObject>();
dates.add(datetemp);
dateCache.setCache(datetemp.getString("CurDate"), dates);
}
}
dates = (List<BusinessObject>)dateCache.getCacheObject(date);
if(dates == null || dates.isEmpty())
return isWorkingDate(date);//如果系统未配置工作日信息,则按照正常周末为非工作日计算
else
{
for(BusinessObject d:dates)
{
if(d.matchSql(matchSql, null))
{
if("1".equals(d.getString("WorkFlag")))
return true;
else
return false;
}
}
}
}
else
{
for(BusinessObject d:dates)
{
if(d.matchSql(matchSql, null))
{
if("1".equals(d.getString("WorkFlag")))
return true;
else
return false;
}
}
}
return isWorkingDate(date);//如果没有定义节假日数据,默认按照周末决定节假日
}
public static void clear() throws Exception{
DateHelper.dateCache.clear();
}
/**
* 计算任务处理时间 分秒
* @param BeginTime
* @param EndTime
* @return
* @throws Exception
*/
public static String getDiffTime(String BeginTime, String EndTime) throws Exception {
SimpleDateFormat formatter = new SimpleDateFormat(AMR_NOMAL_DATETIME_FORMAT);
if(BeginTime == null || EndTime == null || "".equals(BeginTime) ||"".equals(EndTime)) return "";
Date begin = formatter.parse(BeginTime);
Date end = formatter.parse(EndTime);
long minutediff = (int) ((end.getTime()-begin.getTime())/(1000*60.00));
long seconddiff = (int) ((end.getTime()-begin.getTime())%(1000*60.00))/1000;
String Return = minutediff+""+seconddiff+"";
return Return;
}
public static void main(String[] args) throws Exception{
System.out.println(DateHelper.getMonths("2016/01/31", "2016/08/31"));
for(int i = 0; i < 10000;i++)
{
System.out.println(DateHelper.getRelativeDate("2016/01/29","D", i)+"--"+DateHelper.isWorkingDate(DateHelper.getRelativeDate("2016/01/29","D", i)));
}
}
}