Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. /*
  2. * Copyright 2012 ZXing authors
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #import "ZXCalendarParsedResult.h"
  17. static NSRegularExpression *ZX_DATE_TIME = nil;
  18. static NSRegularExpression *ZX_RFC2445_DURATION = nil;
  19. const long ZX_RFC2445_DURATION_FIELD_UNITS[] = {
  20. 7 * 24 * 60 * 60 * 1000, // 1 week
  21. 24 * 60 * 60 * 1000, // 1 day
  22. 60 * 60 * 1000, // 1 hour
  23. 60 * 1000, // 1 minute
  24. 1000, // 1 second
  25. };
  26. @implementation ZXCalendarParsedResult
  27. + (void)initialize {
  28. if ([self class] != [ZXCalendarParsedResult class]) return;
  29. ZX_DATE_TIME = [[NSRegularExpression alloc] initWithPattern:@"[0-9]{8}(T[0-9]{6}Z?)?"
  30. options:0
  31. error:nil];
  32. ZX_RFC2445_DURATION = [[NSRegularExpression alloc] initWithPattern:@"P(?:(\\d+)W)?(?:(\\d+)D)?(?:T(?:(\\d+)H)?(?:(\\d+)M)?(?:(\\d+)S)?)?"
  33. options:NSRegularExpressionCaseInsensitive
  34. error:nil];
  35. }
  36. - (id)initWithSummary:(NSString *)summary startString:(NSString *)startString endString:(NSString *)endString
  37. durationString:(NSString *)durationString location:(NSString *)location organizer:(NSString *)organizer
  38. attendees:(NSArray *)attendees description:(NSString *)description latitude:(double)latitude
  39. longitude:(double)longitude {
  40. if (self = [super initWithType:kParsedResultTypeCalendar]) {
  41. _summary = summary;
  42. _start = [self parseDate:startString];
  43. if (endString == nil) {
  44. long durationMS = [self parseDurationMS:durationString];
  45. _end = durationMS < 0 ? nil : [NSDate dateWithTimeIntervalSince1970:[_start timeIntervalSince1970] + durationMS / 1000];
  46. } else {
  47. _end = [self parseDate:endString];
  48. }
  49. _startAllDay = startString.length == 8;
  50. _endAllDay = endString != nil && endString.length == 8;
  51. _location = location;
  52. _organizer = organizer;
  53. _attendees = attendees;
  54. _resultDescription = description;
  55. _latitude = latitude;
  56. _longitude = longitude;
  57. }
  58. return self;
  59. }
  60. + (id)calendarParsedResultWithSummary:(NSString *)summary startString:(NSString *)startString
  61. endString:(NSString *)endString durationString:(NSString *)durationString
  62. location:(NSString *)location organizer:(NSString *)organizer
  63. attendees:(NSArray *)attendees description:(NSString *)description latitude:(double)latitude
  64. longitude:(double)longitude {
  65. return [[self alloc] initWithSummary:summary startString:startString endString:endString durationString:durationString
  66. location:location organizer:organizer attendees:attendees description:description
  67. latitude:latitude longitude:longitude];
  68. }
  69. - (NSString *)displayResult {
  70. NSMutableString *result = [NSMutableString stringWithCapacity:100];
  71. [ZXParsedResult maybeAppend:self.summary result:result];
  72. [ZXParsedResult maybeAppend:[self format:self.startAllDay date:self.start] result:result];
  73. [ZXParsedResult maybeAppend:[self format:self.endAllDay date:self.end] result:result];
  74. [ZXParsedResult maybeAppend:self.location result:result];
  75. [ZXParsedResult maybeAppend:self.organizer result:result];
  76. [ZXParsedResult maybeAppendArray:self.attendees result:result];
  77. [ZXParsedResult maybeAppend:self.description result:result];
  78. return result;
  79. }
  80. /**
  81. * Parses a string as a date. RFC 2445 allows the start and end fields to be of type DATE (e.g. 20081021)
  82. * or DATE-TIME (e.g. 20081021T123000 for local time, or 20081021T123000Z for UTC).
  83. */
  84. - (NSDate *)parseDate:(NSString *)when {
  85. NSArray *matches = [ZX_DATE_TIME matchesInString:when options:0 range:NSMakeRange(0, when.length)];
  86. if (matches.count == 0) {
  87. [NSException raise:NSInvalidArgumentException
  88. format:@"Invalid date"];
  89. }
  90. if (when.length == 8) {
  91. // Show only year/month/day
  92. return [[self buildDateFormat] dateFromString:when];
  93. } else {
  94. // The when string can be local time, or UTC if it ends with a Z
  95. if (when.length == 16 && [when characterAtIndex:15] == 'Z') {
  96. return [[self buildDateTimeFormat] dateFromString:[when substringToIndex:15]];
  97. } else {
  98. return [[self buildDateTimeFormat] dateFromString:when];
  99. }
  100. }
  101. }
  102. - (NSString *)format:(BOOL)allDay date:(NSDate *)date {
  103. if (date == nil) {
  104. return nil;
  105. }
  106. NSDateFormatter *format = [[NSDateFormatter alloc] init];
  107. format.dateFormat = allDay ? @"MMM d, yyyy" : @"MMM d, yyyy hh:mm:ss a";
  108. return [format stringFromDate:date];
  109. }
  110. - (long)parseDurationMS:(NSString *)durationString {
  111. if (durationString == nil) {
  112. return -1;
  113. }
  114. NSArray *m = [ZX_RFC2445_DURATION matchesInString:durationString options:0 range:NSMakeRange(0, durationString.length)];
  115. if (m.count == 0) {
  116. return -1;
  117. }
  118. long durationMS = 0;
  119. NSTextCheckingResult *match = m[0];
  120. for (int i = 0; i < sizeof(ZX_RFC2445_DURATION_FIELD_UNITS) / sizeof(long); i++) {
  121. if ([match rangeAtIndex:i + 1].location != NSNotFound) {
  122. NSString *fieldValue = [durationString substringWithRange:[match rangeAtIndex:i + 1]];
  123. if (fieldValue != nil) {
  124. durationMS += ZX_RFC2445_DURATION_FIELD_UNITS[i] * [fieldValue intValue];
  125. }
  126. }
  127. }
  128. return durationMS;
  129. }
  130. - (NSDateFormatter *)buildDateFormat {
  131. NSDateFormatter *format = [[NSDateFormatter alloc] init];
  132. format.dateFormat = @"yyyyMMdd";
  133. format.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"GMT"];
  134. return format;
  135. }
  136. - (NSDateFormatter *)buildDateTimeFormat {
  137. NSDateFormatter *format = [[NSDateFormatter alloc] init];
  138. format.dateFormat = @"yyyyMMdd'T'HHmmss";
  139. return format;
  140. }
  141. - (NSString *)description {
  142. return self.resultDescription;
  143. }
  144. @end