zh-Hans, zh-Hant and the "old" zh-CHS, zh-CHT

With Windows Vista and Microsoft .Net 2.0 (MS07-040 security patch) and 3.0+, we've started to use the IETF standard "zh-Hans", and "zh-Hant" names for Chinese simplified and traditional.  In windows the zh-CHS/zh-CHT names were never used because the named APIs are new to Vista.  Also in Silverlight we don't use the old names since Silverlight is new.

However in .Net 2.0/3.x we still recognize zh-CHS & zh-CHT for backwards compatibility.  Additionally we prefer the "old" zh-CHS and zh-CHT names when enumerating or returning the name of a CultureInfo created by LCID (0x0004 or 0x7c04)  The other oddity is that to recognize more resources, we made the parent of zh-CHS/zh-CHT be zh-Hans/zh-Hant. 

This allows resources labeled zh-Hans or zh-Hant (the preferred name) to be loaded by systems that used the older zh-CHS/zh-CHT names.  Unfortunately they can't be parents of each other, so this resource fallback only works one direction.  You cannot normally find zh-CHS resources if you start with a zh-Hans locale.  So the recommendation is to use zh-Hans/zh-Hant when creating resources.

In the future (like v4+, we're not sure when) zh-CHS/zh-CHT will no longer be recognized by default.  Users will still be able to create zh-CHS/zh-CHT custom cutlures if necessary to workaround legacy naming related issues, similar to the way you can make an az-AZ-Latn now to work around that name change.


Comments (6)
  1. I was asked if this means that users should start using zh-Hant/zh-Hans for their resource names now.  The answer is a qualified yes.  Qualified because you may have callers using the old names or tools that aren’t expecting the new names making it more difficult.

  2. ptenn says:


    I’ve been reading through your blog, and wanted to ask you a few questions since you’re definitely an expert (and probably wrote some of the FCL classes I’m using) in the .NET Localization arena.

    Please be patient with me if I’m a bit unfamiliar with some core .NET concepts … I’m a longtime Java developer who just recently started getting into .NET.

    I’m building a site that currently supports Chinese (Simplified) and English: http://www.zendear.com.  I’m using RESX files and URL rewriting.  I want to also support Traditional Chinese.

    1.  Is there a way I can "reuse" my Simplified Chinese RESX files instead of having to copy them, convert them to Traditional Chinese?  My main reason for wanting to do so is to maintain less code.  

    For example, the login page:


    Has 2 RESX files:

    – login.aspx.resx

    – login.aspx.zh-CHS.resx

    Going to the Chinese version:


    Just does a URL rewrite back to login.aspx and provides query string parameters telling the page to use Simplified Chinese.

    I could copy login.aspx.zh-CHS.resx to login.aspx.zh-CHT.resx and convert the file.  However, this will mean I have a bunch of extra RESX files to maintain (probably an additional 50 in all) and keep in synch.

    Since conversion from Simplified to Traditional Chinese is a pretty automatic process (I have a Word Processor that you can just switch between the two), I’m wondering if

    2.  I’m on .NET Framework 2.0.  I noticed in the MSDN doc:


    that I need to use zh-CHS and zh-CHT.

    However, on the new .NET Framework 3.5, it specifies zh-Hans and zh-Hant (and doesn’t list the zh-CHS/zh-CHT).  

    If I start using zh-Hans/zh-Hant BEFORE upgrading to .NET 3.5, will it break my application?  

    Also, if I upgrade to .NET 3.5 BEFORE refactoring my code to use zh-Hans/zh-Hant, does that mean that my app will break?  

    I’m trying to figure out whether or not the upgrade to .NET 3.5 and code refactor (zh-CHS to zh-Hans) need to go together, and if they can go separate, the best migration plan.

    Thank you for your time,

    Philip Tenn


  3. In .Net 3.5 it should recognize both the "old" and the "new" names, so if you use the "new" names, then requests with the old names should still work to load resources.

    I don’t deal with the resx files very much, but I think you need to have 2 copies, and I don’t know of an automagical way to convert between the simplified and traditional.

    If they were identical (maybe like zh-CHS and zh-Hans), then I’d wonder about using a hard-link in the file system, but since your files differe that isn’t an option.

  4. Hi,

    I have an issue with an application that I’m working on.  When I specify:

    Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture( "zh-Hans" );

    I receive the following error message:

    "Please select a specific culture, such as zh-CN, zh-HK, zh-TW, zh-MO, zh-SG."

    If I specify the culture like this,

    Thread.CurrentThread.CurrentUICulture = new CultureInfo( "zh-Hans" );

    I no longer receive the error message but I also end up with the english version at runtime.  I have renamed the Resource file so that’s not the issue.

    If I specify zh-CN with either method above, the resources load fine and all is well.  Any ideas as to what might be the trouble here?  I’ve tried using the legacy simplified chinese culture in the CreateSpecifiedCulture method and it barfs too.

  5. percyboy says:

    to Thomas Goddard :

    "zh-Hans" is not a specific culture. It is only a language, just like the old "zh-CHS".

  6. percyboy says:

    to ptenn:

    there is currently no stable or reliable auto translate systems or tools between Simplified and Traditional Chinese. So you should consider to create seperate resources for each of them.

Comments are closed.

Skip to main content