Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Timestamps are now represented to the millisecond rather than the second #847

Merged
merged 1 commit into from
Oct 16, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 22 additions & 8 deletions Bugsnag/Helpers/BSG_RFC3339DateTool.m
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,13 @@

#import "BSG_RFC3339DateTool.h"

// New formatter: Everything is UTC
// New formatter: Everything is UTC with milliseconds
static NSDateFormatter *g_currentDateFormatter;

// Old formatter: Everything is UTC, no milliseconds
static NSDateFormatter *g_utcDateFormatter;

// Old formatter: Time zones can be specified
// Oldx2 formatter: Time zones can be specified
static NSDateFormatter *g_timezoneAllowedDateFormatter;

@implementation BSG_RFC3339DateTool
Expand All @@ -36,6 +39,11 @@ + (void)initialize {
NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"];
NSTimeZone *zone = [NSTimeZone timeZoneForSecondsFromGMT:0];

g_currentDateFormatter = [NSDateFormatter new];
[g_currentDateFormatter setLocale:locale];
[g_currentDateFormatter setTimeZone:zone];
[g_currentDateFormatter setDateFormat:@"yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'SSS'Z'"];

g_utcDateFormatter = [NSDateFormatter new];
[g_utcDateFormatter setLocale:locale];
[g_utcDateFormatter setTimeZone:zone];
Expand All @@ -52,19 +60,25 @@ + (NSString *)stringFromDate:(NSDate *)date {
if (![date isKindOfClass:[NSDate class]]) {
return nil;
}
return [g_utcDateFormatter stringFromDate:date];
return [g_currentDateFormatter stringFromDate:date];
}

+ (NSDate *)dateFromString:(NSString *)string {
if (![string isKindOfClass:[NSString class]]) {
return nil;
}
NSDate *date = [g_utcDateFormatter dateFromString:string];
if (!date) {
// Fallback to older date format that included time zones
date = [g_timezoneAllowedDateFormatter dateFromString:string];
NSDate *date = nil;

if((date = [g_currentDateFormatter dateFromString:string]) != nil) {
return date;
}

// Fallback to older date formats
if((date = [g_utcDateFormatter dateFromString:string]) != nil) {
return date;
}
return date;

return [g_timezoneAllowedDateFormatter dateFromString:string];
}

+ (NSString *)stringFromUNIXTimestamp:(unsigned long long)timestamp {
Expand Down
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
Changelog
=========

## TBD

## Enhancements

* Timestamp accuracy in reports has been increased from seconds to milliseconds.
[847](https://github.com/bugsnag/bugsnag-cocoa/pull/847)

## 6.2.1 (2020-10-15)

## Bug fixes
Expand Down
2 changes: 1 addition & 1 deletion Tests/BugsnagBreadcrumbsTest.m
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ - (void)testArrayValue {
XCTAssertNotNil(value);
XCTAssertTrue(value.count == 3);
NSDateFormatter *formatter = [NSDateFormatter new];
formatter.dateFormat = @"yyyy'-'MM'-'dd'T'HH':'mm':'ssX5";
formatter.dateFormat = @"yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'SSSX5";
for (int i = 0; i < value.count; i++) {
NSDictionary *item = value[i];
XCTAssertTrue([item isKindOfClass:[NSDictionary class]]);
Expand Down
2 changes: 1 addition & 1 deletion Tests/BugsnagErrorReportSinkTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ - (void)testEventDevice {
XCTAssertEqualObjects(device[@"jailbroken"], @YES);
XCTAssertEqualObjects(device[@"freeMemory"], @742920192);
XCTAssertEqualObjects(device[@"orientation"], @"unknown");
XCTAssertEqualObjects(device[@"time"], @"2014-12-02T01:56:13Z");
XCTAssertEqualObjects(device[@"time"], @"2014-12-02T01:56:13.000Z");
}

- (void)testEventApp {
Expand Down
37 changes: 34 additions & 3 deletions Tests/KSCrash/RFC3339DateTool_Tests.m
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,37 @@ @interface RFC3339DateTool_Tests : XCTestCase @end

@implementation RFC3339DateTool_Tests

- (NSDate *)newDateWithYear:(int) year month:(int)month day:(int)day hour:(int)hour minute:(int)minute second:(int)second nano:(int)nano tz:(NSString *)tz {
NSDateComponents* comps = [[NSDateComponents alloc]init];
comps.year = year;
comps.month = month;
comps.day = day;
comps.hour = hour;
comps.minute = minute;
comps.second = second;
comps.nanosecond = nano;
comps.timeZone = [NSTimeZone timeZoneWithName:tz];
NSCalendar* calendar = [NSCalendar currentCalendar];
return [calendar dateFromComponents:comps];
}

- (void)assertString:(NSString*)asString isEquivalentToString:(NSString *)encodedString andYear:(int) year month:(int)month day:(int)day hour:(int)hour minute:(int)minute second:(int)second nano:(int)nano tz:(NSString *)tz {
NSDate *expectedDate = [self newDateWithYear:year month:month day:day hour:hour minute:minute second:second nano:nano tz:tz];
NSDate *actualDate = [BSG_RFC3339DateTool dateFromString:asString];
NSString *actualString = [BSG_RFC3339DateTool stringFromDate:expectedDate];
XCTAssertEqualObjects(encodedString, actualString);
NSString *expectedInterval = [NSString stringWithFormat:@"%f", expectedDate.timeIntervalSince1970];
NSString *actualInterval = [NSString stringWithFormat:@"%f", actualDate.timeIntervalSince1970];
XCTAssertEqualObjects(expectedInterval, actualInterval);
}

- (void)testLegacyFormats {
[self assertString:@"2020-05-14T11:41:20.123Z" isEquivalentToString:@"2020-05-14T11:41:20.123Z" andYear:2020 month:5 day:14 hour:11 minute:41 second:20 nano:123000000 tz:@"UTC"];
[self assertString:@"2020-05-14T11:41:20Z" isEquivalentToString:@"2020-05-14T11:41:20.000Z" andYear:2020 month:5 day:14 hour:11 minute:41 second:20 nano:0 tz:@"UTC"];
[self assertString:@"2020-05-14T11:41:20+000" isEquivalentToString:@"2020-05-14T11:41:20.000Z" andYear:2020 month:5 day:14 hour:11 minute:41 second:20 nano:0 tz:@"UTC"];
[self assertString:@"2020-05-14T12:41:20+100" isEquivalentToString:@"2020-05-14T11:41:20.000Z" andYear:2020 month:5 day:14 hour:11 minute:41 second:20 nano:0 tz:@"UTC"];
}

- (NSDate*) gmtDateWithYear:(int) year
month:(int) month
day:(int) day
Expand All @@ -54,7 +85,7 @@ - (NSDate*) gmtDateWithYear:(int) year
- (void) testStringFromDate
{
NSDate* date = [self gmtDateWithYear:2000 month:1 day:2 hour:3 minute:4 second:5];
NSString* expected = @"2000-01-02T03:04:05Z";
NSString* expected = @"2000-01-02T03:04:05.000Z";
NSString* actual = [BSG_RFC3339DateTool stringFromDate:date];

XCTAssertEqualObjects(actual, expected, @"");
Expand Down Expand Up @@ -84,13 +115,13 @@ - (void) testDateFromStringWithTimezonePlus2
XCTAssertEqualObjects(actual, expected, @"");

// Convert back again to verify overall effect
XCTAssertEqualObjects([BSG_RFC3339DateTool stringFromDate:actual], @"2000-01-02T01:04:05Z");
XCTAssertEqualObjects([BSG_RFC3339DateTool stringFromDate:actual], @"2000-01-02T01:04:05.000Z");
}

- (void) testStringFromUnixTimestamp
{
NSDate* date = [self gmtDateWithYear:2000 month:1 day:2 hour:3 minute:4 second:5];
NSString* expected = @"2000-01-02T03:04:05Z";
NSString* expected = @"2000-01-02T03:04:05.000Z";
NSString* actual = [BSG_RFC3339DateTool stringFromUNIXTimestamp:(unsigned long long)[date timeIntervalSince1970]];

XCTAssertEqualObjects(actual, expected, @"");
Expand Down
2 changes: 1 addition & 1 deletion Tests/report-react-native-promise-rejection.json

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions Tests/report.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"system": {
"binary_cpu_type": 16777223,
"boot_time": "2014-11-18T07:02:37Z",
"boot_time": "2014-11-18T07:02:37.000Z",
"CFBundleName": "CrashProbeiOS",
"app_uuid": "D0A41830-4FD2-3B02-A23B-0741AD4C7F52",
"process_name": "CrashProbeiOS",
Expand All @@ -24,7 +24,7 @@
"CFBundleShortVersionString": "1.0",
"binary_cpu_subtype": 3,
"system_name": "iPhone OS",
"app_start_time": "2014-12-02T01:56:13Z",
"app_start_time": "2014-12-02T01:56:13.000Z",
"CFBundleExecutable": "CrashProbeiOS",
"process_id": 15137,
"cpu_subtype": 8,
Expand All @@ -48,7 +48,7 @@
"report": {
"process_name": "CrashProbeiOS",
"id": "10BA6DDD-6658-4B6A-B66E-9378B9F354BB",
"timestamp": "2014-12-02T01:56:13Z",
"timestamp": "2014-12-02T01:56:13.000Z",
"type": "standard",
"version": {
"major": 3,
Expand Down Expand Up @@ -2103,8 +2103,8 @@
"depth": 4,
"severity": "warning",
"breadcrumbs": [
{"message": "App launched", "timestamp": "2020-02-14T16:12:22Z", "type": "manual", "metaData":{}},
{"message": "Tapped button", "timestamp": "2020-02-14T16:12:24Z", "type": "manual", "metaData":{}}
{"message": "App launched", "timestamp": "2020-02-14T16:12:22.000Z", "type": "manual", "metaData":{}},
{"message": "Tapped button", "timestamp": "2020-02-14T16:12:24.000Z", "type": "manual", "metaData":{}}
]
}
}
Expand Down