@@ -187,17 +187,17 @@ } + (instancetype)distantFuture { return [[[self alloc] - initWithTimeIntervalSince1970: DBL_MAX] autorelease]; + initWithTimeIntervalSince1970: INFINITY] autorelease]; } + (instancetype)distantPast { return [[[self alloc] - initWithTimeIntervalSince1970: DBL_MIN] autorelease]; + initWithTimeIntervalSince1970: -INFINITY] autorelease]; } - init { struct timeval t; @@ -303,21 +303,30 @@ { self = [super init]; @try { void *pool = objc_autoreleasePoolPush(); + OFString *stringValue; union { double d; uint64_t u; } d; if (![[element name] isEqual: [self className]] || ![[element namespace] isEqual: OF_SERIALIZATION_NS]) @throw [OFInvalidArgumentException exception]; - d.u = (uint64_t)[element hexadecimalValue]; - _seconds = d.d; + stringValue = [element stringValue]; + + if ([stringValue isEqual: @"DISTANT_PAST"]) + _seconds = -INFINITY; + else if ([stringValue isEqual: @"DISTANT_FUTURE"]) + _seconds = INFINITY; + else { + d.u = (uint64_t)[element hexadecimalValue]; + _seconds = d.d; + } objc_autoreleasePoolPop(pool); } @catch (id e) { [self release]; @throw e; @@ -384,11 +393,14 @@ return OF_ORDERED_SAME; } - (OFString*)description { - return [self dateStringWithFormat: @"%Y-%m-%dT%H:%M:%SZ"]; + if (isinf(_seconds)) + return (_seconds > 0 ? @"Distant Future" : @"Distant Past"); + else + return [self dateStringWithFormat: @"%Y-%m-%dT%H:%M:%SZ"]; } - (OFXMLElement*)XMLElementBySerializing { void *pool = objc_autoreleasePoolPush(); @@ -399,13 +411,18 @@ } d; element = [OFXMLElement elementWithName: [self className] namespace: OF_SERIALIZATION_NS]; - d.d = _seconds; - [element setStringValue: - [OFString stringWithFormat: @"%016" PRIx64, d.u]]; + if (isinf(_seconds)) + [element setStringValue: + (_seconds > 0 ? @"DISTANT_FUTURE" : @"DISTANT_PAST")]; + else { + d.d = _seconds; + [element setStringValue: + [OFString stringWithFormat: @"%016" PRIx64, d.u]]; + } [element retain]; objc_autoreleasePoolPop(pool);