Java 时区国际化处理

前言

项目主打海外业务,不可避免碰到时区的问题。目前的解决方案是,服务器、数据库统一设置为0时区,前端提交日期格式的字符串参数,请求头传递时区的参数(如:东八区【+8】,西一区【-1】),后台根据偏移量将日期字符串转换成0时区的Date

切面

package com.woodare.tsp.service.core.security.aspect;import cn.hutool.core.date.DatePattern;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.woodare.tsp.common.core.constant.HeaderConst;
import com.woodare.tsp.common.core.utils.LocalDateTimeUtils;
import com.woodare.tsp.common.core.utils.ServletUtils;
import com.woodare.tsp.common.core.web.domain.BaseEntity;
import com.woodare.tsp.common.core.web.domain.BaseRequest;
import com.woodare.tsp.consumer.api.service.ConsumerService;
import com.woodare.tsp.service.core.security.annotation.CtlHeaderTrackAnno;
import com.woodare.tsp.system.api.service.TenantService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.Map;
import java.util.Objects;
import java.util.TimeZone;/*** @author lufeng*/
@Slf4j
@Aspect
@Component
@RequiredArgsConstructor
public class TimeZoneAspect {private final ThreadLocal<CtlHeaderTrackAnno> localTrackAnno = new ThreadLocal<>();private static final String BEGIN_TIME = "beginTime";private static final String END_TIME = "endTime";private static final String START_DATE = "startDate";private static final String END_DATE = "endDate";@Pointcut("@annotation(com.woodare.tsp.service.core.security.annotation.TimeZone)")public void timeZone() {// For Aspect}@Before("timeZone()")public void runBefore(JoinPoint joinPoint) {Object arg = joinPoint.getArgs()[0];if(arg instanceof BaseRequest){BaseRequest baseRequest = (BaseRequest) arg;this.formatDateByTimeZone(baseRequest.getParams());}else if(arg instanceof BaseEntity){BaseEntity baseEntity = (BaseEntity) arg;this.formatDateByTimeZone(baseEntity.getParams());}}private void formatDateByTimeZone(Map<String, Object> params) {String timezone = Objects.requireNonNull(ServletUtils.getRequest()).getHeader(HeaderConst.X_TIME_ZONE);// 根据时区转换日期字符串if(params.containsKey(BEGIN_TIME) && params.containsKey(END_TIME) && StrUtil.isNotBlank(timezone)){Object begin = params.get(BEGIN_TIME);Object end = params.get(END_TIME);Date startDate = LocalDateTimeUtils.parseV2(begin.toString(), DatePattern.NORM_DATETIME_PATTERN, Integer.parseInt(timezone));Date endDate = LocalDateTimeUtils.parseV2(end.toString(), DatePattern.NORM_DATETIME_PATTERN, Integer.parseInt(timezone));params.put(START_DATE, startDate);params.put(END_DATE, endDate);}}}

工具类

package com.woodare.tsp.common.core.utils;import cn.hutool.core.date.DatePattern;
import cn.hutool.core.util.StrUtil;import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.util.Date;
import java.util.TimeZone;public class LocalDateTimeUtils {public static String formatObject(Object date, String pattern, Integer offset) {if (date == null || StrUtil.isBlank(pattern) || offset == null) {return "";}if (date instanceof Date) {return format((Date) date, pattern, offset);}else if (date instanceof String) {return formatString((String) date, pattern, offset);}return "";}public static String format(Date date, String pattern, Integer offset) {if (date == null || StrUtil.isBlank(pattern) || offset == null) {return "";}TimeZone tz = TimeZone.getTimeZone("UTC");if (offset != null) {tz.setRawOffset(-offset * 60 * 1000);}SimpleDateFormat sdf = new SimpleDateFormat(pattern);sdf.setTimeZone(tz);String d = sdf.format(date);return d;}public static String showAsTimezone(Integer offset) {if (offset == null) {return "";}String returnVal = "UTC";if (offset > 0) {returnVal += "-";}else {returnVal += "+";}offset = Math.abs(offset);int hour = offset / 60;if (hour >= 10) {returnVal += hour + ":";}else {returnVal += "0" + hour + ":";}int minute = offset % 60;if (minute >= 10) {returnVal += minute;}else {returnVal += "0" + minute;}return returnVal;}public static String formatString(String dateString, String pattern, Integer offset) {if (StrUtil.isBlank(dateString) || StrUtil.isBlank(pattern) || offset == null) {return "";}SimpleDateFormat sdfWithTimeZone = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");sdfWithTimeZone.setTimeZone(TimeZone.getTimeZone("UTC"));Date date = null;try {date = sdfWithTimeZone.parse(dateString);} catch (ParseException e) {return "";}TimeZone tz = TimeZone.getTimeZone("UTC");if (offset != null) {tz.setRawOffset(-offset * 60 * 1000);}SimpleDateFormat sdf = new SimpleDateFormat(pattern);sdf.setTimeZone(tz);String d = sdf.format(date);return d;}public static Date parse(String dateStr, String pattern, Integer offset) {if (StrUtil.isBlank(dateStr) || StrUtil.isBlank(pattern) || offset == null) {return null;}TimeZone tz = TimeZone.getTimeZone("UTC");tz.setRawOffset(-offset * 60 * 1000);SimpleDateFormat sdf = new SimpleDateFormat(pattern);sdf.setTimeZone(tz);Date d = null;try {d = sdf.parse(dateStr);} catch (ParseException e) {e.printStackTrace();}return d;}public static Date parseV2(String dateStr, String pattern, Integer offset) {if (StrUtil.isBlank(dateStr) || StrUtil.isBlank(pattern) || offset == null) {return null;}SimpleDateFormat sdf = new SimpleDateFormat(pattern);ZoneId zoneId = ZoneId.ofOffset("GMT", ZoneOffset.ofHours(offset));TimeZone timeZone = TimeZone.getTimeZone(zoneId);sdf.setTimeZone(timeZone);Date d = null;try {d = sdf.parse(dateStr);} catch (ParseException e) {e.printStackTrace();}return d;}public static void main(String[] args) {// 前台请求日期Object begin = "2023-02-02 00:00:00";Object end = "2023-02-02 23:59:59";// 操作系统置为0时区TimeZone.setDefault(TimeZone.getTimeZone("GMT+0:00"));// 模拟东8区请求【比0时区快了8小时】(0时区转东八区,+8;东八区转0时区,-8)Date startDate = LocalDateTimeUtils.parseV2(begin.toString(), DatePattern.NORM_DATETIME_PATTERN, Integer.parseInt("8"));Date endDate = LocalDateTimeUtils.parseV2(end.toString(), DatePattern.NORM_DATETIME_PATTERN, Integer.parseInt("8"));
//		Wed Feb 01 16:00:00 GMT+00:00 2023
//		Thu Feb 02 15:59:59 GMT+00:00 2023System.out.println(startDate);System.out.println(endDate);// 模拟西1区请求【比0时区慢了1小时】(0时区转西一区,-1;西一区转0时区,+1)Date startDate1 = LocalDateTimeUtils.parseV2(begin.toString(), DatePattern.NORM_DATETIME_PATTERN, Integer.parseInt("-1"));Date endDate1 = LocalDateTimeUtils.parseV2(end.toString(), DatePattern.NORM_DATETIME_PATTERN, Integer.parseInt("-1"));
//		Thu Feb 02 01:00:00 GMT+00:00 2023
//		Fri Feb 03 00:59:59 GMT+00:00 2023System.out.println(startDate1);System.out.println(endDate1);}}


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部