Ответ 1
UPDATE
подведение итогов:
- у вас есть схема, которая где-то использует стиль даты, и вы не можете изменить схему
- у вас есть XML-данные, которые используют эту схему и указывают какую-либо дату с часовым поясом (так что это формат
yyyy-MM-ddXXX
) - вы хотите удалить часть
XXX
из представления даты в этом файле (сама дата не отправляет какой-либо часовой пояс, дата - всего лишь число)
поэтому это может быть примерная схема:
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<element name="foo">
<complexType>
<sequence>
<element name="bar" type="date" minOccurs="1" maxOccurs="1"/>
</sequence>
</complexType>
</element>
</schema>
это может быть пример данных:
<?xml version="1.0" encoding="UTF-8"?>
<foo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="foo.xsd">
<bar>2014-01-01+06:00</bar>
</foo>
это аннотированный класс JAXB
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Foo implements Serializable
{
private static final long serialVersionUID = 1L;
@XmlElement(name = "bar")
@XmlJavaTypeAdapter(DateAdapter.class)
@XmlSchemaType(name = "date")
private Date bar;
// getters/setters
}
это адаптер даты
public class DateAdapter extends XmlAdapter<String, Date>
{
@Override
public String marshal(Date date)
{
DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
df.setTimeZone(TimeZone.getTimeZone("GMT"));
return df.format(date);
}
@Override
public Date unmarshal(String date) throws ParseException
{
DateFormat df = new SimpleDateFormat("yyyy-MM-ddXXX");
return df.parse(date);
}
}
это главное, проверяющее схему:
public static void main(String[] args) throws JAXBException, SAXException
{
JAXBContext context = JAXBContext.newInstance(Foo.class);
SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = sf.newSchema(Foo.class.getResource("/foo.xsd"));
Unmarshaller unmarshaller = context.createUnmarshaller();
unmarshaller.setSchema(schema);
Foo foo = (Foo) unmarshaller.unmarshal(Foo.class.getResource("/foo.xml"));
System.out.println("unmarshalled: " + foo.getBar());
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.setProperty(Marshaller.JAXB_NO_NAMESPACE_SCHEMA_LOCATION, "foo.xsd");
marshaller.setSchema(schema);
marshaller.marshal(foo, System.out);
}
и это результат, часовой пояс был удален, и представление даты явно изменилось
unmarshalled: Tue Dec 31 19:00:00 CET 2013
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<foo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="foo.xsd">
<bar>2013-12-31</bar>
</foo>
Возможно, это изменение представления даты не то, что вы ожидаете, но это не относится к JAXB, дата не изменилась.
я забыл привязки для обратного генерации Foo:
<jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc" jaxb:extensionBindingPrefixes="xjc" jaxb:version="2.0">
<jaxb:globalBindings>
<xjc:javaType name="java.util.Date" xmlType="xsd:date" adapter="aaa.DateAdapter" />
</jaxb:globalBindings>
</jaxb:bindings>
КОНЕЦ ОБНОВЛЕНИЯ
Извините, слишком долго для комментария...
я не могу понять:
- Почему, черт возьми, вы используете
XmlGregorianCalendar
? - почему вы должны
marshal
/unmarshal
(serialize
/deserialize
) в ту же структуру данных? - почему вы должны удалить часовой пояс?
и
- Я использую прямое и простое
java.util.Date
-
marshal
/unmarshal
должен всегда включатьString
(по крайней мере для XML) - Я действительно не вижу веских оснований для произвольного удаления части представления даты. возможно, вы хотите сериализовать его в абсолютном режиме.
Однако
public class DateAdapter extends XmlAdapter<String, Date>
{
@Override
public String marshal(Date date)
{
DateFormat df = DateFormat.getDateTimeInstance();
df.setTimeZone(TimeZone.getTimeZone("GMT"));
return df.format(date);
}
@Override
public Date unmarshal(String date) throws ParseException
{
DateFormat df = DateFormat.getDateTimeInstance();
df.setTimeZone(TimeZone.getTimeZone("GMT"));
return df.parse(date);
}
public static void main(String[] args) throws ParseException
{
DateAdapter adapter = new DateAdapter();
String str = adapter.marshal(new Date());
System.out.println(str); // 16-dic-2013 10.02.09 --> to gmt
Date date = adapter.unmarshal(str);
System.out.println(date); // Mon Dec 16 11:02:09 CET 2013 --> correct, i'm gmt+1
}
}