/**
* 时间计算工具类
* @author stronginfo
* @version 2013-11-03
*/
public class TimeUtils {
public static String toTimeString (long time) {
TimeUtils t = new TimeUtils(time);
int day = t.get(TimeUtils.DAY);
int hour = t.get(TimeUtils.HOUR);
int minute = t.get(TimeUtils.MINUTE);
int second = t.get(TimeUtils.SECOND);
StringBuilder sb = new StringBuilder();
if (day > 0 ){
sb.append(day).append("天" );
}
if (hour > 0 ){
sb.append(hour).append("时" );
}
if (minute > 0 ){
sb.append(minute).append("分" );
}
if (second > 0 ){
sb.append(second).append("秒" );
}
return sb.toString();
}
/**
* 时间字段常量,表示“秒”
*/
public final static int SECOND = 0 ;
/**
* 时间字段常量,表示“分”
*/
public final static int MINUTE = 1 ;
/**
* 时间字段常量,表示“时”
*/
public final static int HOUR = 2 ;
/**
* 时间字段常量,表示“天”
*/
public final static int DAY = 3 ;
/**
* 各常量允许的最大值
*/
private final int [] maxFields = { 59 , 59 , 23 , Integer.MAX_VALUE - 1 };
/**
* 各常量允许的最小值
*/
private final int [] minFields = { 0 , 0 , 0 , Integer.MIN_VALUE };
/**
* 默认的字符串格式时间分隔符
*/
private String timeSeparator = ":" ;
/**
* 时间数据容器
*/
private int [] fields = new int [4 ];
/**
* 无参构造,将各字段置为 0
*/
public TimeUtils () {
this (0 , 0 , 0 , 0 );
}
/**
* 使用时、分构造一个时间
* @param hour 小时
* @param minute 分钟
*/
public TimeUtils (int hour, int minute) {
this (0 , hour, minute, 0 );
}
/**
* 使用时、分、秒构造一个时间
* @param hour 小时
* @param minute 分钟
* @param second 秒
*/
public TimeUtils (int hour, int minute, int second) {
this (0 , hour, minute, second);
}
/**
* 使用一个字符串构造时间<br/>
* Time time = new Time("14:22:23");
* @param time 字符串格式的时间,默认采用“:”作为分隔符
*/
public TimeUtils (String time) {
this (time, null );
}
/**
* 使用时间毫秒构建时间
* @param time
*/
public TimeUtils (long time){
this (new Date(time));
}
/**
* 使用日期对象构造时间
* @param date
*/
public TimeUtils (Date date){
this (DateFormatUtils.formatUTC(date, "HH:mm:ss" ));
}
/**
* 使用天、时、分、秒构造时间,进行全字符的构造
* @param day 天
* @param hour 时
* @param minute 分
* @param second 秒
*/
public TimeUtils (int day, int hour, int minute, int second) {
initialize(day, hour, minute, second);
}
/**
* 使用一个字符串构造时间,指定分隔符<br/>
* Time time = new Time("14-22-23", "-");
* @param time 字符串格式的时间
*/
public TimeUtils (String time, String timeSeparator) {
if (timeSeparator != null ) {
setTimeSeparator(timeSeparator);
}
parseTime(time);
}
/**
* 设置时间字段的值
* @param field 时间字段常量
* @param value 时间字段的值
*/
public void set (int field, int value) {
if (value < minFields[field]) {
throw new IllegalArgumentException(value + ", time value must be positive." );
}
fields[field] = value % (maxFields[field] + 1 );
int carry = value / (maxFields[field] + 1 );
if (carry > 0 ) {
int upFieldValue = get(field + 1 );
set(field + 1 , upFieldValue + carry);
}
}
/**
* 获得时间字段的值
* @param field 时间字段常量
* @return 该时间字段的值
*/
public int get (int field) {
if (field < 0 || field > fields.length - 1 ) {
throw new IllegalArgumentException(field + ", field value is error." );
}
return fields[field];
}
/**
* 将时间进行“加”运算,即加上一个时间
* @param time 需要加的时间
* @return 运算后的时间
*/
public TimeUtils addTime (TimeUtils time) {
TimeUtils result = new TimeUtils();
int up = 0 ;
for (int i = 0 ; i < fields.length; i++) {
int sum = fields[i] + time.fields[i] + up;
up = sum / (maxFields[i] + 1 );
result.fields[i] = sum % (maxFields[i] + 1 );
}
return result;
}
/**
* 将时间进行“减”运算,即减去一个时间
* @param time 需要减的时间
* @return 运算后的时间
*/
public TimeUtils subtractTime (TimeUtils time) {
TimeUtils result = new TimeUtils();
int down = 0 ;
for (int i = 0 , k = fields.length - 1 ; i < k; i++) {
int difference = fields[i] + down;
if (difference >= time.fields[i]) {
difference -= time.fields[i];
down = 0 ;
} else {
difference += maxFields[i] + 1 - time.fields[i];
down = -1 ;
}
result.fields[i] = difference;
}
result.fields[DAY] = fields[DAY] - time.fields[DAY] + down;
return result;
}
/**
* 获得时间字段的分隔符
* @return
*/
public String getTimeSeparator () {
return timeSeparator;
}
/**
* 设置时间字段的分隔符(用于字符串格式的时间)
* @param timeSeparator 分隔符字符串
*/
public void setTimeSeparator (String timeSeparator) {
this .timeSeparator = timeSeparator;
}
private void initialize (int day, int hour, int minute, int second) {
set(DAY, day);
set(HOUR, hour);
set(MINUTE, minute);
set(SECOND, second);
}
private void parseTime (String time) {
if (time == null ) {
initialize(0 , 0 , 0 , 0 );
return ;
}
String t = time;
int field = DAY;
set(field--, 0 );
int p = -1 ;
while ((p = t.indexOf(timeSeparator)) > -1 ) {
parseTimeField(time, t.substring(0 , p), field--);
t = t.substring(p + timeSeparator.length());
}
parseTimeField(time, t, field--);
}
private void parseTimeField (String time, String t, int field) {
if (field < SECOND || t.length() < 1 ) {
parseTimeException(time);
}
char [] chs = t.toCharArray();
int n = 0 ;
for (int i = 0 ; i < chs.length; i++) {
if (chs[i] <= ' ' ) {
continue ;
}
if (chs[i] >= '0' && chs[i] <= '9' ) {
n = n * 10 + chs[i] - '0' ;
continue ;
}
parseTimeException(time);
}
set(field, n);
}
private void parseTimeException (String time) {
throw new IllegalArgumentException(time + ", time format error, HH"
+ this .timeSeparator + "mm" + this .timeSeparator + "ss" );
}
public String toString () {
StringBuilder sb = new StringBuilder(16 );
sb.append(fields[DAY]).append(',' ).append(' ' );
buildString(sb, HOUR).append(timeSeparator);
buildString(sb, MINUTE).append(timeSeparator);
buildString(sb, SECOND);
return sb.toString();
}
private StringBuilder buildString (StringBuilder sb, int field) {
if (fields[field] < 10 ) {
sb.append('0' );
}
return sb.append(fields[field]);
}
public int hashCode () {
final int PRIME = 31 ;
int result = 1 ;
result = PRIME * result + Arrays.hashCode(fields);
return result;
}
public boolean equals (Object obj) {
if (this == obj)
return true ;
if (obj == null )
return false ;
if (getClass() != obj.getClass())
return false ;
final TimeUtils other = (TimeUtils) obj;
if (!Arrays.equals(fields, other.fields)) {
return false ;
}
return true ;
}
}
public class WorkDayUtils {
public static void main (String[] args) {
try {
String strDateStart = "2013-08-01" ;
String strDateEnd = "2014-08-31" ;
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd" );
Date date_start = sdf.parse(strDateStart);
Date date_end = sdf.parse(strDateEnd);
WorkDayUtils app = new WorkDayUtils();
Calendar cal_start = Calendar.getInstance();
Calendar cal_end = Calendar.getInstance();
cal_start.setTime(date_start);
cal_end.setTime(date_end);
System.out.println("开始日:" + cal_start.get(Calendar.YEAR) + "-" + (cal_start.get(Calendar.MONTH) + 1 )
+ "-" + cal_start.get(Calendar.DAY_OF_MONTH) + " " + app.getChineseWeek(cal_start));
System.out.println("结束日:" + cal_end.get(Calendar.YEAR) + "-" + (cal_end.get(Calendar.MONTH) + 1 )
+ "-" + cal_end.get(Calendar.DAY_OF_MONTH) + " " + app.getChineseWeek(cal_end));
System.out.println("工作日:" + app.getWorkingDay(cal_start, cal_end));
System.out.println("休息日:" + app.getHolidays(cal_start, cal_end));
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 获取日期之间的天数
* @param d1
* @param d2
* @return
*/
public int getDaysBetween (java.util.Calendar d1, java.util.Calendar d2) {
if (d1.after(d2)) {
java.util.Calendar swap = d1;
d1 = d2;
d2 = swap;
}
int days = d2.get(java.util.Calendar.DAY_OF_YEAR)
- d1.get(java.util.Calendar.DAY_OF_YEAR);
int y2 = d2.get(java.util.Calendar.YEAR);
if (d1.get(java.util.Calendar.YEAR) != y2) {
d1 = (java.util.Calendar) d1.clone();
do {
days += d1.getActualMaximum(java.util.Calendar.DAY_OF_YEAR);
d1.add(java.util.Calendar.YEAR, 1 );
} while (d1.get(java.util.Calendar.YEAR) != y2);
}
return days;
}
/**
* 获取工作日
* @param d1
* @param d2
* @return
*/
public int getWorkingDay (java.util.Calendar d1, java.util.Calendar d2) {
int result = -1 ;
if (d1.after(d2)) {
java.util.Calendar swap = d1;
d1 = d2;
d2 = swap;
}
int charge_start_date = 0 ;
int charge_end_date = 0 ;
int stmp;
int etmp;
stmp = 7 - d1.get(Calendar.DAY_OF_WEEK);
etmp = 7 - d2.get(Calendar.DAY_OF_WEEK);
if (stmp != 0 && stmp != 6 ) {
charge_start_date = stmp - 1 ;
}
if (etmp != 0 && etmp != 6 ) {
charge_end_date = etmp - 1 ;
}
result = (getDaysBetween(this .getNextMonday(d1), this .getNextMonday(d2)) / 7 )
* 5 + charge_start_date - charge_end_date;
return result;
}
/**
* 获取中文日期
* @param date
* @return
*/
public String getChineseWeek (Calendar date) {
final String dayNames[] = { "星期日" , "星期一" , "星期二" , "星期三" , "星期四" , "星期五" , "星期六" };
int dayOfWeek = date.get(Calendar.DAY_OF_WEEK);
return dayNames[dayOfWeek - 1 ];
}
/**
* 获得日期的下一个星期一的日期
* @param date
* @return
*/
public Calendar getNextMonday (Calendar date) {
Calendar result = null ;
result = date;
do {
result = (Calendar) result.clone();
result.add(Calendar.DATE, 1 );
} while (result.get(Calendar.DAY_OF_WEEK) != 2 );
return result;
}
/**
* 获取休息日
* @param d1
* @param d2
* @return
*/
public int getHolidays (Calendar d1, Calendar d2) {
return this .getDaysBetween(d1, d2) - this .getWorkingDay(d1, d2);
}
}