Unverified Commit 2e183b62 authored by Zachary Anderson's avatar Zachary Anderson Committed by GitHub

[flutter_tool] Include the local timezone in analytics timestamp (#37345)

parent 0d6a962b
......@@ -32,3 +32,18 @@ class _FixedTimeClock extends SystemClock {
@override
DateTime now() => _fixedTime;
}
/// Format time as 'yyyy-MM-dd HH:mm:ss Z' where Z is the difference between the
/// timezone of t and UTC formatted according to RFC 822.
String formatDateTime(DateTime t) {
final String sign = t.timeZoneOffset.isNegative ? '-' : '+';
final Duration tzOffset = t.timeZoneOffset.abs();
final int hoursOffset = tzOffset.inHours;
final int minutesOffset =
tzOffset.inMinutes - (Duration.minutesPerHour * hoursOffset);
assert(hoursOffset < 24);
assert(minutesOffset < 60);
String twoDigits(int n) => (n >= 10) ? '$n' : '0$n';
return '$t $sign${twoDigits(hoursOffset)}${twoDigits(minutesOffset)}';
}
......@@ -223,7 +223,7 @@ class _UsageImpl implements Usage {
final Map<String, String> paramsWithLocalTime = <String, String>{
...?parameters,
cdKey(CustomDimensions.localTime): systemClock.now().toString(),
cdKey(CustomDimensions.localTime): formatDateTime(systemClock.now()),
};
_analytics.sendScreenView(command, parameters: paramsWithLocalTime);
}
......@@ -240,7 +240,7 @@ class _UsageImpl implements Usage {
final Map<String, String> paramsWithLocalTime = <String, String>{
...?parameters,
cdKey(CustomDimensions.localTime): systemClock.now().toString(),
cdKey(CustomDimensions.localTime): formatDateTime(systemClock.now()),
};
_analytics.sendEvent(category, parameter, parameters: paramsWithLocalTime);
......
......@@ -212,7 +212,7 @@ void main() {
final String log = fs.file('analytics.log').readAsStringSync();
final DateTime dateTime = DateTime.fromMillisecondsSinceEpoch(kMillis);
expect(log.contains(dateTime.toString()), isTrue);
expect(log.contains(formatDateTime(dateTime)), isTrue);
}, overrides: <Type, Generator>{
FileSystem: () => memoryFileSystem,
SystemClock: () => mockClock,
......@@ -237,7 +237,7 @@ void main() {
final String log = fs.file('analytics.log').readAsStringSync();
final DateTime dateTime = DateTime.fromMillisecondsSinceEpoch(kMillis);
expect(log.contains(dateTime.toString()), isTrue);
expect(log.contains(formatDateTime(dateTime)), isTrue);
}, overrides: <Type, Generator>{
FileSystem: () => memoryFileSystem,
SystemClock: () => mockClock,
......
......@@ -18,4 +18,22 @@ void main() {
expect(clock.ago(const Duration(days: 10)), DateTime(1991, 8, 13));
});
});
group('formatting', () {
test('can round-trip formatted time', () {
final DateTime time = DateTime(1991, 7, 31);
expect(time.isUtc, isFalse);
// formatDateTime() adds a timezone offset to DateTime.toString().
final String formattedTime = formatDateTime(time);
// If a date time string has a timezone offset, DateTime.tryParse()
// converts the parsed time to UTC.
final DateTime parsedTime = DateTime.tryParse(formattedTime);
expect(parsedTime, isNotNull);
expect(parsedTime.isUtc, isTrue);
// Convert the parsed time (which should be utc) to the local timezone and
// compare against the original time which is in the local timezone. They
// should be the same.
expect(parsedTime.toLocal(), equals(time));
});
});
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment