Search code examples
vaadinvaadin-flowvaadin-gridvaadin21

Vaadin 21: change date format at LocalDateTimeRenderer in Grid on locale change


Situation and problem, short

The LocalDateTimeRenderer in Vaadin 21 shows a German date in a German browser, even if the Locale in the Vaadin session is changed to e.g. Locale.UK.

Situation and problem, long / detailled

In a Vaadin 21 Grid I've got a column for LocalDateTime. It's created like this for an entity type T:

private <T> Column<T> addLocalDateTimeColumn(Grid<T> grid, ValueProvider<T, LocalDateTime> getter) {
    LocalDateTimeRenderer<T> renderer = new LocalDateTimeRenderer(getter);
    Column<T> column = grid.addColumn(renderer).setAutoWidth(true);
    return column;
}

When I change the Locale in the session by calling UI.getCurrent().getSession().setLocale(locale); the whole application is translated into the new language, but not the content of the LocalDateTime-column.

Refreshing the whole Grid by calling grid.getDataProvider().refreshAll() (see here Vaadin 21: re-translate column with ItemLabelGenerator on locale change ) causes the ValueProvider in the code example above to get called again (a good indicator I think) but it does not format the LocalDateTime in the new selected language (this is the unexpected behavior).

So even if the locale in the session is English / Locale.UK, the LocalDateTime value is formatted in German like this: enter image description here

Using a localized DateTimeFormatter like this LocalDateTimeRenderer<T> renderer = new LocalDateTimeRenderer(getter, DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL, FormatStyle.SHORT)); also did not help: the style was different but the months were still translated German.

Workaround

Using a custom TextRenderer works (= column LocalDateTime content is translated with the session's locale):

private <T> Column<T> addLocalDateTimeColumn(Grid<T> grid, ValueProvider<T, LocalDateTime> getter) {
    Renderer<T> renderer = new TextRenderer<T>(new ItemLabelGenerator<T>() {

        @Override
        public String apply(T entity) {
            final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd. MMMM yyyy HH:mm", UI.getCurrent().getLocale());
            return getter.apply(entity).format(formatter);
        }
    });
    Column<T> column = grid.addColumn(renderer).setAutoWidth(true);
    return column;
}

Question

Is there some trick to get the same result with Vaadins LocalDateTimeRenderer?


Solution

  • No, it's not possible to change the locale of a column dynamically if you're using LocalDateRenderer or LocalDateTimeRenderer in Vaadin 21 or Vaadin 22. This is because of the following:

    1. The locale isn't explicitly saved in the Renderer. The Locale given to the renderer constructor (or the default) is used to produce a Formatter, which is saved into the field private DateTimeFormatter formatter;
    2. The formatter doesn't have any getters or setters.
    3. Even if the Locale of the VaadinSession changes, the formatter's locale stays the same as what it was created with
    4. You can't change the Renderer of a Column to something else after its creation.

    What you can do is remove the Column and re-add it with a new LocalDate(Time)Renderer with the requested Locale.

    I'd recommend creating a feature request about this in https://github.com/vaadin/flow-components/