简体   繁体   中英

Play 2.0 date format

I'm trying to format a date in a Scala template in Play. So far I've written this:

<p>@DateFormat.getInstance().format(deadline)</p>

Where deadline is the date I'm outputting to the web page. However, this uses the JVM's locale and not the one selected by the user.

My app currently supports two locales, Norwegian (no) and English (en). This works well for messages, but not for Date s. So I tried adding a GlobalSettings to intercept each request as shown below, but apparently it's never invoked:

import java.lang.reflect.Method;
import java.util.Locale;
import org.springframework.context.i18n.LocaleContext;
import org.springframework.context.i18n.LocaleContextHolder;
import play.GlobalSettings;
import play.i18n.Lang;
import play.mvc.Action;
import play.mvc.Http.Request; 

public class Global extends GlobalSettings {

    @SuppressWarnings("rawtypes")
    @Override
    public Action onRequest(final Request request, final Method actionMethod) {

        LocaleContextHolder.setLocaleContext(new LocaleContext() {
            public Locale getLocale() {
                Lang preferred = Lang.preferred(request.acceptLanguages());
                return preferred.toLocale();
            }
        });
        return super.onRequest(request, actionMethod);
    }
}

Does someone have a solution to this problem? Is it a known bug in Play? I'm using version 2.0.4.

Thanks!

I tried estmatic's solution, but it didn't discriminate properly between country variants of the same language, for example if my browser's preferred languages were "en_AU" and "en_US" in that order, then it would only use the "en" part, which resulted in a US-style date (with the month first) rather than an Aussie-style one (with the date first, as is right and proper).

My solution was to create a helper class as follows:

public class Formatter extends Controller {

    private static final int DATE_STYLE = LONG;
    private static final int TIME_STYLE = SHORT;

    /**
     * Formats the given Date as a date and time, using the locale of the current
     * request's first accepted language.
     *
     * @param date the date to format (required)
     * @return the formatted date
     * @see play.mvc.Http.Request#acceptLanguages()
     */
    public static String formatDateTime(final Date date) {
        final Locale locale = getPreferredLocale();
        return DateFormat.getDateTimeInstance(
                DATE_STYLE, TIME_STYLE, locale).format(date);
    }

    private static Locale getPreferredLocale() {
        final List<Lang> acceptedLanguages = request().acceptLanguages();
        final Lang preferredLanguage = acceptedLanguages.isEmpty() ?
                Lang.preferred(acceptedLanguages) : acceptedLanguages.get(0);
        return new Locale(preferredLanguage.language(), preferredLanguage.country());
    }
}

Then in my Scala templates, all I had to do was use (for example):

@import my.package.Formatter
...
Date = @Formatter.formatDateTime(someDate)

This seems cleaner to me than having a lot of Locale construction logic in the templates.

Well you need to provide the locale when you get your DateFormat instance; otherwise it'll just use the system default locale instead of what Play is getting from the browser.

Something like this seems to work:

@DateFormat.getDateInstance(DateFormat.LONG, (implicitly[Lang]).toLocale).format(deadline)

That implicitly[Lang] bit is basically calling Lang.preferred(request.acceptLanguages() just like you were doing in your onRequest() method.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM