2014-02-26 3 views
5

Ich möchte ein gespeichertes Datum anzeigen (Zeitzone ist UTC) mit der Zeitzone des Benutzers formatiert (kann für jeden Benutzer variieren und wird im Profil gespeichert).Der beste Weg zur benutzerspezifischen Datum/Zeitzone Konvertierung mit Spring MVC + Freemarker

Die Lösung, die ich kam, ist die folgende und Ich möchte wissen, ob dies der beste Weg ist, es zu tun, oder wenn es eine andere, vielleicht einfachere Lösung gibt.

Zeitzone auf UTC eingestellt mit:

-Duser.timezone=UTC 

Controller Freemarker-Template, HandlerInterceptor:

Controller:

@Controller 
@RequestMapping("/test") 
public class TestController { 

     @RequestMapping 
     public String dateTest(Model model){ 
       final Date date = new Date(); 
       model.addAttribute("formattedDate", new SimpleDateFormat("hh:mm:ss").format(date)); 
       model.addAttribute("date", date);    
       return "test"; 
     } 
} 

Freemarker-Vorlage:

<#setting time_zone="${currentTimeZone}"> 

UTC Time: ${formattedDate}<br/> 
Localized time for timezone <i>${currentTimeZone}</i>: ${date?time} 

HandlerInterceptor:

public class TimezoneHandlerInterceptor extends HandlerInterceptorAdapter{ 

     @Override 
     public void postHandle(HttpServletRequest request, 
         HttpServletResponse response, Object handler, 
         ModelAndView modelAndView) throws Exception { 

       //Only for testing, in production something like: 
       //final String currentUserTimezone = userService.getCurrentUser().getTimezoneId(); 
       final String currentUserTimezone = "Europe/Berlin"; 

       modelAndView.addObject("currentTimeZone", currentUserTimezone);    
     } 
} 

Ausgang:

UTC Time: 08:03:53 
Localized time for timezone Europe/Berlin: 09:03:53 

So ist es eine Standard oder sogar aus dem Kasten heraus Art und Weise das gleiche Ergebnis zu erzielen? Danke für Ihre Hilfe.

Antwort

2

Da Sie dasselbe Datum zweimal ausgeben, nur anders gerendert (andere Zeitzone), handelt es sich wahrscheinlich nur um ein Problem mit der Präsentation (MVC-Ansicht) und sollte daher nicht im Modell gelöst werden. Stattdessen könnten Sie etwas tun, wie dies die Vorlage:

<#import "/lib/utils.ftl" as u> 
... 
UTC Time: ${u.utcTime(date)}<br/> 
Localized time for timezone <i>${currentTimeZone}</i>: ${date?time} 

utcTime sollte innerhalb utils.ftl wie <#assign u = "com.something.freemarker.UtcTimeMethod"?new()> definiert werden, wobei com.something.freemarker.UtcTimeMethod ist eine TemplateMethodModelEx Umsetzung. Es gibt andere Wege, dies zu tun, wie u ist vielleicht eine gemeinsame Variable in der Freemarker-Konfiguration definiert usw. Der Punkt ist, dass Sie die UTC-Zeit drucken muss nicht das Modell beeinflussen.

Ab dem <#setting time_zone=currentTimeZone> Teil (beachten Sie, dass für ${...} es gibt keine Notwendigkeit), sicher hängt es von der Web Application Framework, aber die schöne Lösung wäre, wenn Sie die Zeitzone einstellen (wie auf der Grundlage der locale des Besuchers) vor Die Vorlage wird aufgerufen. Freemarker unterstützt, dass über Template.createProcessingEnvironment (siehe JavaDoc), aber vielleicht Spring MVC nicht.

Auch ein Date Objekt speichert immer die Datum-Zeit in UTC. Sie müssen die Zeitzone dafür nicht mit -D festlegen.

+0

Vielen Dank für Ihre Antwort. Sie haben Recht, es ist nur ein Rendering-Problem und sollte nicht im Modell/Controller durchgeführt werden - das war nur für Demonstrationszwecke. Ich denke diese 'Template.createProcessingEnvironment' ist, was ich eigentlich gesucht habe. Spring MVC legt das Gebietsschema fest, aber ich habe nicht herausgefunden, wie man die Zeitzone auf die gleiche Weise einstellt - aber mit diesem Hinweis kann ich den Quellcode durchsehen und selbst die endgültige Lösung finden. –

1

Nein, das sieht gut aus. Ich empfehle, nicht für die Formatierung von Zeichenfolge auf user.timezone verlassen, da schließlich jemand Ihre Webapp mit der falschen Zeitzone beginnen; stattdessen Sie

DateFormat formatter = new SimpleDateFormat("hh:mm:ss"); 
formatter.setTimeZone(TimeZone.getTimeZone("UTC")); 

Übrigens verwenden können, haben Sie CodeReview gesehen? Diese Frage ist für beide Seiten gleichermaßen geeignet, wenn man sie so formuliert, wie Sie es formuliert haben.

+0

Vielen Dank für Ihre Antwort. Es hat mich in die richtige Richtung geführt, denke ich.Auch der Hinweis auf CodeReview war sehr interessant. –

Verwandte Themen