You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+45Lines changed: 45 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -51,6 +51,7 @@ For instance:
51
51
- To customize any aspect of `http.Client` used to perform requests, use `HttpClient` option, otherwise `http.DefaultClient` will be used
52
52
- To pass custom headers, make use of `Headers` option.
53
53
- To not fail parsing when unmapped fields exist in RPC responses, use `SkipUnknownFields(true)` option (default is `false`)
54
+
- To change how `<dateTime.iso8601>` values are encoded and decoded, use `TimeFormat` option (default is `time.RFC3339`) - see [Time formats](#time-formats)
54
55
55
56
### Argument encoding
56
57
@@ -103,6 +104,50 @@ If XML-RPC response contains no value for well-known data-types, it will be deco
103
104
As per XML-RPC specification, `<struct>` may not have an empty list of `<member>` elements, thus no default "empty" value is defined for it.
104
105
Similarly, `<array/>` is considered invalid.
105
106
107
+
### Time formats
108
+
109
+
The XML-RPC specification defines `dateTime.iso8601` as ISO8601, but implementations disagree in practice - compact and extended forms, present or absent timezone offsets and fractional seconds are all encountered.
110
+
By default this library encodes and decodes using `time.RFC3339`. The `TimeFormat` option changes that:
// Encode using the compact form from the specification's example: 19980717T14:08:55
115
+
FormatLayout: xmlrpc.LayoutISO8601Compact,
116
+
// Accept any of the commonly encountered forms when decoding
117
+
ParseLayouts: xmlrpc.CommonParseLayouts(),
118
+
// The compact layout carries no offset, so pin both directions to UTC
119
+
FormatLocation: time.UTC,
120
+
ParseLocation: time.UTC,
121
+
}))
122
+
```
123
+
124
+
Fields come in two pairs: `Format*` controls what goes on the wire, `Parse*` what is accepted off it. `FormatLayout` is the single layout used to encode; `ParseLayouts` are tried in order when decoding and default to `FormatLayout` when unset. When you do set `ParseLayouts` it is the complete list - `FormatLayout` is not added for you, so include it if this client should still read back what it writes. A few layout constants are provided:
ISO8601 calls the form without separators *basic* and the form with them *extended*. The layout shown in the XML-RPC specification's example is neither - a basic date with an extended time - and is called *compact* here. The specification does not mandate a layout, and leaves timezone assumptions to server documentation, which is why this is configurable at all. A fractional second is accepted on decode even though no layout declares one.
136
+
137
+
Notes on timezones:
138
+
139
+
*`ParseLocation` only applies to decoded values whose layout carries no offset - values that do carry one always keep it. Left unset it follows `time.Parse`: offset-less values are UTC, and an offset matching the process timezone yields that location along with its DST rules. Set it to decode into one location regardless of where the process runs.
140
+
*`FormatLocation`, when set, converts values to that location before encoding. By default values are encoded in whichever location they carry, which is fine for zoned layouts but a trap for zone-less ones: a non-UTC `time.Time` would be written as its local wall-clock with no offset, and the receiver has no way to know. **Always set `FormatLocation` when `FormatLayout` carries no offset.**
141
+
142
+
Servers doing something stranger than a fixed set of layouts can be handled by implementing the `TimeFormatter` interface directly:
143
+
144
+
```go
145
+
typeTimeFormatterinterface {
146
+
FormatTime(t time.Time) string
147
+
ParseTime(value string) (time.Time, error)
148
+
}
149
+
```
150
+
106
151
### Field renaming
107
152
108
153
XML-RPC specification does not necessarily specify any rules for struct's member names. Some services allow struct member names to include characters not compatible with standard Go field naming.
0 commit comments