GWT: использовать DateTimeFormat для клиента и SimpleDateFormat на сервере

У меня есть функция, которая должна работать одинаково как на клиенте, так и на сервере и форматирует даты.

if (GWT.isClient())
{
  // Use DateTimeFormat
} else {
  // Use SimpleDateFormat
}

GWT жалуется: нет исходного кода для типа SimpleDateFormat. Ошибка не является фатальной (по крайней мере, в режиме dev), но раздражает и не может ее подавить. Нашел аналогичный вопрос на http://groups.google.com/group/google-web-toolkit/browse_thread/thread/981247fca161c287. Там они предлагают:

Вы можете предоставить фиктивную реализацию суперпользователя SimpleDateTimeFormat, чтобы он компилировался.

Я пробовал. Теперь Eclipse жалуется:

java.text Объявленный пакет "java.text" не соответствует ожидаемому пакету "foo.jre.java.text" SimpleDateFormat.java

Ответы

Ответ 1

Вы должны сказать Eclipse, чтобы не компилировать ваш файл с супер-source'd Java. Если вы используете Maven, это просто вопрос перехода на src/main/resources; в противном случае исключить ваш пакет "jre" из пути сборки Eclipse.

... что, как говорится, я бы предпочел бы суперпоследовать класс, используя SimpleDateFormat/DateTimeFormat, и/или переместил его в вспомогательный класс, который вы бы использовали для супер-источника.

Ответ 2

Вы можете использовать com.google.gwt.i18n.shared.DateTimeFormat на сервере и клиенте:

Вызовите защищенный конструктор, чтобы избежать GWT.create

String pattern = "yyyyMMdd"; /*your pattern here*/ 
DefaultDateTimeFormatInfo info = new DefaultDateTimeFormatInfo();
DateTimeFormat dtf = new DateTimeFormat(pattern, info) {};  // <= trick here

Пример

Date d = dtf.parse("20120301");
CalendarUtil.addDaysToDate(d, -1);
String s = dtf.format(d);
// s now contains "20120229"

Трюк выполняется путем расширения DateTimeFormat, поэтому мы можем использовать защищенный конструктор с DateTimeFormatInfo, где мы используем new DefaultDateTimeFormatInfo(), чтобы избежать вызова GWT.create

Ответ 3

Это решение немного отличается, но по тому же пути, что и один, представленный на форуме, но он разрешает проблему GWT 2.7 @stepancheg, и я упомянул.

import java.util.Date;

import com.google.gwt.core.client.GWT;
import com.google.gwt.thirdparty.guava.common.annotations.GwtCompatible;
import com.google.gwt.thirdparty.guava.common.annotations.GwtIncompatible;

public abstract class DateTimeFormat {
    static DateTimeFormat getFormat(String pattern)
    {
        if (GWT.isClient())
            return new DateTimeFormatClient(pattern);
        else
            return new DateTimeFormatServer(pattern);
    }

    public abstract String format(Date date);

    public abstract Date parse(String dateString);

    @GwtCompatible
    private static class DateTimeFormatClient extends DateTimeFormat
    {
        protected String pattern;

        public DateTimeFormatClient(String pattern)
        {
            this.pattern = pattern;
        }


        public String format(Date date)
        {
            return com.google.gwt.i18n.client.DateTimeFormat.getFormat(pattern).format(date);
        }

        public Date parse(String stringDate){
            return com.google.gwt.i18n.client.DateTimeFormat.getFormat(pattern).parseStrict(stringDate);
        }
    }

    private static class DateTimeFormatServer extends DateTimeFormatClient
    {

        public DateTimeFormatServer(String pattern)
        {
            super(pattern);
        }


        @GwtIncompatible("Server format")
        public String format(Date date)
        {
            return (new java.text.SimpleDateFormat(pattern)).format(date);
        }  

        @GwtIncompatible("Server parse")
        public Date parse(String dateString){
            try{
                return (new java.text.SimpleDateFormat(pattern)).parse(dateString);
            }catch(Exception ex){
            throw new IllegalArgumentException("Cannot convert to date: "+ dateString);
            }
        }

    }
}

Надеюсь, что это поможет другим.

Ответ 4

import com.google.gwt.i18n.shared.DateTimeFormat;
DateTimeFormat fm = DateTimeFormat.getFormat("MM/dd");
String st = fm.format(date);

Ответ 5

import java.util.Date;

import com.google.gwt.core.shared.GWT;
import com.google.gwt.thirdparty.guava.common.annotations.GwtCompatible;
import com.google.gwt.thirdparty.guava.common.annotations.GwtIncompatible;

public abstract class DateTimeFormat
{
    static DateTimeFormat getFormat(String pattern)
    {
        if (GWT.isClient())
            return DateTimeFormatClient.getFormat(pattern);
        else
            return DateTimeFormatServer.getFormat(pattern);
    }

    public abstract String format(Date date);

    @GwtCompatible
    private static class DateTimeFormatClient extends DateTimeFormat
    {
        private com.google.gwt.i18n.client.DateTimeFormat dateTimeFormat;

        protected DateTimeFormatClient(String pattern)
        {
            this.dateTimeFormat = com.google.gwt.i18n.client.DateTimeFormat.getFormat(pattern);
        }

        public static DateTimeFormat getFormat(String pattern)
        {
            return new DateTimeFormatClient(pattern);
        }

        public String format(Date date)
        {
            return dateTimeFormat.format(date);
        }
    }

    @GwtIncompatible("Server version of the class")
    private static class DateTimeFormatServer extends DateTimeFormat
    {
        private java.text.SimpleDateFormat dateTimeFormat;

        protected DateTimeFormatServer(String pattern)
        {
            this.dateTimeFormat = new java.text.SimpleDateFormat(pattern);
        }

        public static DateTimeFormat getFormat(String pattern)
        {
            return new DateTimeFormatServer(pattern);
        }

        public String format(Date date)
        {
            return dateTimeFormat.format(date);
        }       

    }
}