/* * Copyright (c) 2015. Bearchoke */ package com.bearchoke.platform.server.common.web.interceptor; import org.apache.commons.lang3.StringUtils; import org.springframework.format.datetime.standard.DateTimeContext; import org.springframework.format.datetime.standard.DateTimeContextHolder; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.time.ZoneId; import java.time.ZoneOffset; /** * Spring MVC Interceptor that sets the request's {@link org.joda.time.DateTimeZone} from a cookie. * Allows the client's timezone to be figured out by JavaScript, then submitted and applied on the server as the default timezone for the request. * Useful when you need to render dates in client local time. * @author Keith Donald */ @Component public class DateTimeZoneHandlerInterceptor implements HandlerInterceptor { public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { DateTimeContext context = new DateTimeContext(); context.setTimeZone(getZoneId(request)); DateTimeContextHolder.setDateTimeContext(context); return true; } public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { if (modelAndView != null) { modelAndView.addObject("zoneId", DateTimeContextHolder.getDateTimeContext()); } } public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { DateTimeContextHolder.resetDateTimeContext(); } // interna helpers private ZoneId getZoneId(HttpServletRequest request) { String offset = request.getHeader("TimeZone-Offset"); ZoneOffset zoneOffset = getZoneOffset(offset); if (zoneOffset != null) { try { return zoneOffset.normalized(); } catch (IllegalArgumentException e) { return ZoneId.systemDefault(); } } else { return ZoneId.systemDefault(); } } private ZoneOffset getZoneOffset(String offsetS) { // we expect the front-end to be sending a number over such as 420 (Indo time) if (StringUtils.isNotBlank(offsetS)) { // we get minutes from the header so we need to add 60 to get to seconds int offset = Integer.valueOf(offsetS) * 60; return ZoneOffset.ofTotalSeconds(offset); } else { return ZoneOffset.UTC; } } }