Skip to content

Configuring Date and Time Mapping

Blake Watters edited this page Sep 28, 2013 · 8 revisions

Deprecated in v0.21.0

This document details date and time transformation API's that were deprecated in RestKit v0.21.0. Please consult the Object Mapping document in the Transforming Date and Time Representations subsection of the Value Transformation reference for information about working with RKValueTransformers instead.

RestKit is capable of parsing string representations containing dates and times and mapping them into local NSDate attributes as well as serializing local NSDate properties into strings for transport over HTTP. This document details the specifics of configuring this support for your application.

NSDateFormatter objects are known to be expensive to setup and tear down. For this reason, RestKit maintains an internal collection of date formatters that are used across all object mapping operations. By default, RestKit defines date formatters for you that will parse dates with the following configurations:

  1. yyyy-MM-dd'T'HH:mm:ss'Z' in the UTC Time Zone
  2. MM/dd/yyyy in the UTC Time Zone

Global date formatters are configured via static methods on the RKObjectMapping class:

  • + defaultDateFormatters - Returns the currently configured collection date formatters to consult when mapping strings into dates.
  • + setDefaultDateFormatters: - Sets a new default collection of date formatters. Expects dateFormatters to be an array of NSDateFormatter objects.
  • + addDefaultDateFormatter: - Adds a NSDateFormatter to the end of the list of date formatters to use when parsing dates from strings.
  • + addDefaultDateFormatterForString:inTimeZone: - Constructs a new NSDateFormatter for you configured with the specified date format string and time zone. If a nil time zone is provided, the formatter will be configured for UTC time.
  • + preferredDateFormatter - Returns the preferred date formatter for use when transforming NSDate attributes into NSString representations. The preferred formatter is used when serializing into form encoded and JSON representations. Changing the preferred formatter will change how dates are sent to your remote backend for processing. Defaults to @"yyyy-MM-dd HH:mm:ss Z" in the UTC time zone.
  • + setPreferredDateFormatter: - Sets the preferred date formatter to a new NSDateFormatter object. This formatter will be used during serialization.

You can also configure how dates and times are handled on a per-object mapping basis via properties on instances of RKObjectMapping:

For applications that depend on ASP.NET JSON resources, dates are encoded in specially formatted strings, appearing as either of the following formats: /Date(1234567890123+0000)/ or /Date(1234567890123)/. In both cases, the 13 digit number is based off of the number of milliseconds since January 1, 1970 00:00 GMT. The +0000 is the timezone offset from GMT (in hours and minutes). This relative date style makes it impossible to map to an NSDate using only the standard NSDateFormatter class. Therefore, we have provided a special formatter class for this purpose, aptly named RKDotNetDateFormatter:

  • + dotNetDateFormatter: - Instantiates an autoreleased RKDotNetDateFormatter object with the timezone set to GMT, and suitable for use in place of a standard NSDateFormatter. No additional configuration is required.
  • + dotNetDateFormatterWithTimeZone: - Instantiates an autoreleased RKDotNetDateFormatter object with a provided timeZone, and suitable for use in place of a standard NSDateFormatter. No additional configuration is required. This customized timezone is only effective during serialization, such as during a conversion of an existing NSDate in your model to an ASP.NET JSON representation. The reason for this is outlined below.

For application that depend on Ruby on Rails JSON resource with dates like 2013-01-01T12:00:00+00:00 use RKISO8601DateFormatter formater.

  • NOTE: NSDate objects do not have timezones, and you should never change an actual date value based on a timezone offset. However, timezones are important when presenting dates to the user. Therefore, If an offset is present in the ASP.NET string during mapping for incoming data, we actually ignore the offset portion (i.e. +0500) of the date string because we want to store the actual date value in its raw form, without any pollution of timezone information. If, on the other hand, there is no offset in the ASP.NET string, we assume GMT (+0000) anyway. To reiterate, timezones are only used and employed during serialization (converting NSDates to ASP.NET strings).

Examples

Setting the Date Formatters for a Particular Mapping

Change the date handling for a particular object mapping to only use the specified formatter.

NSDateFormatter* dateFormatter = [NSDateFormatter new];
[dateFormatter  setDateFormat:@"yyyy-MM-dd"];
dateFormatter.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"UTC"];
dateFormatter.locale = [[[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"] autorelease];

assignmentMapping.dateFormatters = [NSArray arrayWithObject: dateFormatter];

Add a new Global Formatter

Add a new formatter that will be used for all object mappings when the target attribute is an NSDate property.

// Construct our own NSDateFormatter
NSDateFormatter *dateFormatter = [NSDateFormatter new];
[dateFormatter  setDateFormat:@"yyyy-MM-dd"];
dateFormatter.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"UTC"];
dateFormatter.locale = [[[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"] autorelease];

[RKObjectMapping addDefaultDateFormatter:dateFormatter];
[dateFormatter release];

// Using the Convenience Methods
NSTimeZone *EST = [NSTimeZone timeZoneWithAbbreviation:@"EST"];
[RKObjectMapping addDefaultDateFormatterForString:@"yyyy-MM-dd" inTimeZone:EST];

Setting the Preferred Output Date Formatter

This will control how dates are outputted into your generated JSON/form encoded output.

NSDateFormatter *dateFormatter = [NSDateFormatter new];
[dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss Z"];
dateFormatter.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"UTC"];
dateFormatter.locale = [[[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"] autorelease];

// Set it Globally
[RKObjectMapping setPreferredDateFormatter:dateFormatter];

// Or for a Particular Object Mapping
someObjectMapping.preferredDateFormatter = dateFormatter;