Skip to content

Commit

Permalink
Merge pull request #1483 from cacaodev/CFPropertyList-XML-date-deseri…
Browse files Browse the repository at this point in the history
…alization

CPDate deserialization from XML Property List, with test.
  • Loading branch information
aparajita committed Mar 25, 2012
2 parents 1a8fc7f + 9ef95e1 commit e13d070
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 0 deletions.
37 changes: 37 additions & 0 deletions Foundation/CPDate.j
Original file line number Diff line number Diff line change
Expand Up @@ -231,4 +231,41 @@ var CPDateTimeKey = @"CPDateTimeKey";

@end

// Based on 'Universal JavaScript Date.parse for ISO 8601' available at https://github.com/csnover/js-iso8601.
var numericKeys = [1, 4, 5, 6, 7, 10, 11];
Date.parseISO8601 = function (date)
{
var timestamp, struct, minutesOffset = 0;

// First, check for native parsing.
timestamp = Date.parse(date);

if (isNaN(timestamp) && (struct = /^(\d{4}|[+\-]\d{6})(?:-(\d{2})(?:-(\d{2}))?)?(?:T(\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{3}))?)?(?:(Z)|([+\-])(\d{2})(?::(\d{2}))?)?)?$/.exec(date)))
{
// avoid NaN timestamps caused by “undefined” values being passed to Date.UTC
for (var i = 0, k; (k = numericKeys[i]); ++i)
{
struct[k] = +struct[k] || 0;
}

// allow undefined days and months
struct[2] = (+struct[2] || 1) - 1;
struct[3] = +struct[3] || 1;

if (struct[8] !== 'Z' && struct[9] !== undefined)
{
minutesOffset = struct[10] * 60 + struct[11];

if (struct[9] === '+')
{
minutesOffset = 0 - minutesOffset;
}
}

return Date.UTC(struct[1], struct[2], struct[3], struct[4], struct[5] + minutesOffset, struct[6], struct[7]);
}

return timestamp;
};

Date.prototype.isa = CPDate;
5 changes: 5 additions & 0 deletions Objective-J/CFPropertyList.js
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,7 @@ var XML_XML = "xml",
PLIST_DICTIONARY = "dict",
PLIST_ARRAY = "array",
PLIST_STRING = "string",
PLIST_DATE = "date",
PLIST_BOOLEAN_TRUE = "true",
PLIST_BOOLEAN_FALSE = "false",
PLIST_NUMBER_REAL = "real",
Expand Down Expand Up @@ -596,6 +597,10 @@ CFPropertyList.propertyListFromXML = function(/*String | XMLNode*/ aStringOrXMLN
object = decodeHTMLComponent(FIRST_CHILD(XMLNode) ? TEXT_CONTENT(XMLNode) : "");

break;

case PLIST_DATE: var timestamp = Date.parseISO8601(TEXT_CONTENT(XMLNode));
object = isNaN(timestamp) ? new Date() : new Date(timestamp);
break;

case PLIST_BOOLEAN_TRUE: object = YES;
break;
Expand Down
10 changes: 10 additions & 0 deletions Tests/Objective-J/CFPropertyListTest.j
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,14 @@ var FILE = require("file"),
});
}

- (void)testDateDeserialization
{
var path = FILE.join(FILE.dirname(module.path), "PropertyLists/XMLDate.plist"),
object = CFPropertyList.readPropertyListFromFile(path),
date = [object objectForKey:@"date"];

[self assert:[CPDate class] equals:[date class]];
[self assert:[[CPDate alloc] initWithString:"2012-01-01 10:00:00 +0100"] equals:date];
}

@end
8 changes: 8 additions & 0 deletions Tests/Objective-J/PropertyLists/XMLDate.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>date</key>
<date>2012-01-01T09:00:00Z</date>
</dict>
</plist>

0 comments on commit e13d070

Please sign in to comment.