1
- # JAXB type adapter classes for java.time
1
+ # Introduction
2
2
3
- Working with date and time values in JAXB can be cumbersome because you are
4
- (normally) forced to work with ` XMLGregorianCalendar ` . However, there is a
5
- simple solution for that: make JAXB use Java's ` OffsetDateTime ` and
6
- ` OffsetTime ` instead. This library provides a set of ` XmlAdapters ` to
7
- achieve this goal.
3
+ jTextTime is a small no-dep library to convert between various derivatives
4
+ of the ISO 8601 text format and the ` java.time ` classes
5
+ ` OffsetDateTime ` and ` OffsetTime ` .
8
6
9
- Adapters:
7
+ [ ISO 8601] ( https://en.wikipedia.org/wiki/ISO_8601 ) is a very versatile format.
8
+ Its 'extended form' is what most derivatives are based on and also what this
9
+ library focuses on. Unfortunately, because of its flexibility, it rarely
10
+ makes sense for an application to state that it "publishes date-time values
11
+ according to the ISO 8601 format". Yet, this is what many applications do.
12
+
13
+ jTextTime focuses on 3 date-time formats:
14
+
15
+ * XML Date-Time Schema types. This is a well-defined, narrowed, derivative
16
+ of the ISO 8601 Extended Format. jTextTime provides parsing and formatting
17
+ features. In addition, it provides ready-made JAXB type adapters for smooth
18
+ interaction with JAXB.
19
+
20
+ * ECMAScript5 Date Time format. jTextTime provides parsing and formatting
21
+ features.
22
+
23
+ * Generic ISO 8601 Extended format. There is already support for this in the JDK, but
24
+ jTextTime adds support for lenient parsing and support for the format where
25
+ the timezone offset may be absent.
26
+
27
+ When * parsing* from text to date-time objects the library allows optional
28
+ lenient parsing, for example accepting a space as the separator between
29
+ the date and time value. Lenient parsing is only done where the interpretation
30
+ is unambiguous.
31
+
32
+ When * formatting* the library places emphasis on strict compliance with
33
+ the given specification.
10
34
11
- | XmlAdapter class | XML schema data type | Java class
12
- | --- | --- | ---
13
- | ` OffsetDateTimeXmlAdapter ` | ` xs:dateTime ` | ` OffsetDateTime `
14
- | ` OffsetTimeXmlAdapter ` | ` xs:time ` | ` OffsetTime `
15
- | ` OffsetDateXmlAdapter ` | ` xs:date ` | ` OffsetDateTime ` (with time fields set to midnight)
16
- | ` OffsetDateClassXmlAdapter ` | ` xs:date ` | ` OffsetDate ` (custom class)
17
35
18
36
## Download
19
37
@@ -27,144 +45,17 @@ The library is available from Central Maven:
27
45
</dependency >
28
46
```
29
47
30
- ## Usage in classes
31
-
32
- It is outside the scope of this guide to explain how JAXB XmlAdapters are applied.
33
- But here's a little taste:
34
-
35
- ``` java
36
- public class Customer {
37
-
38
- @XmlElement
39
- @XmlJavaTypeAdapter (OffsetDateTimeXmlAdapter . class)
40
- @XmlSchemaType (name = " dateTime" )
41
- public OffsetDateTime getLastOrderTime () {
42
- ....
43
- }
44
-
45
- @XmlElement
46
- @XmlJavaTypeAdapter (OffsetDateXmlAdapter . class)
47
- @XmlSchemaType (name = " date" )
48
- public OffsetDateTime getDateOfBirth () { // returns a date-only value
49
- ....
50
- }
51
- }
52
- ```
48
+ The library has no transitive dependencies.
53
49
54
- The trick is the [ XmlJavaTypeAdapter] ( https://docs.oracle.com/javase/8/docs/api/javax/xml/bind/annotation/adapters/XmlJavaTypeAdapter.html ) annotation which can be applied to fields, getters/setters, packages, etc.
55
- In fact the most convenient usage of this library is probably to apply the
56
- annotations at the * package level* . Thereby you do not have to annotate each element/attribute
57
- individually. Simply put something like the following in your ` package-info.java ` file:
58
-
59
- ``` java
60
- @XmlJavaTypeAdapters
61
- ({
62
- @XmlJavaTypeAdapter (value = OffsetDateTimeXmlAdapter . class, type = OffsetDateTime . class),
63
- @XmlJavaTypeAdapter (value = OffsetTimeXmlAdapter . class, type = OffsetTime . class),
64
- @XmlJavaTypeAdapter (value = OffsetDateClassXmlAdapter . class, type = OffsetDate . class),
65
- })
66
- @XmlSchemaTypes
67
- ({
68
- @XmlSchemaType (name = " dateTime" , type = OffsetDateTime . class),
69
- @XmlSchemaType (name = " time" , type = OffsetTime . class),
70
- @XmlSchemaType (name = " date" , type = OffsetDate . class)
71
- })
72
- package org.example.mydtopackage ;
73
-
74
- import com.addicticks.jaxb.adapters.time.OffsetDate ;
75
- import com.addicticks.jaxb.adapters.time.OffsetDateTimeXmlAdapter ;
76
- import com.addicticks.jaxb.adapters.time.OffsetDateClassXmlAdapter ;
77
- import com.addicticks.jaxb.adapters.time.OffsetTimeXmlAdapter ;
78
- import java.time.OffsetDateTime ;
79
- import java.time.OffsetTime ;
80
- import javax.xml.bind.annotation.XmlSchemaType ;
81
- import javax.xml.bind.annotation.XmlSchemaTypes ;
82
- import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter ;
83
- import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapters ;
50
+ Requires Java 8 or later.
84
51
85
- ```
52
+ ## JAXB
53
+
54
+ The library makes working with ` java.time ` values in JAXB a breeze.
55
+ Normally you'll be forced to work with XMLGregorianCalendar, but not anymore.
86
56
87
- The adapter will now apply to all classes in the package.
88
- Furthermore, because of the ` @XmlSchemaTypes ` annotation, if you
89
- generate an XML Schema from your classes, it will use correct schema types.
90
- (otherwise you'll see ` xs:string ` as the schema type for such elements/attributes,
91
- which is * not* what you want)
92
-
93
-
94
- ## Differences between XML date/time types and Java's Offset datetime classes
95
-
96
- The ` OffsetTime ` and ` OffsetDateTime ` classes introduced in Java 8 are
97
- the closest equivalents from the java.time package to the XML Schema date
98
- and time values. However, there are a few subtle differences:
99
-
100
- * The XML date/time data types allows for the timezone offset to be left out.
101
- Therefore, when unmarshalling, we may have to supply our own value for the offset.
102
- This value should depend entirely on the scenario. By default the library will
103
- supply the current offset from the JVM's default ` ZoneId ` , but this may not be
104
- what you want. In this case then extend the adapters and override
105
- the ` getCurrentZoneOffset() ` method.
106
-
107
- * Java doesn't have a date-only data type. Two different adapters are
108
- provided for converting to/from ` xs:date ` :
109
- * ` OffsetDateClassXmlAdapter ` uses a custom ` OffsetDate ` class which is merely
110
- a thin wrapper around the ` OffsetDateTime ` class from the JDK. This is
111
- likely to be the most convenient alternative if you want to apply
112
- the ` @XmlJavaTypeAdapter ` annotation at the package level.
113
- * ` OffsetDateXmlAdapter ` uses the JDK's own ` OffsetDateTimeClass `
114
- with the time set to midnight. This is likely to be the most convenient
115
- alternative if you are using XJC to generate classes from XML schema.
116
-
117
- * The XML ` xs:time ` and ` xs:dateTime ` data types allow for unlimited number of
118
- digits in the fractional part of the seconds element. For example the following
119
- is a perfectly valid ` xs:time ` value: "23:30:28.123456789012345678901234567890".
120
- Parsing (unmarshalling) this will fail because Java's ` OffsetTime ` (and ` OffsetDateTime ` )
121
- only allows up to nano seconds precision. This means no more than 9 digits
122
- after the decimal point.
123
-
124
-
125
- ## Usage with XJC
126
-
127
- If you generate Java classes from XML schema using the ` xjc ` tool then you must
128
- use a so-called bindings file to instruct the xjc tool which adapter you want to use.
129
-
130
- Using the out-of-the-box adapters from this library then the bindings file
131
- should look like this:
132
-
133
- ``` xml
134
- <?xml version =" 1.0" encoding =" UTF-8" ?>
135
- <!-- This file is automatically picked up by the jaxb2-maven-plugin
136
- if it lives in src/main/xjb -->
137
- <jxb : bindings
138
- xmlns : jxb =" http://java.sun.com/xml/ns/jaxb"
139
- xmlns : xs =" http://www.w3.org/2001/XMLSchema"
140
- xmlns : xjc =" http://java.sun.com/xml/ns/jaxb/xjc"
141
- xmlns : xsi =" http://www.w3.org/2001/XMLSchema-instance"
142
- xsi : schemaLocation =" http://java.sun.com/xml/ns/jaxb http://java.sun.com/xml/ns/jaxb/bindingschema_2_0.xsd"
143
- version =" 2.1" >
144
-
145
- <jxb : globalBindings >
146
- <!-- Avoid having to work with XMLGregorianCalendar.
147
- Instead, map as follows:
148
-
149
- XML dateTime : OffsetDateTime
150
- XML date : OffsetDateTime (time value truncated)
151
- XML time : OffsetTime -->
152
-
153
- <xjc : javaType adapter =" com.addicticks.jaxb.adapters.time.OffsetDateTimeXmlAdapter"
154
- name =" java.time.OffsetDateTime" xmlType =" xs:dateTime" />
155
- <xjc : javaType adapter =" com.addicticks.jaxb.adapters.time.OffsetDateXmlAdapter"
156
- name =" java.time.OffsetDateTime" xmlType =" xs:date" />
157
- <xjc : javaType adapter =" com.addicticks.jaxb.adapters.time.OffsetTimeXmlAdapter"
158
- name =" java.time.OffsetTime" xmlType =" xs:time" />
159
-
160
- </jxb : globalBindings >
161
-
162
- </jxb : bindings >
163
- ```
164
-
165
- If you are using the [ JAXB2 Maven Plugin] ( https://www.mojohaus.org/jaxb2-maven-plugin/ )
166
- then name the file ` jaxb-datetime-bindings.xjb ` and place it in ` src/main/xjb ` .
167
- Thereby it will automatically be picked up by the plugin.
57
+ See [ Wiki] ( https://github.com/Addicticks/jTexttime/wiki/JAXB-type-adapter-classes-for-java.time )
58
+ for more information.
168
59
169
60
170
61
0 commit comments