将时间处理成几天前的格式
需求
将时间转化成几天前、几个月前等等!
我的项目环境
- 主要框架:SpringBoot
- 模版引擎:FreeMarker
解决步骤
- 首先引入FreeMarker的几个模版工具类
DirectiveHandler:
package com.lmy.eblog.templates.common;
import freemarker.core.Environment;
import freemarker.template.*;
import org.springframework.util.Assert;
import java.io.IOException;
import java.io.StringWriter;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* 引自mbog项目
*
* Created by langhsu on 2017/11/14.
*/
public class DirectiveHandler {
private Environment env;
private Map<String, TemplateModel> parameters;
private TemplateModel[] loopVars;
private TemplateDirectiveBody body;
private Environment.Namespace namespace;
/**
* 构建 DirectiveHandler
*
* @param env 系统环境变量,通常用它来输出相关内容,如Writer out = env.getOut()。
* @param parameters 自定义标签传过来的对象
* @param loopVars 循环替代变量
* @param body 用于处理自定义标签中的内容,如<@myDirective>将要被处理的内容</@myDirective>;当标签是<@myDirective />格式时,body=null。
*/
public DirectiveHandler(Environment env, Map<String, TemplateModel> parameters, TemplateModel[] loopVars,
TemplateDirectiveBody body) {
this.env = env;
this.loopVars = loopVars;
this.parameters = parameters;
this.body = body;
this.namespace = env.getCurrentNamespace();
}
public void render() throws IOException, TemplateException {
Assert.notNull(body, "must have template directive body");
body.render(env.getOut());
}
public void renderString(String text) throws Exception {
StringWriter writer = new StringWriter();
writer.append(text);
env.getOut().write(text);
}
public DirectiveHandler put(String key, Object value) throws TemplateModelException {
namespace.put(key, wrap(value));
return this;
}
public String getString(String name) throws TemplateModelException {
return TemplateModelUtils.converString(getModel(name));
}
public Integer getInteger(String name) throws TemplateModelException {
return TemplateModelUtils.converInteger(getModel(name));
}
public Short getShort(String name) throws TemplateModelException {
return TemplateModelUtils.converShort(getModel(name));
}
public Long getLong(String name) throws TemplateModelException {
return TemplateModelUtils.converLong(getModel(name));
}
public Double getDouble(String name) throws TemplateModelException {
return TemplateModelUtils.converDouble(getModel(name));
}
public String[] getStringArray(String name) throws TemplateModelException {
return TemplateModelUtils.converStringArray(getModel(name));
}
public Boolean getBoolean(String name) throws TemplateModelException {
return TemplateModelUtils.converBoolean(getModel(name));
}
public Date getDate(String name) throws TemplateModelException {
return TemplateModelUtils.converDate(getModel(name));
}
public String getString(String name, String defaultValue) throws Exception {
String result = getString(name);
return null == result ? defaultValue : result;
}
public Integer getInteger(String name, int defaultValue) throws Exception {
Integer result = getInteger(name);
return null == result ? defaultValue : result;
}
public Long getLong(String name, long defaultValue) throws Exception {
Long result = getLong(name);
return null == result ? defaultValue : result;
}
public String getContextPath() {
String ret = null;
try {
ret = TemplateModelUtils.converString(getEnvModel("base"));
} catch (TemplateModelException e) {
}
return ret;
}
/**
* 包装对象
* @param object
* @return
* @throws TemplateModelException
*/
public TemplateModel wrap(Object object) throws TemplateModelException {
return env.getObjectWrapper().wrap(object);
}
/**
* 获取局部变量
* @param name
* @return
* @throws TemplateModelException
*/
public TemplateModel getEnvModel(String name) throws TemplateModelException {
return env.getVariable(name);
}
public void write(String text) throws IOException {
env.getOut().write(text);
}
private TemplateModel getModel(String name) {
return parameters.get(name);
}
/**
* Created by langhsu on 2017/11/14.
*/
public abstract static class BaseMethod implements TemplateMethodModelEx {
public String getString(List<TemplateModel> arguments, int index) throws TemplateModelException {
return TemplateModelUtils.converString(getModel(arguments, index));
}
public Integer getInteger(List<TemplateModel> arguments, int index) throws TemplateModelException {
return TemplateModelUtils.converInteger(getModel(arguments, index));
}
public Long getLong(List<TemplateModel> arguments, int index) throws TemplateModelException {
return TemplateModelUtils.converLong(getModel(arguments, index));
}
public Date getDate(List<TemplateModel> arguments, int index) throws TemplateModelException {
return TemplateModelUtils.converDate(getModel(arguments, index));
}
public TemplateModel getModel(List<TemplateModel> arguments, int index) {
if (index < arguments.size()) {
return arguments.get(index);
}
return null;
}
}
}
TemplateDirective:
package com.lmy.eblog.templates.common;
import freemarker.core.Environment;
import freemarker.template.TemplateDirectiveBody;
import freemarker.template.TemplateDirectiveModel;
import freemarker.template.TemplateException;
import freemarker.template.TemplateModel;
import java.io.IOException;
import java.util.Map;
/**
* Created by langhsu on 2017/11/14.
*/
public abstract class TemplateDirective implements TemplateDirectiveModel {
protected static String RESULT = "result";
protected static String RESULTS = "results";
@Override
public void execute(Environment env, Map parameters,
TemplateModel[] loopVars, TemplateDirectiveBody body) throws TemplateException, IOException {
try {
execute(new DirectiveHandler(env, parameters, loopVars, body));
} catch (IOException e) {
throw e;
} catch (Exception e) {
throw new TemplateException(e, env);
}
}
abstract public String getName();
abstract public void execute(DirectiveHandler handler) throws Exception;
}
TemplateModelUtils:
package com.lmy.eblog.templates.common;
import freemarker.template.*;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import static org.apache.commons.lang3.StringUtils.*;
/**
* Freemarker 模型工具类
*
* Created by langhsu on 2017/11/14.
*/
public class TemplateModelUtils {
public static final DateFormat FULL_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
public static final int FULL_DATE_LENGTH = 19;
public static final DateFormat SHORT_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
public static final int SHORT_DATE_LENGTH = 10;
public static String converString(TemplateModel model) throws TemplateModelException {
if (null != model) {
if (model instanceof TemplateScalarModel) {
return ((TemplateScalarModel) model).getAsString();
} else if ((model instanceof TemplateNumberModel)) {
return ((TemplateNumberModel) model).getAsNumber().toString();
}
}
return null;
}
public static TemplateHashModel converMap(TemplateModel model) throws TemplateModelException {
if (null != model) {
if (model instanceof TemplateHashModelEx) {
return (TemplateHashModelEx) model;
} else if (model instanceof TemplateHashModel) {
return (TemplateHashModel) model;
}
}
return null;
}
public static Integer converInteger(TemplateModel model) throws TemplateModelException {
if (null != model) {
if (model instanceof TemplateNumberModel) {
return ((TemplateNumberModel) model).getAsNumber().intValue();
} else if (model instanceof TemplateScalarModel) {
String s = ((TemplateScalarModel) model).getAsString();
if (isNotBlank(s)) {
try {
return Integer.parseInt(s);
} catch (NumberFormatException e) {
}
}
}
}
return null;
}
public static Short converShort(TemplateModel model) throws TemplateModelException {
if (null != model) {
if (model instanceof TemplateNumberModel) {
return ((TemplateNumberModel) model).getAsNumber().shortValue();
} else if (model instanceof TemplateScalarModel) {
String s = ((TemplateScalarModel) model).getAsString();
if (isNotBlank(s)) {
try {
return Short.parseShort(s);
} catch (NumberFormatException e) {
}
}
}
}
return null;
}
public static Long converLong(TemplateModel model) throws TemplateModelException {
if (null != model) {
if (model instanceof TemplateNumberModel) {
return ((TemplateNumberModel) model).getAsNumber().longValue();
} else if (model instanceof TemplateScalarModel) {
String s = ((TemplateScalarModel) model).getAsString();
if (isNotBlank(s)) {
try {
return Long.parseLong(s);
} catch (NumberFormatException e) {
}
}
}
}
return null;
}
public static Double converDouble(TemplateModel model) throws TemplateModelException {
if (null != model) {
if (model instanceof TemplateNumberModel) {
return ((TemplateNumberModel) model).getAsNumber().doubleValue();
} else if (model instanceof TemplateScalarModel) {
String s = ((TemplateScalarModel) model).getAsString();
if (isNotBlank(s)) {
try {
return Double.parseDouble(s);
} catch (NumberFormatException ignored) {
}
}
}
}
return null;
}
public static String[] converStringArray(TemplateModel model) throws TemplateModelException {
if (model instanceof TemplateSequenceModel) {
TemplateSequenceModel smodel = (TemplateSequenceModel) model;
String[] values = new String[smodel.size()];
for (int i = 0; i < smodel.size(); i++) {
values[i] = converString(smodel.get(i));
}
return values;
} else {
String str = converString(model);
if (isNotBlank(str)) {
return split(str,',');
}
}
return null;
}
public static Boolean converBoolean(TemplateModel model) throws TemplateModelException {
if (null != model) {
if (model instanceof TemplateBooleanModel) {
return ((TemplateBooleanModel) model).getAsBoolean();
} else if (model instanceof TemplateNumberModel) {
return !(0 == ((TemplateNumberModel) model).getAsNumber().intValue());
} else if (model instanceof TemplateScalarModel) {
String temp = ((TemplateScalarModel) model).getAsString();
if (isNotBlank(temp)) {
return Boolean.valueOf(temp);
}
}
}
return null;
}
public static Date converDate(TemplateModel model) throws TemplateModelException {
if (null != model) {
if (model instanceof TemplateDateModel) {
return ((TemplateDateModel) model).getAsDate();
} else if (model instanceof TemplateScalarModel) {
String temp = trimToEmpty(((TemplateScalarModel) model).getAsString());
return parseDate(temp);
}
}
return null;
}
public static Date parseDate(String date) {
Date ret = null;
try {
if (FULL_DATE_LENGTH == date.length()) {
ret = FULL_DATE_FORMAT.parse(date);
} else if (SHORT_DATE_LENGTH == date.length()) {
ret = SHORT_DATE_FORMAT.parse(date);
}
} catch (ParseException e) {
}
return ret;
}
}
- 自定义一个时间处理类并实现
DirectiveHandler.BaseMethod
接口
这里的注释已经很详细了,我就不再解释,时间处理的核心逻辑也在这里,大家也可以适当的修改成自己想要的格式,有什么错误的话还请大佬们指出!
package com.lmy.eblog.templates;
/**
* @Project eblog
* @Package com.lmy.eblog.templates
* @author Administrator
* @date 2020/10/2 9:50
* @version V1.0
*/
import com.lmy.eblog.templates.common.DirectiveHandler;
import freemarker.core.Environment;
import freemarker.template.*;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* @author Lmy
* @ClassName TimeAgoMethod
* @Description 自定义时间处理标签
* @date 2020/10/2 9:50
**/
@Component
public class TimeAgoMethod extends DirectiveHandler.BaseMethod {
// 定义时间单位相应的毫秒数
private static final long ONE_MINUTE = 60000L;
private static final long ONE_HOUR = 3600000L;
private static final long ONE_DAY = 86400000L;
private static final long ONE_WEEK = 604800000L;
// 定义时间后缀
private static final String ONE_SECOND_AGO = "秒前";
private static final String ONE_MINUTE_AGO = "分钟前";
private static final String ONE_HOUR_AGO = "小时前";
private static final String ONE_DAY_AGO = "天前";
private static final String ONE_MONTH_AGO = "月前";
private static final String ONE_YEAR_AGO = "年前";
private static final String ONE_UNKNOWN = "未知";
@Override
public Object exec(List arguments) throws TemplateModelException {
// 获取时间参数
Date time = getDate(arguments, 0);
// 处理并返回
return format(time);
}
/**
* 格式化时间
* @param date
* @return
*/
public static String format(Date date) {
// 校验时间是否为空
if (null == date) {
return ONE_UNKNOWN;
}
// 将时间转换成毫秒数
long delta = new Date().getTime() - date.getTime();
// 判断是否小于一分钟
if (delta < 1L * ONE_MINUTE) {
// 将时间装换成秒
long seconds = toSeconds(delta);
// 返回秒数加后缀
return (seconds <= 0 ? 1 : seconds) + ONE_SECOND_AGO;
}
if (delta < 60L * ONE_MINUTE) {
long minutes = toMinutes(delta);
return (minutes <= 0 ? 1 : minutes) + ONE_MINUTE_AGO;
}
if (delta < 24L * ONE_HOUR) {
long hours = toHours(delta);
return (hours <= 0 ? 1 : hours) + ONE_HOUR_AGO;
}
if (delta < 48L * ONE_HOUR) {
return "昨天";
}
if (delta < 30L * ONE_DAY) {
long days = toDays(delta);
return (days <= 0 ? 1 : days) + ONE_DAY_AGO;
}
if (delta < 12L * 4L * ONE_WEEK) {
long months = toMonths(delta);
return (months <= 0 ? 1 : months) + ONE_MONTH_AGO;
} else {
long years = toYears(delta);
return (years <= 0 ? 1 : years) + ONE_YEAR_AGO;
}
}
/*----------------- 一系列时间处理方法 -------------------*/
private static long toSeconds(long date) {
return date / 1000L;
}
private static long toMinutes(long date) {
return toSeconds(date) / 60L;
}
private static long toHours(long date) {
return toMinutes(date) / 60L;
}
private static long toDays(long date) {
return toHours(date) / 24L;
}
private static long toMonths(long date) {
return toDays(date) / 30L;
}
private static long toYears(long date) {
return toMonths(date) / 365L;
}
}
- 编写配置类,将自定义的模版注入到FreeMarker环境中
package com.lmy.eblog.config;
import com.lmy.eblog.templates.TimeAgoMethod;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import javax.annotation.PostConstruct;
@Configuration
public class FreemarkerConfig {
@Autowired
private freemarker.template.Configuration configuration;
@PostConstruct
public void setUp() {
configuration.setSharedVariable("timeAgo", new TimeAgoMethod());
}
}
- 最后直接在页面中使用就好了