-
Notifications
You must be signed in to change notification settings - Fork 99
/
TTTDateTransformers.m
87 lines (70 loc) · 3.17 KB
/
TTTDateTransformers.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
// TTTDateTransformers.m
//
// Copyright (c) 2013 Mattt Thompson
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#import "TTTDateTransformers.h"
#import "NSValueTransformer+TransformerKit.h"
#include <time.h>
#include <xlocale.h>
NSString * const TTTISO8601DateTransformerName = @"TTTISO8601DateTransformerName";
static NSString * TTTISO8601TimestampFromDate(NSDate *date) {
static NSDateFormatter *_iso8601DateFormatter = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_iso8601DateFormatter = [[NSDateFormatter alloc] initWithDateFormat:@"%Y-%m-%dT%H:%M:%S%z" allowNaturalLanguage:NO];
[_iso8601DateFormatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"]];
});
return [_iso8601DateFormatter stringFromDate:date];
}
static NSDate * TTTDateFromISO8601Timestamp(NSString *timestamp) {
static int const ISO_8601_MAX_LENGTH = 25;
const char *source = [timestamp cStringUsingEncoding:NSUTF8StringEncoding];
char destination[ISO_8601_MAX_LENGTH];
size_t length = strlen(source);
if (length == 0) {
return nil;
}
if (length == 20 && source[length - 1] == 'Z') {
memcpy(destination, source, length - 1);
strncpy(destination + length - 1, "+0000\0", 6);
} else if (length == 25 && source[22] == ':') {
memcpy(destination, source, 22);
memcpy(destination + 22, source + 23, 2);
} else {
memcpy(destination, source, MIN(length, ISO_8601_MAX_LENGTH - 1));
}
destination[sizeof(destination) - 1] = NULL;
struct tm time = {
.tm_isdst = -1,
};
strptime_l(source, "%FT%T%z", &time, NULL);
return [NSDate dateWithTimeIntervalSince1970:mktime(&time)];
}
@implementation TTTDateTransformers
+ (void)load {
@autoreleasepool {
[NSValueTransformer registerValueTransformerWithName:TTTISO8601DateTransformerName transformedValueClass:[NSDate class] returningTransformedValueWithBlock:^id(id value) {
return TTTISO8601TimestampFromDate(value);
} allowingReverseTransformationWithBlock:^id(id value) {
return TTTDateFromISO8601Timestamp(value);
}];
}
}
@end