123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164 |
- /*
- * Copyright 2012 ZXing authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
- #import "ZXCalendarParsedResult.h"
-
- static NSRegularExpression *ZX_DATE_TIME = nil;
- static NSRegularExpression *ZX_RFC2445_DURATION = nil;
-
- const long ZX_RFC2445_DURATION_FIELD_UNITS[] = {
- 7 * 24 * 60 * 60 * 1000, // 1 week
- 24 * 60 * 60 * 1000, // 1 day
- 60 * 60 * 1000, // 1 hour
- 60 * 1000, // 1 minute
- 1000, // 1 second
- };
-
- @implementation ZXCalendarParsedResult
-
- + (void)initialize {
- if ([self class] != [ZXCalendarParsedResult class]) return;
-
- ZX_DATE_TIME = [[NSRegularExpression alloc] initWithPattern:@"[0-9]{8}(T[0-9]{6}Z?)?"
- options:0
- error:nil];
-
- ZX_RFC2445_DURATION = [[NSRegularExpression alloc] initWithPattern:@"P(?:(\\d+)W)?(?:(\\d+)D)?(?:T(?:(\\d+)H)?(?:(\\d+)M)?(?:(\\d+)S)?)?"
- options:NSRegularExpressionCaseInsensitive
- error:nil];
- }
-
- - (id)initWithSummary:(NSString *)summary startString:(NSString *)startString endString:(NSString *)endString
- durationString:(NSString *)durationString location:(NSString *)location organizer:(NSString *)organizer
- attendees:(NSArray *)attendees description:(NSString *)description latitude:(double)latitude
- longitude:(double)longitude {
- if (self = [super initWithType:kParsedResultTypeCalendar]) {
- _summary = summary;
- _start = [self parseDate:startString];
-
- if (endString == nil) {
- long durationMS = [self parseDurationMS:durationString];
- _end = durationMS < 0 ? nil : [NSDate dateWithTimeIntervalSince1970:[_start timeIntervalSince1970] + durationMS / 1000];
- } else {
- _end = [self parseDate:endString];
- }
-
- _startAllDay = startString.length == 8;
- _endAllDay = endString != nil && endString.length == 8;
-
- _location = location;
- _organizer = organizer;
- _attendees = attendees;
- _resultDescription = description;
- _latitude = latitude;
- _longitude = longitude;
- }
- return self;
- }
-
- + (id)calendarParsedResultWithSummary:(NSString *)summary startString:(NSString *)startString
- endString:(NSString *)endString durationString:(NSString *)durationString
- location:(NSString *)location organizer:(NSString *)organizer
- attendees:(NSArray *)attendees description:(NSString *)description latitude:(double)latitude
- longitude:(double)longitude {
- return [[self alloc] initWithSummary:summary startString:startString endString:endString durationString:durationString
- location:location organizer:organizer attendees:attendees description:description
- latitude:latitude longitude:longitude];
- }
-
- - (NSString *)displayResult {
- NSMutableString *result = [NSMutableString stringWithCapacity:100];
- [ZXParsedResult maybeAppend:self.summary result:result];
- [ZXParsedResult maybeAppend:[self format:self.startAllDay date:self.start] result:result];
- [ZXParsedResult maybeAppend:[self format:self.endAllDay date:self.end] result:result];
- [ZXParsedResult maybeAppend:self.location result:result];
- [ZXParsedResult maybeAppend:self.organizer result:result];
- [ZXParsedResult maybeAppendArray:self.attendees result:result];
- [ZXParsedResult maybeAppend:self.description result:result];
- return result;
- }
-
- /**
- * Parses a string as a date. RFC 2445 allows the start and end fields to be of type DATE (e.g. 20081021)
- * or DATE-TIME (e.g. 20081021T123000 for local time, or 20081021T123000Z for UTC).
- */
- - (NSDate *)parseDate:(NSString *)when {
- NSArray *matches = [ZX_DATE_TIME matchesInString:when options:0 range:NSMakeRange(0, when.length)];
- if (matches.count == 0) {
- [NSException raise:NSInvalidArgumentException
- format:@"Invalid date"];
- }
- if (when.length == 8) {
- // Show only year/month/day
- return [[self buildDateFormat] dateFromString:when];
- } else {
- // The when string can be local time, or UTC if it ends with a Z
- if (when.length == 16 && [when characterAtIndex:15] == 'Z') {
- return [[self buildDateTimeFormat] dateFromString:[when substringToIndex:15]];
- } else {
- return [[self buildDateTimeFormat] dateFromString:when];
- }
- }
- }
-
- - (NSString *)format:(BOOL)allDay date:(NSDate *)date {
- if (date == nil) {
- return nil;
- }
- NSDateFormatter *format = [[NSDateFormatter alloc] init];
- format.dateFormat = allDay ? @"MMM d, yyyy" : @"MMM d, yyyy hh:mm:ss a";
- return [format stringFromDate:date];
- }
-
- - (long)parseDurationMS:(NSString *)durationString {
- if (durationString == nil) {
- return -1;
- }
- NSArray *m = [ZX_RFC2445_DURATION matchesInString:durationString options:0 range:NSMakeRange(0, durationString.length)];
- if (m.count == 0) {
- return -1;
- }
- long durationMS = 0;
- NSTextCheckingResult *match = m[0];
- for (int i = 0; i < sizeof(ZX_RFC2445_DURATION_FIELD_UNITS) / sizeof(long); i++) {
- if ([match rangeAtIndex:i + 1].location != NSNotFound) {
- NSString *fieldValue = [durationString substringWithRange:[match rangeAtIndex:i + 1]];
- if (fieldValue != nil) {
- durationMS += ZX_RFC2445_DURATION_FIELD_UNITS[i] * [fieldValue intValue];
- }
- }
- }
- return durationMS;
- }
-
- - (NSDateFormatter *)buildDateFormat {
- NSDateFormatter *format = [[NSDateFormatter alloc] init];
- format.dateFormat = @"yyyyMMdd";
- format.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"GMT"];
- return format;
- }
-
- - (NSDateFormatter *)buildDateTimeFormat {
- NSDateFormatter *format = [[NSDateFormatter alloc] init];
- format.dateFormat = @"yyyyMMdd'T'HHmmss";
- return format;
- }
-
- - (NSString *)description {
- return self.resultDescription;
- }
-
- @end
|