Skip to content

Commit 9efbeed

Browse files
authored
Merge pull request #429 from davidmorgan/iso-datetime
Add Iso8601DateTimeSerializer.
2 parents 74e7e0d + 46bec53 commit 9efbeed

File tree

4 files changed

+95
-0
lines changed

4 files changed

+95
-0
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@
44

55
- Support serializing `BuiltSet` with `StandardJsonPlugin`. It's serialized to
66
a JSON list.
7+
- Add `Iso8601DateTimeSerializer` for use when you want ISO8601 serialization
8+
instead of microseconds since epoch.
79
- Fix code generation when inherited generic fields are made non-generic.
810

11+
912
# 5.4.5
1013

1114
- Improve error message on failure to deserialize.
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// Copyright (c) 2018, Google Inc. Please see the AUTHORS file for details.
2+
// All rights reserved. Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
import 'package:built_collection/built_collection.dart';
6+
import 'package:built_value/serializer.dart';
7+
8+
/// Alternative serializer for [DateTime].
9+
///
10+
/// Install this to use ISO8601 format instead of the default (microseconds
11+
/// since epoch). Use [SerializersBuilder.add] to install it.
12+
///
13+
/// An exception will be thrown on attempt to serialize local DateTime
14+
/// instances; you must use UTC.
15+
class Iso8601DateTimeSerializer implements PrimitiveSerializer<DateTime> {
16+
final bool structured = false;
17+
@override
18+
final Iterable<Type> types = new BuiltList<Type>([DateTime]);
19+
@override
20+
final String wireName = 'DateTime';
21+
22+
@override
23+
Object serialize(Serializers serializers, DateTime dateTime,
24+
{FullType specifiedType: FullType.unspecified}) {
25+
if (!dateTime.isUtc) {
26+
throw new ArgumentError.value(
27+
dateTime, 'dateTime', 'Must be in utc for serialization.');
28+
}
29+
30+
return dateTime.toIso8601String();
31+
}
32+
33+
@override
34+
DateTime deserialize(Serializers serializers, Object serialized,
35+
{FullType specifiedType: FullType.unspecified}) {
36+
return DateTime.parse(serialized as String).toUtc();
37+
}
38+
}

built_value/lib/standard_json_plugin.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ import 'dart:convert' show json;
99
/// and support for more collection types. But, you may need to interact with
1010
/// other systems that use simple map-based JSON. If so, use
1111
/// [SerializersBuilder.addPlugin] to install this plugin.
12+
///
13+
/// When using this plugin you may wish to also install
14+
/// `Iso8601DateTimeSerializer` which switches serialization of `DateTime`
15+
/// from microseconds since epoch to ISO 8601 format.
1216
class StandardJsonPlugin implements SerializerPlugin {
1317
static final BuiltSet<Type> _unsupportedTypes =
1418
new BuiltSet<Type>([BuiltListMultimap, BuiltSetMultimap]);
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// Copyright (c) 2018, Google Inc. Please see the AUTHORS file for details.
2+
// All rights reserved. Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
import 'package:built_value/iso_8601_date_time_serializer.dart';
6+
import 'package:built_value/serializer.dart';
7+
import 'package:test/test.dart';
8+
9+
void main() {
10+
final serializers = (new Serializers().toBuilder()
11+
..add(new Iso8601DateTimeSerializer()))
12+
.build();
13+
14+
group('DateTime with known specifiedType', () {
15+
final data = new DateTime.utc(1980, 1, 2, 3, 4, 5, 6, 7);
16+
final serialized = '1980-01-02T03:04:05.006007Z';
17+
final specifiedType = const FullType(DateTime);
18+
19+
test('can be serialized', () {
20+
expect(serializers.serialize(data, specifiedType: specifiedType),
21+
serialized);
22+
});
23+
24+
test('can be deserialized', () {
25+
expect(serializers.deserialize(serialized, specifiedType: specifiedType),
26+
data);
27+
});
28+
29+
test('serialize throws if not UTC', () {
30+
expect(() => serializers.serialize(new DateTime.now()),
31+
throwsA(new isInstanceOf<ArgumentError>()));
32+
});
33+
});
34+
35+
group('DateTime with unknown specifiedType', () {
36+
final data = new DateTime.utc(1980, 1, 2, 3, 4, 5, 6, 7);
37+
final serialized = ['DateTime', '1980-01-02T03:04:05.006007Z'];
38+
final specifiedType = FullType.unspecified;
39+
40+
test('can be serialized', () {
41+
expect(serializers.serialize(data, specifiedType: specifiedType),
42+
serialized);
43+
});
44+
45+
test('can be deserialized', () {
46+
expect(serializers.deserialize(serialized, specifiedType: specifiedType),
47+
data);
48+
});
49+
});
50+
}

0 commit comments

Comments
 (0)