基于jdk8的时间工具类
Java时间工具类,以后逐步扩展。
以下分别是对时间的操作,获取天、周、月、季度、年度起止时间,对日期的操作三个工具类。
1、对时间的构造和格式转化,比如毫秒值转化为X天X时X分X秒格式,各种时间的构造方法,时间加减方法等。
1 package com.gaspipe.app.common.utils; 2 3 import java.text.SimpleDateFormat; 4 import java.time.*; 5 import java.util.Arrays; 6 import java.util.Date; 7 8 import org.apache.commons.lang3.time.DateFormatUtils; 9 10 /** 11 * 时间计算工具类 12 * @author chenchi 13 * @version 2020-11-03 14 */ 15 public class TimeUtils { 16 17 public static final String PATTERN_yyMMddHHmmss = "yyMMddHHmmss"; 18 public static final String PATTERN_yyMMddHHmmssSSS = "yyMMddHHmmssSSS"; 19 public static final String PATTERN_STANDARD_TIME_MS = "yyyy-MM-dd HH:mm:ss.SSS"; 20 public static final String PATTERN_STANDARD_TIME = "yyyy-MM-dd HH:mm:ss"; 21 //秒置为0 22 public static final String PATTERN_STANDARD_TIME_NO_SECOND = "yyyy-MM-dd HH:mm"; 23 public static final String PATTERN_yyMMdd = "yyMMdd"; 24 public static final String PATTERN_STANDARD_TIME_SIGN = "yyyy-MM-dd#HH:mm:ss"; 25 public static final String PATTERN_STANDARD_TIME_SIGN_NO_BAR = "yyyyMMdd#HHmmss"; 26 public static final String PATTERN_MMdd = "MM-dd"; 27 public static final String PATTERN_yyyyMMdd = "yyyy-MM-dd"; 28 29 30 public static String toTimeString(long time) { 31 TimeUtils t = new TimeUtils(time); 32 int day = t.get(TimeUtils.DAY); 33 int hour = t.get(TimeUtils.HOUR); 34 int minute = t.get(TimeUtils.MINUTE); 35 int second = t.get(TimeUtils.SECOND); 36 StringBuilder sb = new StringBuilder(); 37 if (day > 0){ 38 sb.append(day).append("天"); 39 } 40 if (hour > 0){ 41 sb.append(hour).append("时"); 42 } 43 if (minute > 0){ 44 sb.append(minute).append("分"); 45 } 46 if (second > 0){ 47 sb.append(second).append("秒"); 48 } 49 return sb.toString(); 50 } 51 52 /** 53 * 时间字段常量,表示“秒” 54 */ 55 public final static int SECOND = 0; 56 57 /** 58 * 时间字段常量,表示“分” 59 */ 60 public final static int MINUTE = 1; 61 62 /** 63 * 时间字段常量,表示“时” 64 */ 65 public final static int HOUR = 2; 66 67 /** 68 * 时间字段常量,表示“天” 69 */ 70 public final static int DAY = 3; 71 72 /** 73 * 各常量允许的最大值 74 */ 75 private final int[] maxFields = { 59, 59, 23, Integer.MAX_VALUE - 1 }; 76 77 /** 78 * 各常量允许的最小值 79 */ 80 private final int[] minFields = { 0, 0, 0, Integer.MIN_VALUE }; 81 82 /** 83 * 默认的字符串格式时间分隔符 84 */ 85 private String timeSeparator = ":"; 86 87 /** 88 * 时间数据容器 89 */ 90 private int[] fields = new int[4]; 91 92 /** 93 * 无参构造,将各字段置为 0 94 */ 95 public TimeUtils() { 96 this(0, 0, 0, 0); 97 } 98 99 /** 100 * 使用时、分构造一个时间 101 * @param hour 小时 102 * @param minute 分钟 103 */ 104 public TimeUtils(int hour, int minute) { 105 this(0, hour, minute, 0); 106 } 107 108 /** 109 * 使用时、分、秒构造一个时间 110 * @param hour 小时 111 * @param minute 分钟 112 * @param second 秒 113 */ 114 public TimeUtils(int hour, int minute, int second) { 115 this(0, hour, minute, second); 116 } 117 118 /** 119 * 使用一个字符串构造时间<br/> 120 * Time time = new Time("14:22:23"); 121 * @param time 字符串格式的时间,默认采用“:”作为分隔符 122 */ 123 public TimeUtils(String time) { 124 this(time, null); 125 // System.out.println(time); 126 } 127 128 /** 129 * 使用时间毫秒构建时间 130 * @param time 131 */ 132 public TimeUtils(long time){ 133 this(new Date(time)); 134 } 135 136 /** 137 * 使用日期对象构造时间 138 * @param date 139 */ 140 public TimeUtils(Date date){ 141 this(DateFormatUtils.formatUTC(date, "HH:mm:ss")); 142 } 143 144 /** 145 * 使用天、时、分、秒构造时间,进行全字符的构造 146 * @param day 天 147 * @param hour 时 148 * @param minute 分 149 * @param second 秒 150 */ 151 public TimeUtils(int day, int hour, int minute, int second) { 152 initialize(day, hour, minute, second); 153 } 154 155 /** 156 * 使用一个字符串构造时间,指定分隔符<br/> 157 * Time time = new Time("14-22-23", "-"); 158 * @param time 字符串格式的时间 159 */ 160 public TimeUtils(String time, String timeSeparator) { 161 if(timeSeparator != null) { 162 setTimeSeparator(timeSeparator); 163 } 164 parseTime(time); 165 } 166 167 /** 168 * 设置时间字段的值 169 * @param field 时间字段常量 170 * @param value 时间字段的值 171 */ 172 public void set(int field, int value) { 173 if(value < minFields[field]) { 174 throw new IllegalArgumentException(value + ", time value must be positive."); 175 } 176 fields[field] = value % (maxFields[field] + 1); 177 // 进行进位计算 178 int carry = value / (maxFields[field] + 1); 179 if(carry > 0) { 180 int upFieldValue = get(field + 1); 181 set(field + 1, upFieldValue + carry); 182 } 183 } 184 185 /** 186 * 获得时间字段的值 187 * @param field 时间字段常量 188 * @return 该时间字段的值 189 */ 190 public int get(int field) { 191 if(field < 0 || field > fields.length - 1) { 192 throw new IllegalArgumentException(field + ", field value is error."); 193 } 194 return fields[field]; 195 } 196 197 /** 198 * 将时间进行“加”运算,即加上一个时间 199 * @param time 需要加的时间 200 * @return 运算后的时间 201 */ 202 public TimeUtils addTime(TimeUtils time) { 203 TimeUtils result = new TimeUtils(); 204 int up = 0; // 进位标志 205 for (int i = 0; i < fields.length; i++) { 206 int sum = fields[i] + time.fields[i] + up; 207 up = sum / (maxFields[i] + 1); 208 result.fields[i] = sum % (maxFields[i] + 1); 209 } 210 return result; 211 } 212 213 /** 214 * 将时间进行“减”运算,即减去一个时间 215 * @param time 需要减的时间 216 * @return 运算后的时间 217 */ 218 public TimeUtils subtractTime(TimeUtils time) { 219 TimeUtils result = new TimeUtils(); 220 int down = 0; // 退位标志 221 for (int i = 0, k = fields.length - 1; i < k; i++) { 222 int difference = fields[i] + down; 223 if (difference >= time.fields[i]) { 224 difference -= time.fields[i]; 225 down = 0; 226 } else { 227 difference += maxFields[i] + 1 - time.fields[i]; 228 down = -1; 229 } 230 result.fields[i] = difference; 231 } 232 result.fields[DAY] = fields[DAY] - time.fields[DAY] + down; 233 return result; 234 } 235 236 /** 237 * 获得时间字段的分隔符 238 * @return 239 */ 240 public String getTimeSeparator() { 241 return timeSeparator; 242 } 243 244 /** 245 * 设置时间字段的分隔符(用于字符串格式的时间) 246 * @param timeSeparator 分隔符字符串 247 */ 248 public void setTimeSeparator(String timeSeparator) { 249 this.timeSeparator = timeSeparator; 250 } 251 252 private void initialize(int day, int hour, int minute, int second) { 253 set(DAY, day); 254 set(HOUR, hour); 255 set(MINUTE, minute); 256 set(SECOND, second); 257 } 258 259 private void parseTime(String time) { 260 if(time == null) { 261 initialize(0, 0, 0, 0); 262 return; 263 } 264 String t = time; 265 int field = DAY; 266 set(field--, 0); 267 int p = -1; 268 while((p = t.indexOf(timeSeparator)) > -1) { 269 parseTimeField(time, t.substring(0, p), field--); 270 t = t.substring(p + timeSeparator.length()); 271 } 272 parseTimeField(time, t, field--); 273 } 274 275 private void parseTimeField(String time, String t, int field) { 276 if(field < SECOND || t.length() < 1) { 277 parseTimeException(time); 278 } 279 char[] chs = t.toCharArray(); 280 int n = 0; 281 for(int i = 0; i < chs.length; i++) { 282 if(chs[i] <= ' ') { 283 continue; 284 } 285 if(chs[i] >= '0' && chs[i] <= '9') { 286 n = n * 10 + chs[i] - '0'; 287 continue; 288 } 289 parseTimeException(time); 290 } 291 set(field, n); 292 } 293 294 private void parseTimeException(String time) { 295 throw new IllegalArgumentException(time + ", time format error, HH" 296 + this.timeSeparator + "mm" + this.timeSeparator + "ss"); 297 } 298 299 public String toString() { 300 StringBuilder sb = new StringBuilder(16); 301 sb.append(fields[DAY]).append(',').append(' '); 302 buildString(sb, HOUR).append(timeSeparator); 303 buildString(sb, MINUTE).append(timeSeparator); 304 buildString(sb, SECOND); 305 return sb.toString(); 306 } 307 308 private StringBuilder buildString(StringBuilder sb, int field) { 309 if(fields[field] < 10) { 310 sb.append('0'); 311 } 312 return sb.append(fields[field]); 313 } 314 315 public int hashCode() { 316 final int PRIME = 31; 317 int result = 1; 318 result = PRIME * result + Arrays.hashCode(fields); 319 return result; 320 } 321 322 public boolean equals(Object obj) { 323 if (this == obj) 324 return true; 325 if (obj == null) 326 return false; 327 if (getClass() != obj.getClass()) 328 return false; 329 final TimeUtils other = (TimeUtils) obj; 330 if (!Arrays.equals(fields, other.fields)) { 331 return false; 332 } 333 return true; 334 } 335 336 public static Date dateFormat(String str_date, String pattern) throws Exception{ 337 Date date = new SimpleDateFormat(pattern).parse(str_date); 338 return date; 339 } 340 341 public static String dateString(Date date, String pattern) { 342 SimpleDateFormat sdf=new SimpleDateFormat(pattern); 343 String dateStr = sdf.format(date); 344 return dateStr; 345 } 346 347 public static String dateStringTZ(Date date, String pattern) { 348 String dateStr = dateString(date, pattern); 349 return dateStr.replace("#", "T") + "Z"; 350 } 351 352 353 }
2、获取天、周、月、季度、年度起止时间的方法。
1 package com.gaspipe.app.common.utils; 2 3 import java.text.SimpleDateFormat; 4 import java.time.*; 5 import java.util.Arrays; 6 import java.util.Date; 7 8 import org.apache.commons.lang3.time.DateFormatUtils; 9 10 /** 11 * 时间计算工具类 12 * @author chenchi 13 * @version 2020-11-03 14 */ 15 public class TimeUtils { 16 17 public static final String MinTime = "T00:00:00"; 18 public static final String MaxTime = "T23:59:59.999999999"; 19 20 /** 21 * 功能描述: 22 * 当天的开始时间 23 * 24 * @param today 25 * @param isFirst true 表示开始时间,false表示结束时间 26 * @return java.time.LocalDateTime 27 * @author chenchi 28 * @date 2021/5/8 14:49 29 */ 30 public static LocalDateTime getStartOrEndDayOfDay(LocalDate today, Boolean isFirst){ 31 32 LocalDate resDate = LocalDate.now(); 33 if (today == null) { 34 today = resDate; 35 } 36 if(isFirst){ 37 return LocalDateTime.of(today, LocalTime.MIN); 38 }else{ 39 return LocalDateTime.of(today, LocalTime.MAX); 40 } 41 } 42 43 /** 44 * 功能描述: 45 * 本周的起止时间 46 * 47 * @param today 48 * @param isFirst true 表示开始时间,false表示结束时间 49 * @return java.time.LocalDateTime 50 * @author chenchi 51 * @date 2021/5/8 14:51 52 */ 53 public static LocalDateTime getStartOrEndDayOfWeek(LocalDate today, Boolean isFirst){ 54 55 String time = MinTime; 56 LocalDate resDate = LocalDate.now(); 57 if (today == null) { 58 today = resDate; 59 } 60 DayOfWeek week = today.getDayOfWeek(); 61 int value = week.getValue(); 62 if (isFirst) { 63 resDate = today.minusDays(value - 1); 64 } else { 65 resDate = today.plusDays(7 - value); 66 time = MaxTime; 67 } 68 LocalDateTime localDateTime = LocalDateTime.parse(resDate.toString() + time); 69 return localDateTime; 70 } 71 72 /** 73 * 功能描述: 74 * 本月的起止时间 75 * 76 * @param today 77 * @param isFirst true 表示开始时间,false表示结束时间 78 * @return java.time.LocalDateTime 79 * @author chenchi 80 * @date 2021/5/8 14:51 81 */ 82 public static LocalDateTime getStartOrEndDayOfMonth(LocalDate today, Boolean isFirst){ 83 String time = MinTime; 84 LocalDate resDate = LocalDate.now(); 85 if (today == null) { 86 today = resDate; 87 } 88 Month month = today.getMonth(); 89 int length = month.length(today.isLeapYear()); 90 if (isFirst) { 91 resDate = LocalDate.of(today.getYear(), month, 1); 92 } else { 93 resDate = LocalDate.of(today.getYear(), month, length); 94 time = MinTime; 95 } 96 LocalDateTime localDateTime = LocalDateTime.parse(resDate.toString() + time); 97 return localDateTime; 98 } 99 100 /** 101 * 功能描述: 102 * 本季度的起止时间 103 * 104 * @param today 105 * @param isFirst true 表示开始时间,false表示结束时间 106 * @return java.time.LocalDateTime 107 * @author chenchi 108 * @date 2021/5/8 14:51 109 */ 110 public static LocalDateTime getStartOrEndDayOfQuarter(LocalDate today, Boolean isFirst){ 111 String time = MinTime; 112 LocalDate resDate = LocalDate.now(); 113 if (today == null) { 114 today = resDate; 115 } 116 Month month = today.getMonth(); 117 Month firstMonthOfQuarter = month.firstMonthOfQuarter(); 118 Month endMonthOfQuarter = Month.of(firstMonthOfQuarter.getValue() + 2); 119 if (isFirst) { 120 resDate = LocalDate.of(today.getYear(), firstMonthOfQuarter, 1); 121 } else { 122 resDate = LocalDate.of(today.getYear(), endMonthOfQuarter, endMonthOfQuarter.length(today.isLeapYear())); 123 time = MaxTime; 124 } 125 LocalDateTime localDateTime = LocalDateTime.parse(resDate.toString() + time); 126 return localDateTime; 127 } 128 129 /** 130 * 功能描述: 131 * 本年度的起止时间 132 * 133 * @param today 134 * @param isFirst true 表示开始时间,false表示结束时间 135 * @return java.time.LocalDateTime 136 * @author chenchi 137 * @date 2021/5/8 14:51 138 */ 139 public static LocalDateTime getStartOrEndDayOfYear(LocalDate today, Boolean isFirst){ 140 String time = MinTime; 141 LocalDate resDate = LocalDate.now(); 142 if (today == null) { 143 today = resDate; 144 } 145 if (isFirst) { 146 resDate = LocalDate.of(today.getYear(), Month.JANUARY, 1); 147 } else { 148 resDate = LocalDate.of(today.getYear(), Month.DECEMBER, Month.DECEMBER.length(today.isLeapYear())); 149 time = MaxTime; 150 } 151 LocalDateTime localDateTime = LocalDateTime.parse(resDate.toString() + time); 152 return localDateTime; 153 } 154 155 156 157 }
3、对日期的操作。
1 package com.gaspipe.app.common.utils; 2 3 import org.apache.commons.lang.StringUtils; 4 import org.joda.time.DateTime; 5 import org.joda.time.LocalDate; 6 import org.joda.time.format.DateTimeFormat; 7 import org.joda.time.format.DateTimeFormatter; 8 9 import java.text.SimpleDateFormat; 10 import java.util.Calendar; 11 import java.util.Date; 12 13 /** 14 * 日期处理 15 * 16 * @author chenchi 17 * @date 2021/03/26 18 */ 19 public class DateUtils { 20 /** 时间格式(yyyy-MM-dd) */ 21 public final static String DATE_PATTERN = "yyyy-MM-dd"; 22 /** 时间格式(yyyy-MM-dd HH:mm:ss) */ 23 public final static String DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss"; 24 25 /** 26 * 日期格式化 日期格式为:yyyy-MM-dd 27 * @param date 日期 28 * @return 返回yyyy-MM-dd格式日期 29 */ 30 public static String format(Date date) { 31 return format(date, DATE_PATTERN); 32 } 33 34 /** 35 * 日期格式化 日期格式为:yyyy-MM-dd 36 * @param date 日期 37 * @param pattern 格式,如:DateUtils.DATE_TIME_PATTERN 38 * @return 返回yyyy-MM-dd格式日期 39 */ 40 public static String format(Date date, String pattern) { 41 if(date != null){ 42 SimpleDateFormat df = new SimpleDateFormat(pattern); 43 return df.format(date); 44 } 45 return null; 46 } 47 48 /** 49 * 字符串转换成日期 50 * @param strDate 日期字符串 51 * @param pattern 日期的格式,如:DateUtils.DATE_TIME_PATTERN 52 */ 53 public static Date stringToDate(String strDate, String pattern) { 54 if (StringUtils.isBlank(strDate)){ 55 return null; 56 } 57 58 DateTimeFormatter fmt = DateTimeFormat.forPattern(pattern); 59 return fmt.parseLocalDateTime(strDate).toDate(); 60 } 61 62 /** 63 * 根据周数,获取开始日期、结束日期 64 * @param week 周期 0本周,-1上周,-2上上周,1下周,2下下周 65 * @return 返回date[0]开始日期、date[1]结束日期 66 */ 67 public static Date[] getWeekStartAndEnd(int week) { 68 DateTime dateTime = new DateTime(); 69 LocalDate date = new LocalDate(dateTime.plusWeeks(week)); 70 71 date = date.dayOfWeek().withMinimumValue(); 72 Date beginDate = date.toDate(); 73 Date endDate = date.plusDays(6).toDate(); 74 return new Date[]{beginDate, endDate}; 75 } 76 77 /** 78 * 对日期的【秒】进行加/减 79 * 80 * @param date 日期 81 * @param seconds 秒数,负数为减 82 * @return 加/减几秒后的日期 83 */ 84 public static Date addDateSeconds(Date date, int seconds) { 85 DateTime dateTime = new DateTime(date); 86 return dateTime.plusSeconds(seconds).toDate(); 87 } 88 89 /** 90 * 对日期的【分钟】进行加/减 91 * 92 * @param date 日期 93 * @param minutes 分钟数,负数为减 94 * @return 加/减几分钟后的日期 95 */ 96 public static Date addDateMinutes(Date date, int minutes) { 97 DateTime dateTime = new DateTime(date); 98 return dateTime.plusMinutes(minutes).toDate(); 99 } 100 101 /** 102 * 对日期的【小时】进行加/减 103 * 104 * @param date 日期 105 * @param hours 小时数,负数为减 106 * @return 加/减几小时后的日期 107 */ 108 public static Date addDateHours(Date date, int hours) { 109 DateTime dateTime = new DateTime(date); 110 return dateTime.plusHours(hours).toDate(); 111 } 112 113 /** 114 * 对日期的【天】进行加/减 115 * 116 * @param date 日期 117 * @param days 天数,负数为减 118 * @return 加/减几天后的日期 119 */ 120 public static Date addDateDays(Date date, int days) { 121 DateTime dateTime = new DateTime(date); 122 return dateTime.plusDays(days).toDate(); 123 } 124 125 /** 126 * 对日期的【周】进行加/减 127 * 128 * @param date 日期 129 * @param weeks 周数,负数为减 130 * @return 加/减几周后的日期 131 */ 132 public static Date addDateWeeks(Date date, int weeks) { 133 DateTime dateTime = new DateTime(date); 134 return dateTime.plusWeeks(weeks).toDate(); 135 } 136 137 /** 138 * 对日期的【月】进行加/减 139 * 140 * @param date 日期 141 * @param months 月数,负数为减 142 * @return 加/减几月后的日期 143 */ 144 public static Date addDateMonths(Date date, int months) { 145 DateTime dateTime = new DateTime(date); 146 return dateTime.plusMonths(months).toDate(); 147 } 148 149 /** 150 * 对日期的【年】进行加/减 151 * 152 * @param date 日期 153 * @param years 年数,负数为减 154 * @return 加/减几年后的日期 155 */ 156 public static Date addDateYears(Date date, int years) { 157 DateTime dateTime = new DateTime(date); 158 return dateTime.plusYears(years).toDate(); 159 } 160 161 /** 162 * 计算当前时间至凌晨12点之间的时间间隔(秒) 163 * 164 * @return 165 */ 166 public static long getSecondsFormNowToEnd() { 167 Calendar calendar = Calendar.getInstance(); 168 calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH) + 1, 169 0, 0, 0); 170 long result = (calendar.getTimeInMillis() - new Date().getTime()) / 1000; 171 return result; 172 } 173 /** 174 * 获取过去的分钟 175 * @param date 176 * @return 177 */ 178 public static long pastMinutes(Date date) { 179 long t = new Date().getTime()-date.getTime(); 180 return t/(60*1000); 181 } 182 183 }