How get only year with type XMLGregorianCalendar

989 Views Asked by At

i have a XML Jaxb class to set with XMLGregorianCalendar type. But we are supposed to set only year in this attribute.

XMLGregorianCalendar xmlCal = DatatypeFactory.newInstance().newXMLGregorianCalendar(new 
GregorianCalendar());
xmlCal.setYear(2021);
xmlObject.setBuiltYear(xmlCal); 
// xmlCal.getYear() will give me year but its type int , so setter method not accepting it. If 
has to be of type XMLGregorianCalendar  only with year.

If i set it like above its giving 2021-09-23T10:19:38.346-04:00 but i need only year with type XMLGregorianCalendar . how we can do that ?

2

There are 2 best solutions below

2
Arvind Kumar Avinash On BEST ANSWER

Use XMLGregorianCalendar#clear before setting the year.

Demo:

import java.util.GregorianCalendar;

import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;

public class Main {
    public static void main(String[] args) throws DatatypeConfigurationException {
        XMLGregorianCalendar xmlCal = DatatypeFactory.newInstance().newXMLGregorianCalendar(new GregorianCalendar());
        xmlCal.clear();
        xmlCal.setYear(2021);
        System.out.println(xmlCal);
    }
}

Output:

2021

ONLINE DEMO

0
Anonymous On

The answer by Arvind Kumar Avinash is good and correct. There are other ways to obtain the same, so as a supplement I am presenting a couple.

Edit: A simpler and shorter variant of the code by Arvind Kumar Avinash:

    XMLGregorianCalendar xmlCal
            = DatatypeFactory.newInstance().newXMLGregorianCalendar();
    xmlCal.setYear(2021);
    System.out.println(xmlCal);

Output:

2021

The no-arg newXMLGregorianCalendar() gives us an XMLGregorianCalendar with all fields undefined or null. Set the year, and we’re done.

You may also create your desired XMLGregorianCalendar fully complete directly from a factory method call. Here’s a longish variant:

    XMLGregorianCalendar xmlCal = DatatypeFactory.newInstance()
            .newXMLGregorianCalendarDate(2021, DatatypeConstants.FIELD_UNDEFINED,
                    DatatypeConstants.FIELD_UNDEFINED, DatatypeConstants.FIELD_UNDEFINED);

The result is the same as before. The fields that I set undefined are month, day of month and UTC offset (called timezone with XMLGregorianCalendar).

A much shorter variant is:

    XMLGregorianCalendar xmlCal
            = DatatypeFactory.newInstance().newXMLGregorianCalendar("2021");

Output is still the desired:

2021

Just as you want an XMLGregorianCalendar for the purpose of producing a specific string, the XMLGregorianCalendar can also be constructed from the string you want.

In case you had your year in an int, you may convert first:

    int year = 2021;
    XMLGregorianCalendar xmlCal = DatatypeFactory.newInstance()
            .newXMLGregorianCalendar(String.valueOf(year));

It may feel like a waste to convert your int to a String only to have it parsed again. You decide.

Which way to prefer? It’s a matter of taste.

java.time.Year

As an aside, only if your class requires an XMLGregorianCalendar, use that class. For all other purposes I recommend the Year class:

    Year year = Year.of(2021);
    System.out.println(year);

2021