<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>MultiNC &#187; france</title>
	<atom:link href="http://multinc.com/tag/france/feed/" rel="self" type="application/rss+xml" />
	<link>http://multinc.com</link>
	<description>Explorations in Social Computing</description>
	<lastBuildDate>Wed, 09 Dec 2009 19:05:54 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>iPhone SDK time bug for international users</title>
		<link>http://multinc.com/2009/09/27/iphone-sdk-time-bug-for-international-users/</link>
		<comments>http://multinc.com/2009/09/27/iphone-sdk-time-bug-for-international-users/#comments</comments>
		<pubDate>Sun, 27 Sep 2009 07:00:39 +0000</pubDate>
		<dc:creator>huy</dc:creator>
				<category><![CDATA[Huy dev]]></category>
		<category><![CDATA[iPhone dev]]></category>
		<category><![CDATA[apple]]></category>
		<category><![CDATA[bug]]></category>
		<category><![CDATA[france]]></category>
		<category><![CDATA[globalization]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[iPhone SDK]]></category>
		<category><![CDATA[NSDateFormatter]]></category>

		<guid isPermaLink="false">http://multinc.com/?p=183</guid>
		<description><![CDATA[If your application is acting strange when your users are switching between 12-hour and 24-hour mode in their iPhone settings, you may be experiencing the same thing we are: an NSDateFormatter bug in the iPhone SDK 3.1 (or earlier).
MultiNC develops iPhone applications for a number of global markets, and sometimes we run into bugs unique [...]]]></description>
			<content:encoded><![CDATA[<p>If your application is acting strange when your users are switching between 12-hour and 24-hour mode in their iPhone settings, you may be experiencing the same thing we are: an NSDateFormatter bug in the iPhone SDK 3.1 (or earlier).</p>
<p>MultiNC develops iPhone applications for a number of global markets, and sometimes we run into bugs unique to globalized applications.  One application that we&#8217;re developing has France as primary market.  U.S. users very rarely change their settings from the usual 12-hour mode (AM/PM mode) to 24-hour mode.  However, in France it&#8217;s not rare for users to switch from the more common 24-hour mode to 12-hour mode.  And that&#8217;s when things start acting strange, even causing your application to crash.</p>
<p>Because of users&#8217; regional habits, developers of globalized applications are more likely to encounter this time bug than for US applications.</p>
<h2>Region format &amp; 24-hour mode setting</h2>
<p>First, a little background on the iPhone user interface.  When iPhone users change their region format between, say, &#8220;United States&#8221; and &#8220;France&#8221;, the users&#8217; &#8220;24-Hour Time&#8221; setting is automatically switched to the mode that is most prevalent in that region.  In France, that would set 24-Hour Time to &#8220;ON&#8221;, and in the U.S., that would set it to &#8220;OFF&#8221;.  The users can then manually override that setting and that&#8217;s where trouble starts.</p>
<h2>NSDateFormatter bug</h2>
<p>The pattern of this SDK bug was relatively tricky to determine because of the specific combination and sequence of user settings that would trigger it, but now it&#8217;s actually quite simple to explain.</p>
<p>The problem comes from NSDateFormatter somehow &#8220;getting stuck&#8221; in the 12 or 24-hour time mode that the user has manually selected.  So if a French user manually selects 12-hour mode,  and the application requested NSDateFormatter to output time with the 24-hour format &#8220;HHmm&#8221;, it would actually receive time in a 12-hour format, e.g. &#8220;01:00 PM&#8221;, as if the application had instead requested &#8220;hhmm aa&#8221;.  The reverse would happen if a US user manually selected 24-hour mode: outputting time with the 12-hour  format &#8220;hhmm aa&#8221; would actually get you time in the 24-hour format instead, e.g. &#8220;17:00&#8243;.</p>
<p>This bug turns especially nasty when your application is trying to parse time from a string, rather than outputing.  Similar to the above, the NSDateFormatter seems to be stuck in the time mode that the user has manually chosen and insists on reading time that way, regardless of the string format.  What you can end up with is an incomplete or invalid NSDate, which when later used can cause other parts of the application to crash, as the UIDatePicker did for us.</p>
<p>We are developing with the iPhone SDK version 3.1 beta, but we wouldn&#8217;t be surprised if it applied to all previous SDKs.</p>
<h2>Workaround</h2>
<p>Now that you know the source of the bug, a workaround is straightforward.  But to save you time until Apple fixes it, with our client <a href="http://www.fabernovel.com/">faberNovel</a>&#8217;s gracious permission, here&#8217;s our workaround when dealing in 24-hour time (dealing in 12-hour time would be very similar):</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// Returns time string in 24-hour mode from the given NSDate</span>
<span style="color: #002200;">+</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>time24FromDate<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSDate</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>date withTimeZone<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSTimeZone</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>timeZone
<span style="color: #002200;">&#123;</span>
	<span style="color: #400080;">NSDateFormatter</span> <span style="color: #002200;">*</span>dateFormatter<span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSDateFormatter</span> alloc<span style="color: #002200;">&#93;</span> init<span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#91;</span>dateFormatter setDateFormat<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;HH:mm&quot;</span><span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#91;</span>dateFormatter setTimeZone<span style="color: #002200;">:</span>timeZone<span style="color: #002200;">&#93;</span>;
	<span style="color: #400080;">NSString</span><span style="color: #002200;">*</span> <span style="color: #a61390;">time</span> <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>dateFormatter stringFromDate<span style="color: #002200;">:</span>date<span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#91;</span>dateFormatter release<span style="color: #002200;">&#93;</span>;
&nbsp;
	<span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">time</span>.length &gt; <span style="color: #2400d9;">5</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
		<span style="color: #a61390;">NSRange</span> range;
		range.location <span style="color: #002200;">=</span> <span style="color: #2400d9;">3</span>;
		range.length <span style="color: #002200;">=</span> <span style="color: #2400d9;">2</span>;
		<span style="color: #a61390;">int</span> hour <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #a61390;">time</span> substringToIndex<span style="color: #002200;">:</span><span style="color: #2400d9;">2</span><span style="color: #002200;">&#93;</span> intValue<span style="color: #002200;">&#93;</span>;
		<span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span>minute <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #a61390;">time</span> substringWithRange<span style="color: #002200;">:</span>range<span style="color: #002200;">&#93;</span>;
		range <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #a61390;">time</span> rangeOfString<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;AM&quot;</span><span style="color: #002200;">&#93;</span>;
		<span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>range.length<span style="color: #002200;">==</span><span style="color: #2400d9;">0</span><span style="color: #002200;">&#41;</span>
			hour <span style="color: #002200;">+=</span> <span style="color: #2400d9;">12</span>;
		<span style="color: #a61390;">time</span> <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSString</span> stringWithFormat<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;%02d:%@&quot;</span>, hour, minute<span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#125;</span>
&nbsp;
	<span style="color: #a61390;">return</span> <span style="color: #a61390;">time</span>;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #11740a; font-style: italic;">// Returns a proper NSDate given a time string in 24-hour mode</span>
<span style="color: #002200;">+</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSDate</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>dateFromTime24<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>time24String withTimeZone<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSTimeZone</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>timeZone
<span style="color: #002200;">&#123;</span>
	<span style="color: #a61390;">int</span> hour <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>time24String substringToIndex<span style="color: #002200;">:</span><span style="color: #2400d9;">2</span><span style="color: #002200;">&#93;</span> intValue<span style="color: #002200;">&#93;</span>;
	<span style="color: #a61390;">int</span> minute <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>time24String substringFromIndex<span style="color: #002200;">:</span><span style="color: #2400d9;">3</span><span style="color: #002200;">&#93;</span> intValue<span style="color: #002200;">&#93;</span>;
	<span style="color: #400080;">NSDateFormatter</span> <span style="color: #002200;">*</span>dateFormatter<span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSDateFormatter</span> alloc<span style="color: #002200;">&#93;</span> init<span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#91;</span>dateFormatter setTimeZone<span style="color: #002200;">:</span>timeZone<span style="color: #002200;">&#93;</span>;	
&nbsp;
	<span style="color: #400080;">NSDate</span> <span style="color: #002200;">*</span>result;
	<span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">&#91;</span>Util userSetTwelveHourMode<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
		<span style="color: #002200;">&#91;</span>dateFormatter setDateFormat<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;hh:mm aa&quot;</span><span style="color: #002200;">&#93;</span>;
		<span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>hour &gt; <span style="color: #2400d9;">12</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
			result <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>dateFormatter dateFromString<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSString</span> stringWithFormat<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;%02d:%02d PM&quot;</span>, hour <span style="color: #002200;">-</span> <span style="color: #2400d9;">12</span>, minute<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
		<span style="color: #002200;">&#125;</span> <span style="color: #a61390;">else</span> <span style="color: #002200;">&#123;</span>
			result <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>dateFormatter dateFromString<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSString</span> stringWithFormat<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;%02d:%02d AM&quot;</span>, hour, minute<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
		<span style="color: #002200;">&#125;</span>
	<span style="color: #002200;">&#125;</span> <span style="color: #a61390;">else</span> <span style="color: #002200;">&#123;</span>
		<span style="color: #002200;">&#91;</span>dateFormatter setDateFormat<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;HH:mm&quot;</span><span style="color: #002200;">&#93;</span>;
		result <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>dateFormatter dateFromString<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSString</span> stringWithFormat<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;%02d:%02d&quot;</span>, hour, minute<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#125;</span>
	<span style="color: #002200;">&#91;</span>dateFormatter release<span style="color: #002200;">&#93;</span>;
&nbsp;
	<span style="color: #a61390;">return</span> result;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #11740a; font-style: italic;">// Tests whether the user has set the 12-hour or 24-hour mode in their settings.</span>
<span style="color: #002200;">+</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">BOOL</span><span style="color: #002200;">&#41;</span>userSetTwelveHourMode
<span style="color: #002200;">&#123;</span>
	<span style="color: #400080;">NSDateFormatter</span> <span style="color: #002200;">*</span>testFormatter <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSDateFormatter</span> alloc<span style="color: #002200;">&#93;</span> init<span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#91;</span>testFormatter setTimeStyle<span style="color: #002200;">:</span>NSDateFormatterShortStyle<span style="color: #002200;">&#93;</span>;
	<span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span>testTime <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>testFormatter stringFromDate<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSDate</span> date<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#91;</span>testFormatter release<span style="color: #002200;">&#93;</span>;
	<span style="color: #a61390;">return</span> <span style="color: #002200;">&#91;</span>testTime hasSuffix<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;M&quot;</span><span style="color: #002200;">&#93;</span> || <span style="color: #002200;">&#91;</span>testTime hasSuffix<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;m&quot;</span><span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #11740a; font-style: italic;">// Converts a 24-hour time string to 12-hour time string</span>
<span style="color: #002200;">+</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>time12FromTime24<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>time24String
<span style="color: #002200;">&#123;</span>
	<span style="color: #400080;">NSDateFormatter</span> <span style="color: #002200;">*</span>testFormatter <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSDateFormatter</span> alloc<span style="color: #002200;">&#93;</span> init<span style="color: #002200;">&#93;</span>;
	<span style="color: #a61390;">int</span> hour <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>time24String substringToIndex<span style="color: #002200;">:</span><span style="color: #2400d9;">2</span><span style="color: #002200;">&#93;</span> intValue<span style="color: #002200;">&#93;</span>;
	<span style="color: #a61390;">int</span> minute <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>time24String substringFromIndex<span style="color: #002200;">:</span><span style="color: #2400d9;">3</span><span style="color: #002200;">&#93;</span> intValue<span style="color: #002200;">&#93;</span>;
&nbsp;
	<span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span>result <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSString</span> stringWithFormat<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;%02d:%02d %@&quot;</span>, hour <span style="color: #002200;">%</span> <span style="color: #2400d9;">12</span>, minute, hour &gt; <span style="color: #2400d9;">12</span> ? <span style="color: #002200;">&#91;</span>testFormatter PMSymbol<span style="color: #002200;">&#93;</span> <span style="color: #002200;">:</span> <span style="color: #002200;">&#91;</span>testFormatter AMSymbol<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#91;</span>testFormatter release<span style="color: #002200;">&#93;</span>;
	<span style="color: #a61390;">return</span> result;
<span style="color: #002200;">&#125;</span></pre></div></div>

<h3>References:</h3>
<ul>
<li>StackOverflow &#8211; <a href="http://stackoverflow.com/questions/143075/nsdateformatter-am-i-doing-something-wrong-or-is-this-a-bug">NSDateFormatter, am I doing something wrong or is this a bug?</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://multinc.com/2009/09/27/iphone-sdk-time-bug-for-international-users/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
