Friday, March 28, 2008

How to hack iphone locales

You may already seen out there some projects that translates the iPhone user interface to many different languages. Locale strings are stored in a totally different way though. Things like "Monday" and the Portuguese equivalent "Segunda-Feira" are stored in a ICU (International Components for Unicode) data file.

For 12 mondays I had to stand looking at "Segunda-Feira" being printed out of the bounds of iCal icon. Until today. I tried fgrep'ng the whole iPhone for the string "segunda" with no luck. Then I tried converting all the plists from binaries to XML and fgrep'ng again and still no luck. Doing some research I found that apple uses ICU on iPhone, which drove me to find our target: /usr/share/icu/icudt34l.dat. This is a 8.5MB file bundled with all the locales (timezones, region formats, etc.).

To start playing with it, the first thing we will need is obviously the file itself:
cd /tmp
ssh root@iPhone cp /usr/share/icu/icudt34l.dat /usr/share/icu/icudt34l.dat.bak
scp root@iPhone:/usr/share/icu/icudt34l.dat .
Now we need the ICU version 3.4 tools. Again, I don't like macports or fink so I had a bad time trying to compile it myself (remember I am on a Mac OS X Leopard). You have now the cake recipe:
cd /usr/src
wget ftp://ftp.software.ibm.com/software/globalization/icu/3.4.1/icu-3.4.1.tgz
tar -zxf icu-3.4.1.tgz
mv icu icu-3.4.1
cd icu-3.4.1/source
For some weird reason the configure script for darwin is broken, so I had to fix that with the following patch:
--- config/mh-darwin 2004-05-18 18:54:24.000000000 -0300
+++ config/mh-darwin.new 2008-03-27 23:48:45.000000000 -0300
@@ -58,6 +58,7 @@
@echo "generating dependency information for $<" @$(GEN_DEPS.c) $< > /dev/null
@mv $@ $@~
- @echo -n "$@ " > $@
@cat < $@~ >> $@
@-rm $@~

@@ -65,6 +66,7 @@
@echo "generating dependency information for $<" @$(GEN_DEPS.cc) $< >/dev/null
@mv $@ $@~
- @echo -n "$@ " > $@
@cat < $@~ >> $@
@-rm $@~
Now we can run configure:
./runConfigureICU MacOSX --disable-samples --disable-draft --disable-extras --disable-tracing --disable-tests
and make it:
make
sudo make install
I couldn't manage to get file from bin/ installed on my system, but anyway I wasn't really interested on going deeply on that. Heck, I want to get rid of that "Segunda-Feira" thing !

Lets extract our package now:
cd /tmp
/usr/src/icu-3.4.1/source/bin/decmn icudt34l.dat --pkgdata > out.lst
cd icudt34l
boom ! we got a lot of files... and look who is laying around:
-rw-r--r-- 1 igor wheel 51K Mar 28 00:14 pt.res
-rw-r--r-- 1 igor wheel 496B Mar 27 23:06 pt_BR.res
-rw-r--r-- 1 igor wheel 3.7K Mar 27 23:06 pt_PT.res
The file we want is pt.res, but its a binary file. I couldn't manage to convert it back to something readable but again I am more interested in the quickest solution possible. Just download the pt.txt here. Near to the end you will find the calendar day names. Edit accordingly. Important: remember to use UTF-8.

Now its time to generate our new resource:
/usr/src/icu-3.4.1/source/bin/genrb pt.txt
and re-package:
/usr/src/icu-3.4.1/source/bin/gencmn -v -n icudt34l 0 < ../out.lst
At this point you cross your fingers and hope this works... worked for me :)
scp icudt34l.dat root@iPhone:/usr/share/icu
reboot and you are all set.

If you can read Portuguese you might find this entry interesting as well. It describes the similar process of updating Mac OS X timezone. It makes use of `icupkg` though, that is not available on ICU version 3.4.

7 comments :

not a big deal said...

hi igor,

i also use the portuguese locale, and in the locked screen i get 'terça-feira, 1 de abr' instead of 'terça-feira, 1 de abril'. Do you have the same issue? Do you have any workaround?

i checked the pt.txt file you've posted and the DateTimePatterns seem ok, i don't even see a "EEEE, d' de 'MMM' de 'yyyy" pattern that it could be wrongly using.

any help appreciated

marco v

iGor Feghali said...

Hello Marco,

Confirmed on my 1.1.4. Weird it shows "Thursday, April 3" for English Locale. I am trying to fix that. Stay tunned.

not a big deal said...

that was what bugged me. the date format should be the same accross locales. so i wondered if the pt locale file had the wrong patterns or wrong month names, but apparently (based on the file you posted) it doesn't.

thank you for looking this up. cheers

iGor Feghali said...

surely its not an issue in the ICU database. I had replaced the PT resource file with the EN file resulting in "Saturday, 5 de Apr". That must be hardcoded somewhere else in the phone.

not a big deal said...

ok, thanks for looking in to it anyway

Alvaro said...

I would like to know a solution for this problem...
It's very weird to see "terça-feira, 1 de abr"...

John Smith said...

Have you managed to do the same with the 2.0 software?