首页 > 数据库 > 数据库开发技术 > java时间表达式工具类
今天分享一个java中时间表达式的工具类,话不多说,直接上代码。以下代码是可以直接运行的。
package com.eyesmoons.date;
public class Constants
{
public static final String NEWLINE = "\n";
public static final String COMMA = ",";
public static final String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
public static final String YYYYMMDDHHMMSSSSS = "yyyyMMddHHmmssSSS";
public static final String MONTH_BEGIN = "month_begin";
public static final String ADD_YEARS = "add_years";
public static final String ADD_MONTHS = "add_months";
public static final String MONTH_END = "month_end";
public static final String WEEK_BEGIN = "week_begin";
public static final String WEEK_END = "week_end";
public static final char SUBTRACT_CHAR = '-';
public static final char ADD_CHAR = '+';
public static final char MULTIPLY_CHAR = '*';
public static final char DIVISION_CHAR = '/';
public static final char LEFT_BRACE_CHAR = '(';
public static final char RIGHT_BRACE_CHAR = ')';
public static final String ADD_STRING = "+";
public static final String MULTIPLY_STRING = "*";
public static final String DIVISION_STRING = "/";
public static final String LEFT_BRACE_STRING = "(";
public static final char P = 'P';
public static final char N = 'N';
public static final String SUBTRACT_STRING = "-";
public static final String YEAR_END = "year_end";
public static final String QUARTER_BEGIN = "quarter_begin";
public static final String QUARTER_END = "quarter_end";
}
package com.eyesmoons.date;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils;
import java.lang.management.ManagementFactory;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;
/**
* 时间工具类
*/
@Slf4j
public class CustomDateUtil extends DateUtils
{
public static String YYYY_MM_DD = "yyyy-MM-dd";
public static String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";
public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
private static String[] parsePatterns = {
"yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM",
"yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM",
"yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"};
/**
* 获取当前Date型日期
*
* @return Date() 当前日期
*/
public static Date getNowDate()
{
return new Date();
}
/**
* 获取当前日期, 默认格式为yyyy-MM-dd
*/
public static String getDate()
{
return dateTimeNow(YYYY_MM_DD);
}
public static final String getTime()
{
return dateTimeNow(YYYY_MM_DD_HH_MM_SS);
}
public static final String dateTimeNow()
{
return dateTimeNow(YYYYMMDDHHMMSS);
}
public static final String dateTimeNow(final String format)
{
return parseDateToStr(format, new Date());
}
public static final String dateTime(final Date date)
{
return parseDateToStr(YYYY_MM_DD, date);
}
public static final String dateTime(final String format, final Date date)
{
return parseDateToStr(format, date);
}
public static final String parseDateToStr(final String format, final Date date)
{
return new SimpleDateFormat(format).format(date);
}
public static final Date dateTime(final String format, final String ts)
{
try
{
return new SimpleDateFormat(format).parse(ts);
}
catch (ParseException e)
{
throw new RuntimeException(e);
}
}
/**
* 日期路径 即年/月/日 如2018/08/08
*/
public static final String datePath()
{
Date now = new Date();
return DateFormatUtils.format(now, "yyyy/MM/dd");
}
/**
* 日期路径 即年/月/日 如20180808
*/
public static final String dateTime()
{
Date now = new Date();
return DateFormatUtils.format(now, "yyyyMMdd");
}
/**
* 日期型字符串转化为日期 格式
*/
public static Date parseDate(Object str)
{
if (str == null)
{
return null;
}
try
{
return parseDate(str.toString(), parsePatterns);
}
catch (ParseException e)
{
return null;
}
}
/**
* 获取服务器启动时间
*/
public static Date getServerStartDate()
{
long time = ManagementFactory.getRuntimeMXBean().getStartTime();
return new Date(time);
}
/**
* 计算两个时间差
*/
public static String getDatePoor(Date endDate, Date nowDate)
{
long nd = 1000 * 24 * 60 * 60;
long nh = 1000 * 60 * 60;
long nm = 1000 * 60;
// long ns = 1000;
// 获得两个时间的毫秒时间差异
long diff = endDate.getTime() - nowDate.getTime();
// 计算差多少天
long day = diff / nd;
// 计算差多少小时
long hour = diff % nd / nh;
// 计算差多少分钟
long min = diff % nd % nh / nm;
// 计算差多少秒//输出结果
// long sec = diff % nd % nh % nm / ns;
return day + "天" + hour + "小时" + min + "分钟";
}
/**
* 将数字转换成时分秒,
* 例如: 5261 -> 5秒261毫秒, 3602118 -> 1小时2秒118毫秒
* @param n 数字
*/
public static String convertNumber2DateString(Long n) {
String result = "";
long hh = n / 3600000;
long mm = (n - hh * 3600000) / 60000;
long ss = (n - hh * 3600000 - mm * 60000) / 1000;
long ms = (n - hh * 3600000 - mm * 60000 - ss * 1000);
if (n > 0) {
if (hh > 0) {
result += hh + "小时";
}
if (mm > 0) {
result += mm + "分";
}
if (ss > 0) {
result += ss + "秒";
}
if (ms > 0) {
result += ms + "毫秒";
}
} else {
result = "NaN";
}
return result;
}
/**
* 计算两个日期相差天数
*/
public static int getDatePoorDay(Date endDate, Date startDate)
{
// 获得两个时间的毫秒时间差异
long diff = endDate.getTime() - startDate.getTime();
// 计算差多少天
int day =(int) (diff / (1000 * 24 * 60 * 60));
return day;
}
/**
* date to local datetime
*
* @param date date
* @return local datetime
*/
private static LocalDateTime date2LocalDateTime(Date date) {
return LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
}
/**
* local datetime to date
*
* @param localDateTime local datetime
* @return date
*/
private static Date localDateTime2Date(LocalDateTime localDateTime) {
Instant instant = localDateTime.atZone(ZoneId.systemDefault()).toInstant();
return Date.from(instant);
}
/**
* get current date str
*
* @return date string
*/
public static String getCurrentTime() {
return getCurrentTime(Constants.YYYY_MM_DD_HH_MM_SS);
}
/**
* get the date string in the specified format of the current time
*
* @param format date format
* @return date string
*/
public static String getCurrentTime(String format) {
return LocalDateTime.now().format(DateTimeFormatter.ofPattern(format));
}
/**
* get the formatted date string
*
* @param date date
* @param format e.g. yyyy-MM-dd HH:mm:ss
* @return date string
*/
public static String format(Date date, String format) {
return format(date2LocalDateTime(date), format);
}
/**
* get the formatted date string
*
* @param localDateTime local data time
* @param format yyyy-MM-dd HH:mm:ss
* @return date string
*/
public static String format(LocalDateTime localDateTime, String format) {
return localDateTime.format(DateTimeFormatter.ofPattern(format));
}
/**
* convert time to yyyy-MM-dd HH:mm:ss format
*
* @param date date
* @return date string
*/
public static String dateToString(Date date) {
return format(date, Constants.YYYY_MM_DD_HH_MM_SS);
}
/**
* convert string to date and time
*
* @param date date
* @param format format
* @return date
*/
public static Date parse(String date, String format) {
try {
LocalDateTime ldt = LocalDateTime.parse(date, DateTimeFormatter.ofPattern(format));
return localDateTime2Date(ldt);
} catch (Exception e) {
log.error("error while parse date:" + date, e);
}
return null;
}
/**
* convert date str to yyyy-MM-dd HH:mm:ss format
*
* @param str date string
* @return yyyy-MM-dd HH:mm:ss format
*/
public static Date stringToDate(String str) {
return parse(str, Constants.YYYY_MM_DD_HH_MM_SS);
}
public static Date StringToDate(String dateString, String pattern) {
SimpleDateFormat dateFormat = new SimpleDateFormat(pattern); // 设置日期格式
try {
return dateFormat.parse(dateString);
} catch (ParseException e) {
e.printStackTrace();
}
return null;
}
/**
* get seconds between two dates
*
* @param d1 date1
* @param d2 date2
* @return differ seconds
*/
public static long differSec(Date d1, Date d2) {
if (d1 == null || d2 == null) {
return 0;
}
return (long) Math.ceil(differMs(d1, d2) / 1000.0);
}
/**
* get ms between two dates
*
* @param d1 date1
* @param d2 date2
* @return differ ms
*/
public static long differMs(Date d1, Date d2) {
return Math.abs(d1.getTime() - d2.getTime());
}
/**
* get hours between two dates
*
* @param d1 date1
* @param d2 date2
* @return differ hours
*/
public static long diffHours(Date d1, Date d2) {
return (long) Math.ceil(diffMin(d1, d2) / 60.0);
}
/**
* get minutes between two dates
*
* @param d1 date1
* @param d2 date2
* @return differ minutes
*/
public static long diffMin(Date d1, Date d2) {
return (long) Math.ceil(differSec(d1, d2) / 60.0);
}
/**
* get the date of the specified date in the days before and after
*
* @param date date
* @param day day
* @return the date of the specified date in the days before and after
*/
public static Date getSomeDay(Date date, int day) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.add(Calendar.DATE, day);
return calendar.getTime();
}
/**
* get the hour of day.
*
* @param date date
* @return hour of day
*/
public static int getHourIndex(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
return calendar.get(Calendar.HOUR_OF_DAY);
}
/**
* compare two dates
*
* @param future future date
* @param old old date
* @return true if future time greater than old time
*/
public static boolean compare(Date future, Date old) {
return future.getTime() > old.getTime();
}
/**
* convert schedule string to date
*
* @param schedule schedule
* @return convert schedule string to date
*/
public static Date getScheduleDate(String schedule) {
return stringToDate(schedule);
}
/**
* format time to readable
*
* @param ms ms
* @return format time
*/
public static String format2Readable(long ms) {
long days = MILLISECONDS.toDays(ms);
long hours = MILLISECONDS.toDurationHours(ms);
long minutes = MILLISECONDS.toDurationMinutes(ms);
long seconds = MILLISECONDS.toDurationSeconds(ms);
return String.format("%02d %02d:%02d:%02d", days, hours, minutes, seconds);
}
/**
* format time to duration
*
* @param d1 d1
* @param d2 d2
* @return format time
*/
public static String format2Duration(Date d1, Date d2) {
if (d1 == null || d2 == null) {
return null;
}
return format2Duration(differMs(d1, d2));
}
/**
* format time to duration
*
* @param ms ms
* @return format time
*/
public static String format2Duration(long ms) {
long days = MILLISECONDS.toDays(ms);
long hours = MILLISECONDS.toDurationHours(ms);
long minutes = MILLISECONDS.toDurationMinutes(ms);
long seconds = MILLISECONDS.toDurationSeconds(ms);
StringBuilder strBuilder = new StringBuilder();
strBuilder = days > 0 ? strBuilder.append(days).append("d").append(" ") : strBuilder;
strBuilder = hours > 0 ? strBuilder.append(hours).append("h").append(" ") : strBuilder;
strBuilder = minutes > 0 ? strBuilder.append(minutes).append("m").append(" ") : strBuilder;
strBuilder = seconds > 0 ? strBuilder.append(seconds).append("s") : strBuilder;
return strBuilder.toString();
}
/**
* get monday
* note: Set the first day of the week to Monday, the default is Sunday
*
* @param date date
* @return get monday
*/
public static Date getMonday(Date date) {
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.setFirstDayOfWeek(Calendar.MONDAY);
cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
return cal.getTime();
}
/**
* get sunday
* <p>
* note: Set the first day of the week to Monday, the default is Sunday
*
* @param date date
* @return get sunday
*/
public static Date getSunday(Date date) {
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.setFirstDayOfWeek(Calendar.MONDAY);
cal.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
return cal.getTime();
}
/**
* get first day of month
*
* @param date date
* @return first day of month
*/
public static Date getFirstDayOfMonth(Date date) {
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.set(Calendar.DAY_OF_MONTH, 1);
return cal.getTime();
}
/**
* get some hour of day
*
* @param date date
* @param offsetHour hours
* @return some hour of day
*/
public static Date getSomeHourOfDay(Date date, int offsetHour) {
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.set(Calendar.HOUR_OF_DAY, cal.get(Calendar.HOUR_OF_DAY) + offsetHour);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
return cal.getTime();
}
/**
* get last day of month
*
* @param date date
* @return get last day of month
*/
public static Date getLastDayOfMonth(Date date) {
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.add(Calendar.MONTH, 1);
cal.set(Calendar.DAY_OF_MONTH, 1);
cal.add(Calendar.DAY_OF_MONTH, -1);
return cal.getTime();
}
public static Date getLastDayOfYear(Date date) {
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.add(Calendar.YEAR, 1);
cal.set(Calendar.DAY_OF_YEAR, 1);
cal.add(Calendar.DAY_OF_YEAR, -1);
return cal.getTime();
}
/**
* return YYYY-MM-DD 00:00:00
*
* @param inputDay date
* @return start day
*/
public static Date getStartOfDay(Date inputDay) {
Calendar cal = Calendar.getInstance();
cal.setTime(inputDay);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
return cal.getTime();
}
/**
* return YYYY-MM-DD 23:59:59
*
* @param inputDay day
* @return end of day
*/
public static Date getEndOfDay(Date inputDay) {
Calendar cal = Calendar.getInstance();
cal.setTime(inputDay);
cal.set(Calendar.HOUR_OF_DAY, 23);
cal.set(Calendar.MINUTE, 59);
cal.set(Calendar.SECOND, 59);
cal.set(Calendar.MILLISECOND, 999);
return cal.getTime();
}
/**
* return YYYY-MM-DD 00:00:00
*
* @param inputDay day
* @return start of hour
*/
public static Date getStartOfHour(Date inputDay) {
Calendar cal = Calendar.getInstance();
cal.setTime(inputDay);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
return cal.getTime();
}
/**
* return YYYY-MM-DD 23:59:59
*
* @param inputDay day
* @return end of hour
*/
public static Date getEndOfHour(Date inputDay) {
Calendar cal = Calendar.getInstance();
cal.setTime(inputDay);
cal.set(Calendar.MINUTE, 59);
cal.set(Calendar.SECOND, 59);
cal.set(Calendar.MILLISECOND, 999);
return cal.getTime();
}
/**
* get current date
*
* @return current date
*/
public static Date getCurrentDate() {
return CustomDateUtil.parse(CustomDateUtil.getCurrentTime(),
Constants.YYYY_MM_DD_HH_MM_SS);
}
/**
* get date
*
* @param date date
* @param calendarField calendarField
* @param amount amount
* @return date
*/
public static Date add(final Date date, final int calendarField, final int amount) {
if (date == null) {
throw new IllegalArgumentException("The date must not be null");
}
final Calendar c = Calendar.getInstance();
c.setTime(date);
c.add(calendarField, amount);
return c.getTime();
}
/**
* get current time stamp : yyyyMMddHHmmssSSS
* @return date string
*/
public static String getCurrentTimeStamp() {
return getCurrentTime(Constants.YYYYMMDDHHMMSSSSS);
}
/**
*
* @param format
* @param timestamp 秒级
* @return
*/
public static Long getTimeStamp(final String format, Long timestamp) {
String dateString = dateTime(format, new Timestamp(timestamp*1000));
Date fullDate = dateTime(format, dateString);
String realDateString = dateTime(YYYY_MM_DD_HH_MM_SS, fullDate);
return Timestamp.valueOf(realDateString).getTime()/1000;
}
static final long C0 = 1L;
static final long C1 = C0 * 1000L;
static final long C2 = C1 * 1000L;
static final long C3 = C2 * 1000L;
static final long C4 = C3 * 60L;
static final long C5 = C4 * 60L;
static final long C6 = C5 * 24L;
public static Date getQuarterBegin(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH);
// 计算季度
int quarter = (int) Math.ceil((month + 1) / 3.0);
// 计算季度第一个月
int firstMonthOfQuarter = (quarter - 1) * 3;
// 设置日期为季度第一个月的第一天
calendar.set(year, firstMonthOfQuarter, 1);
return calendar.getTime();
}
public static Date getQuarterEnd(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH);
// 计算季度
int quarter = (int) Math.ceil((month + 1) / 3.0);
// 计算季度最后一个月
int lastMonthOfQuarter = quarter * 3 - 1;
// 设置日期为季度最后一个月的第一天
calendar.set(year, lastMonthOfQuarter, 1);
// 获取季度最后一个月的最大天数
int lastDay = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
// 将日期设置为季度最后一天
calendar.set(Calendar.DAY_OF_MONTH, lastDay);
return calendar.getTime();
}
/**
* Time unit representing one thousandth of a second
*/
public static class MILLISECONDS {
public static long toSeconds(long d) {
return d / (C3 / C2);
}
public static long toMinutes(long d) {
return d / (C4 / C2);
}
public static long toHours(long d) {
return d / (C5 / C2);
}
public static long toDays(long d) {
return d / (C6 / C2);
}
public static long toDurationSeconds(long d) {
return (d % (C4 / C2)) / (C3 / C2);
}
public static long toDurationMinutes(long d) {
return (d % (C5 / C2)) / (C4 / C2);
}
public static long toDurationHours(long d) {
return (d % (C6 / C2)) / (C5 / C2);
}
}
public static String timeStrBeforeNow(int hours) {
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:dd");
LocalDateTime timeNow = LocalDateTime.now();
LocalDateTime localDate = timeNow.minusHours(hours);
String startTime = localDate.format(fmt);
return startTime;
}
public static String dateStrBeforeNow(int months) {
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd");
LocalDate endDate = LocalDate.now();
LocalDate localDate = endDate.minusMonths(months).plusDays(1);
String startTime = localDate.format(fmt);
return startTime;
}
/**
* 时间戳转日期时间
* @param timeStamp
* @param format
* @return
*/
public static String stampToDateTime(Long timeStamp, String format) {
SimpleDateFormat dateFormat = new SimpleDateFormat(format);
Date date = new Date(timeStamp);
return dateFormat.format(date);
}
}
package com.eyesmoons.date;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.util.PropertyPlaceholderHelper;
import java.util.*;
import static com.eyesmoons.date.Constants.*;
/**
* time placeholder util
*/
@Slf4j
public class TimePlaceholderUtils {
/**
* Prefix of the position to be replaced
*/
public static final String PLACEHOLDER_PREFIX = "$[";
/**
* suffix of the position to be replaced
*/
public static final String PLACEHOLDER_SUFFIX = "]";
/**
* Replaces all placeholders of format {@code ${name}} with the value returned
* from the supplied {@link PropertyPlaceholderHelper.PlaceholderResolver}.
*
* @param value the value containing the placeholders to be replaced
* @param date custom date
* @param ignoreUnresolvablePlaceholders ignore unresolvable placeholders
* @return the supplied value with placeholders replaced inline
*/
public static String replacePlaceholders(String value, Date date, boolean ignoreUnresolvablePlaceholders) {
PropertyPlaceholderHelper strictHelper = getPropertyPlaceholderHelper(false);
PropertyPlaceholderHelper nonStrictHelper = getPropertyPlaceholderHelper(true);
PropertyPlaceholderHelper helper = (ignoreUnresolvablePlaceholders ? nonStrictHelper : strictHelper);
return helper.replacePlaceholders(value, new TimePlaceholderResolver(value, date));
}
/**
* Creates a new {@code PropertyPlaceholderHelper} that uses the supplied prefix and suffix.
*
* @param ignoreUnresolvablePlaceholders indicates whether unresolvable placeholders should
* be ignored ({@code true}) or cause an exception ({@code false})
*/
private static PropertyPlaceholderHelper getPropertyPlaceholderHelper(boolean ignoreUnresolvablePlaceholders) {
return new PropertyPlaceholderHelper(PLACEHOLDER_PREFIX, PLACEHOLDER_SUFFIX, null, ignoreUnresolvablePlaceholders);
}
/**
* calculate expression's value
*
* @param expression expression
* @return expression's value
*/
public static Integer calculate(String expression) {
expression = StringUtils.trim(expression);
expression = convert(expression);
List<String> result = string2List(expression);
result = convert2SuffixList(result);
return calculate(result);
}
/**
* Change the sign in the expression to P (positive) N (negative)
* @param expression 表达式
* @return eg. "-3+-6*(+8)-(-5) -> S3+S6*(P8)-(S5)"
*/
private static String convert(String expression) {
char[] arr = expression.toCharArray();
for (int i = 0; i < arr.length; i++) {
if (arr[i] == SUBTRACT_CHAR) {
if (i == 0) {
arr[i] = N;
} else {
char c = arr[i - 1];
if (c == ADD_CHAR || c == SUBTRACT_CHAR || c == MULTIPLY_CHAR || c == DIVISION_CHAR || c == LEFT_BRACE_CHAR) {
arr[i] = N;
}
}
} else if (arr[i] == ADD_CHAR) {
if (i == 0) {
arr[i] = P;
} else {
char c = arr[i - 1];
if (c == ADD_CHAR || c == SUBTRACT_CHAR || c == MULTIPLY_CHAR || c == DIVISION_CHAR || c == LEFT_BRACE_CHAR) {
arr[i] = P;
}
}
}
}
return new String(arr);
}
/**
* to suffix expression
*/
private static List<String> convert2SuffixList(List<String> srcList) {
List<String> result = new ArrayList<>();
Stack<String> stack = new Stack<>();
for (String s : srcList) {
if (Character.isDigit(s.charAt(0))) {
result.add(s);
} else {
switch (s.charAt(0)) {
case LEFT_BRACE_CHAR:
stack.push(s);
break;
case RIGHT_BRACE_CHAR:
while (!LEFT_BRACE_STRING.equals(stack.peek())) {
result.add(stack.pop());
}
stack.pop();
break;
default:
while (!stack.isEmpty() && compare(stack.peek(), s)) {
result.add(stack.pop());
}
stack.push(s);
break;
}
}
}
while (!stack.isEmpty()) {
result.add(stack.pop());
}
return result;
}
/**
* Calculate the suffix expression
*/
private static Integer calculate(List<String> result) {
Stack<Integer> stack = new Stack<>();
for (String s : result) {
if (Character.isDigit(s.charAt(0))) {
stack.push(Integer.parseInt(s));
} else {
Integer backInt = stack.pop();
Integer frontInt = 0;
char op = s.charAt(0);
if (!(op == P || op == N)) {
frontInt = stack.pop();
}
int res = 0;
switch (s.charAt(0)) {
case P:
case ADD_CHAR:
res = frontInt + backInt;
break;
case N:
case SUBTRACT_CHAR:
res = frontInt - backInt;
break;
case MULTIPLY_CHAR:
res = frontInt * backInt;
break;
case DIVISION_CHAR:
res = frontInt / backInt;
break;
default:
break;
}
stack.push(res);
}
}
return stack.pop();
}
/**
* string to list
*/
private static List<String> string2List(String expression) {
List<String> result = new ArrayList<>();
StringBuilder num = new StringBuilder();
for (int i = 0; i < expression.length(); i++) {
if (Character.isDigit(expression.charAt(i))) {
num.append(expression.charAt(i));
} else {
if (num.length() > 0) {
result.add(num.toString());
}
result.add(expression.charAt(i) + "");
num = new StringBuilder();
}
}
if (num.length() > 0) {
result.add(num.toString());
}
return result;
}
/**
* compare loginUser level
*/
private static boolean compare(String peek, String cur) {
boolean b = DIVISION_STRING.equals(cur) || MULTIPLY_STRING.equals(cur) || ADD_STRING.equals(cur) || SUBTRACT_STRING.equals(cur);
if (MULTIPLY_STRING.equals(peek) && b) {
return true;
} else if (DIVISION_STRING.equals(peek) && b) {
return true;
} else if (ADD_STRING.equals(peek) && (ADD_STRING.equals(cur) || SUBTRACT_STRING.equals(cur))) {
return true;
} else {
return SUBTRACT_STRING.equals(peek) && (ADD_STRING.equals(cur) || SUBTRACT_STRING.equals(cur));
}
}
/**
* Placeholder replacement resolver
*/
private static class TimePlaceholderResolver implements PropertyPlaceholderHelper.PlaceholderResolver {
private final String value;
private final Date date;
public TimePlaceholderResolver(String value, Date date) {
this.value = value;
this.date = date;
}
@Override
public String resolvePlaceholder(String placeholderName) {
try {
return calculateTime(placeholderName, date);
} catch (Exception ex) {
log.error("resolve placeholder '{}' in [ {} ]", placeholderName, value, ex);
return null;
}
}
}
/**
* return the formatted date according to the corresponding date format
*/
public static String getPlaceHolderTime(String expression, Date date) {
if (StringUtils.isBlank(expression)) {
return null;
}
if (null == date) {
return null;
}
return calculateTime(expression, date);
}
/**
* calculate time
*
* @param date date
* @return calculate time
*/
private static String calculateTime(String expression, Date date) {
String value;
try {
Map.Entry<Date, String> entry = calcTimeExpression(expression, date);
value = CustomDateUtil.format(entry.getKey(), entry.getValue());
} catch (Exception e) {
log.error(e.getMessage(), e);
throw e;
}
return value;
}
/**
* calculate time expression
* @param expression expression
* @param date date
* @return map with date, date format
*/
public static Map.Entry<Date, String> calcTimeExpression(String expression, Date date) {
Map.Entry<Date, String> resultEntry;
if (expression.startsWith(Constants.ADD_YEARS)) {
resultEntry = calcYears(expression, date);
} else if (expression.startsWith(Constants.ADD_MONTHS)) {
resultEntry = calcMonths(expression, date);
} else if (expression.startsWith(Constants.MONTH_BEGIN)) {
resultEntry = calcMonthBegin(expression, date);
} else if (expression.startsWith(Constants.MONTH_END)) {
resultEntry = calcMonthEnd(expression, date);
} else if (expression.startsWith(Constants.YEAR_END)) {
resultEntry = calcYearEnd(expression, date);
} else if (expression.startsWith(Constants.WEEK_BEGIN)) {
resultEntry = calcWeekStart(expression, date);
} else if (expression.startsWith(Constants.WEEK_END)) {
resultEntry = calcWeekEnd(expression, date);
} else if (expression.startsWith(Constants.QUARTER_BEGIN)) {
resultEntry = calcQuarterBegin(expression, date);
} else if (expression.startsWith(Constants.QUARTER_END)) {
resultEntry = calcQuarterEnd(expression, date);
} else {
resultEntry = calcMinutes(expression, date);
}
return resultEntry;
}
/**
* get first day of a quarter
* @param expression expression
* @param date date
*/
private static Map.Entry<Date, String> calcQuarterBegin(String expression, Date date) {
String addQuarterExpr = expression.substring(QUARTER_BEGIN.length() + 1, expression.length() - 1);
String[] params = addQuarterExpr.split(Constants.COMMA);
if (params.length == 2) {
String dateFormat = params[0];
String dayExpr = params[1];
Integer day = calculate(dayExpr);
Date targetDate = CustomDateUtil.getQuarterBegin(date);
targetDate = org.apache.commons.lang.time.DateUtils.addDays(targetDate, day);
return new AbstractMap.SimpleImmutableEntry<>(targetDate, dateFormat);
}
throw new RuntimeException("expression not valid");
}
/**
* get last day of a quarter
* @param expression expression
* @param date date
*/
private static Map.Entry<Date, String> calcQuarterEnd(String expression, Date date) {
String addQuarterExpr = expression.substring(QUARTER_END.length() + 1, expression.length() - 1);
String[] params = addQuarterExpr.split(Constants.COMMA);
if (params.length == 2) {
String dateFormat = params[0];
String dayExpr = params[1];
Integer day = calculate(dayExpr);
Date targetDate = CustomDateUtil.getQuarterEnd(date);
targetDate = org.apache.commons.lang.time.DateUtils.addDays(targetDate, day);
return new AbstractMap.SimpleImmutableEntry<>(targetDate, dateFormat);
}
throw new RuntimeException("expression not valid");
}
/**
* get first day of month
*
* @param expression expression
* @param date date
* @return first day of month
*/
public static Map.Entry<Date, String> calcMonthBegin(String expression, Date date) {
String addMonthExpr = expression.substring(Constants.MONTH_BEGIN.length() + 1, expression.length() - 1);
String[] params = addMonthExpr.split(Constants.COMMA);
if (params.length == 2) {
String dateFormat = params[0];
String dayExpr = params[1];
Integer day = calculate(dayExpr);
Date targetDate = CustomDateUtil.getFirstDayOfMonth(date);
targetDate = org.apache.commons.lang.time.DateUtils.addDays(targetDate, day);
return new AbstractMap.SimpleImmutableEntry<>(targetDate, dateFormat);
}
throw new RuntimeException("expression not valid");
}
/**
* get last day of month
*
* @param expression expression
* @param date date
* @return last day of month
*/
public static Map.Entry<Date, String> calcMonthEnd(String expression, Date date) {
String addMonthExpr = expression.substring(Constants.MONTH_END.length() + 1, expression.length() - 1);
String[] params = addMonthExpr.split(Constants.COMMA);
if (params.length == 2) {
String dateFormat = params[0];
String dayExpr = params[1];
// 处理上个月
if (dateFormat.endsWith("l1m")) {
dateFormat = dateFormat.replace("l1m", "dd");
String lastMonthOfDay = replacePlaceholders(String.format("$[add_months(%s, -1)]", dateFormat), date, true);
date = CustomDateUtil.StringToDate(lastMonthOfDay, dateFormat);
}
Date targetDate = CustomDateUtil.getLastDayOfMonth(date);
Integer day = calculate(dayExpr);
targetDate = org.apache.commons.lang.time.DateUtils.addDays(targetDate, day);
return new AbstractMap.SimpleImmutableEntry<>(targetDate, dateFormat);
}
throw new RuntimeException("expression not valid");
}
/**
* get first day of a year
* @param expression expression
* @param date date
*/
public static Map.Entry<Date, String> calcYearEnd(String expression, Date date) {
String addYearExpr = expression.substring(Constants.YEAR_END.length() + 1, expression.length() - 1);
String[] params = addYearExpr.split(Constants.COMMA);
if (params.length == 2) {
String dateFormat = params[0];
String dayExpr = params[1];
Date targetDate = CustomDateUtil.getLastDayOfYear(date);
Integer day = calculate(dayExpr);
targetDate = org.apache.commons.lang.time.DateUtils.addDays(targetDate, day);
return new AbstractMap.SimpleImmutableEntry<>(targetDate, dateFormat);
}
throw new RuntimeException("expression not valid");
}
/**
* get first day of week
*
* @param expression expression
* @param date date
* @return monday
*/
public static Map.Entry<Date, String> calcWeekStart(String expression, Date date) {
String addMonthExpr = expression.substring(Constants.WEEK_BEGIN.length() + 1, expression.length() - 1);
String[] params = addMonthExpr.split(Constants.COMMA);
if (params.length == 2) {
String dateFormat = params[0];
String dayExpr = params[1];
Integer day = calculate(dayExpr);
Date targetDate = CustomDateUtil.getMonday(date);
targetDate = org.apache.commons.lang.time.DateUtils.addDays(targetDate, day);
return new AbstractMap.SimpleImmutableEntry<>(targetDate, dateFormat);
}
throw new RuntimeException("expression not valid");
}
/**
* get last day of week
*
* @param expression expression
* @param date date
* @return last day of week
*/
public static Map.Entry<Date, String> calcWeekEnd(String expression, Date date) {
String addMonthExpr = expression.substring(Constants.WEEK_END.length() + 1, expression.length() - 1);
String[] params = addMonthExpr.split(Constants.COMMA);
if (params.length == 2) {
String dateFormat = params[0];
String dayExpr = params[1];
Integer day = calculate(dayExpr);
Date targetDate = CustomDateUtil.getSunday(date);
targetDate = org.apache.commons.lang.time.DateUtils.addDays(targetDate, day);
return new AbstractMap.SimpleImmutableEntry<>(targetDate, dateFormat);
}
throw new RuntimeException("Expression not valid");
}
/**
* calc years expression
*
* @param expression expression
* @param date date
* @return calc months
*/
public static Map.Entry<Date, String> calcYears(String expression, Date date) {
String addYearExpr = expression.substring(ADD_YEARS.length() + 1, expression.length() - 1);
String[] params = addYearExpr.split(Constants.COMMA);
if (params.length == 2) {
String dateFormat = params[0];
String yearExpr = params[1];
Integer addYear = calculate(yearExpr);
Date targetDate = org.apache.commons.lang.time.DateUtils.addYears(date, addYear);
return new AbstractMap.SimpleImmutableEntry<>(targetDate, dateFormat);
}
throw new RuntimeException("expression not valid");
}
/**
* calc months expression
*
* @param expression expression
* @param date date
* @return calc months
*/
public static Map.Entry<Date, String> calcMonths(String expression, Date date) {
String addMonthExpr = expression.substring(Constants.ADD_MONTHS.length() + 1, expression.length() - 1);
String[] params = addMonthExpr.split(Constants.COMMA);
if (params.length == 2) {
String dateFormat = params[0];
String monthExpr = params[1];
Integer addMonth = calculate(monthExpr);
Date targetDate = org.apache.commons.lang.time.DateUtils.addMonths(date, addMonth);
return new AbstractMap.SimpleImmutableEntry<>(targetDate, dateFormat);
}
throw new RuntimeException("expression not valid");
}
/**
* calculate time expression
*
* @param expression expression
* @param date date
* @return calculate time expression with date,format
*/
public static Map.Entry<Date, String> calcMinutes(String expression, Date date) {
if (expression.contains("+")) {
int index = expression.lastIndexOf('+');
if (Character.isDigit(expression.charAt(index + 1))) {
String addMinuteExpr = expression.substring(index + 1);
Date targetDate = org.apache.commons.lang.time.DateUtils
.addMinutes(date, calcMinutes(addMinuteExpr));
String dateFormat = expression.substring(0, index);
return new AbstractMap.SimpleImmutableEntry<>(targetDate, dateFormat);
}
} else if (expression.contains("-")) {
int index = expression.lastIndexOf('-');
if (Character.isDigit(expression.charAt(index + 1))) {
String addMinuteExpr = expression.substring(index + 1);
Date targetDate = DateUtils.addMinutes(date, -calcMinutes(addMinuteExpr));
String dateFormat = expression.substring(0, index);
return new AbstractMap.SimpleImmutableEntry<>(targetDate, dateFormat);
}
// yyyy-MM-dd/HH:mm:ss
return new AbstractMap.SimpleImmutableEntry<>(date, expression);
}
// $[HH mm ss]
return new AbstractMap.SimpleImmutableEntry<>(date, expression);
}
/**
* calculate need minutes
*
* @param minuteExpression minute expression
* @return calculate need minutes
*/
public static Integer calcMinutes(String minuteExpression) {
int index = minuteExpression.indexOf('/');
String calcExpression;
if (index == -1) {
calcExpression = String.format("60*24*(%s)", minuteExpression);
} else {
calcExpression = String.format("60*24*(%s)%s", minuteExpression.substring(0, index),
minuteExpression.substring(index));
}
return calculate(calcExpression);
}
}
package com.eyesmoons.date;
import java.util.Date;
public class TestExpression {
public static void main(String[] args) {
String result01 = TimePlaceholderUtils.replacePlaceholders("$[yyyyMMdd]", new Date(), true);
System.out.println("当天:" + result01);
String result02 = TimePlaceholderUtils.replacePlaceholders("$[yyyyMMdd-1]", new Date(), true);
System.out.println("昨天:" + result02);
String result03 = TimePlaceholderUtils.replacePlaceholders("$[yyyyMM01]", new Date(), true);
System.out.println("本月第一天:" + result03);
String result04 = TimePlaceholderUtils.replacePlaceholders("$[month_end(yyyyMMdd, 0)]", new Date(), true);
System.out.println("本月最后一天:" + result04);
String result05 = TimePlaceholderUtils.replacePlaceholders("$[add_months(yyyyMM01, -1)]", new Date(), true);
System.out.println("上月第一天:" + result05);
String result06 = TimePlaceholderUtils.replacePlaceholders("$[month_end(yyyyMMl1m, 0)]", new Date(), true);
System.out.println("上月最后一天:" + result06);
String result07 = TimePlaceholderUtils.replacePlaceholders("$[yyyy]", new Date(), true);
System.out.println("每年:" + result07);
String result08 = TimePlaceholderUtils.replacePlaceholders("$[add_years(yyyy, -1)]", new Date(), true);
System.out.println("上年:" + result08);
String result09 = TimePlaceholderUtils.replacePlaceholders("$[yyyyMM]", new Date(), true);
System.out.println("每月:" + result09);
String result10 = TimePlaceholderUtils.replacePlaceholders("$[add_months(yyyyMM, -1)]", new Date(), true);
System.out.println("上月:" + result10);
String result11 = TimePlaceholderUtils.replacePlaceholders("$[yyyy0101]", new Date(), true);
System.out.println("每年第一天:" + result11);
String result12 = TimePlaceholderUtils.replacePlaceholders("$[year_end(yyyyMMdd, 0)]", new Date(), true);
System.out.println("每年最后一天:" + result12);
String result13 = TimePlaceholderUtils.replacePlaceholders("$[quarter_begin(yyyyMMdd, 0)]", new Date(), true);
System.out.println("每季度第一天:" + result13);
String result14 = TimePlaceholderUtils.replacePlaceholders("$[quarter_end(yyyyMMdd, 0)]", new Date(), true);
System.out.println("每季度最后一天:" + result14);
String result15 = TimePlaceholderUtils.replacePlaceholders("$[week_begin(yyyyMMdd, -1)]", new Date(), true);
System.out.println("周日:" + result15);
String result16 = TimePlaceholderUtils.replacePlaceholders("$[week_begin(yyyyMMdd, 0)]", new Date(), true);
System.out.println("周一:" + result16);
String result17 = TimePlaceholderUtils.replacePlaceholders("$[week_begin(yyyyMMdd, 1)]", new Date(), true);
System.out.println("周二:" + result17);
String result18 = TimePlaceholderUtils.replacePlaceholders("$[week_begin(yyyyMMdd, 2)]", new Date(), true);
System.out.println("周三:" + result18);
String result19 = TimePlaceholderUtils.replacePlaceholders("$[week_begin(yyyyMMdd, 3)]", new Date(), true);
System.out.println("周四:" + result19);
String result20 = TimePlaceholderUtils.replacePlaceholders("$[week_begin(yyyyMMdd, 4)]", new Date(), true);
System.out.println("周五:" + result20);
String result21 = TimePlaceholderUtils.replacePlaceholders("$[week_begin(yyyyMMdd, 5)]", new Date(), true);
System.out.println("周六:" + result21);
}
}
结果如下:
当天:20230329
昨天:20230328
本月第一天:20230301
本月最后一天:20230331
上月第一天:20230201
上月最后一天:20230228
每年:2023
上年:2022
每月:202303
上月:202302
每年第一天:20230101
每年最后一天:20231231
每季度第一天:20230101
每季度最后一天:20230331
周日:20230326
周一:20230327
周二:20230328
周三:20230329
周四:20230330
周五:20230331
周六:20230401
需要自行导入以下依赖
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.26</version>
</dependency>
<!-- logback -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.4.6</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.4.6</version>
</dependency>
PropertyPlaceholderHelper
如果是springBoot项目,自带PropertyPlaceholderHelper依赖。
原文作者:毛毛小妖的笔记;如有侵权,请联系管理员删除。