Author Archive: Masa Hokari

Formatting with alternate calendars in Flex

This article was originally written in English. Text in other languages was provided by machine translation.

Dates can be formatted in various calendars in the Flex SDK. Let’s explore how it works.

Flex SDK lets you format a given date in “alternate calendars” besides the Gregorian calendar. The industry convention refers all non-Gregorian calendars as alternate calendars. To use an alternate calendar, it requires a little bit of care in your Flex application.

Types of calendars

Before we dive into the alternate calendar usages in the Flex SDK, let’s take a brief look at a couple of calen­dars of the world so that you get familiar with what this calendar talk is about. Please be aware, I can only describe the basic usages of some common alternate calendars. There are complexities behind each of the calendars and I may not be explicitly state them. Investigate fur­ther before you actually use them.

Gregorian calendar

This is the calendar most systems provide as the standard. You probably know this calendar already but here are some of the characteristics: There are always twelve months in a year and each month has 28 to 31 days. The numbers of days in each of the months are fixed (30 or 31 days) except for the second month (February), which includes 28 (non-leap years) or 29 days (leap years). The number of days in a year is fixed (365 or 366 days).

Islamic calendar (Hijri calendar)

Islamic calendar is one of the lunar calendars.  There are always twelve months in a year. Each month has ei­ther 29 or 30 days. Beginning of a month is determined by observing the moon phase (Islamic religious calendar). Because of this nature, it is not very possible to predict the dates with the Islamic religious calendar. For the sake of convenience, there is the variant of the calendar, Islamic civil calendar, which determines the dates through some pure mathematical calculation. Islamic civil calendar may not be accurate for religious events. Number of days in a year is 354 or 355 days. Hence, the Islamic calendar year and the Gregorian calendar year are not synchronized.

Japanese calendar

Japanese calendar is very similar with the Gregorian calendar. The difference is the era part and the year. The Gregorian calendar has been using the same era name for the past 2,000 years (AD; Anno Domini). There is also BC (Before Christ) era but BC years are not by supported by pretty much all calendar apps. On the other hand, Japanese calendar era name changes when there is new emperor. Therefore, every ten to a couple of ten years, there are new eras. *1

*1 Before the 1868, the era name changes were more frequent, an era lasted only as low as two years. But just like the BC in Gregorian, there is not much demand to be able to deal with the older eras in today’s calendar applica­tions.

There are much more types of calendars in the world but I hope you got some ideas how calendars can vary.

How to use the alternate calendars in Flex SDK

Now let’s look at the usage of alternate calendars. How do you use calendar other than the Gregorian in the Flex SDK? The an­swer is to use the locale ID.

The locale ID can optionally contain calendar tag. For example:

Locale ID Meaning
ar-SA Arabic used in Saudi Arabia
ar-SA@calendar=islamic Arabic used in Saudi Arabia. Islamic calendar
en-US@calendar=islamic English used in the U.S. Islamic calendar.

When you need to format a date in an alternate calendar, the calendar tag can be appended to the locale ID. Here is an example:

import spark.formatters.DateTimeFormatter;
private function calendarDemo():void
{
    var d:Date = new Date(2011, 9, 15);
    var dtf:DateTimeFormatter = new DateTimeFormatter();
    dtf.dateStyle = "long";
    dtf.timeStyle = "none";
 
    dtf.setStyle("locale", "en-US");
    trace("(1) " + dtf.format(d));
 
    dtf.setStyle("locale", "ar-SA");
    trace("(2) " + dtf.format(d));
 
    dtf.setStyle("locale", "ja-JP");
    trace("(3) " + dtf.format(d));
 
    dtf.setStyle("locale", "en-US@calendar=islamic");
    trace("(4) " + dtf.format(d));
 
    dtf.setStyle("locale", "ar-SA@calendar=islamic");
    trace("(5) " + dtf.format(d));
 
    dtf.setStyle("locale", "en-US@calendar=japanese");
    trace("(6) " + dtf.format(d));
 
    dtf.setStyle("locale", "ja-JP@calendar=japanese");
    trace("(7) " + dtf.format(d));
}

Here is the result you might get.

Please note that the result may vary depending on the run-time platforms.

Limitations you should be aware of

There are couples of limitations in the current Flash Player and Flex SDK for alternate calendar support.

  1. The Date class can handle only Gregorian dates.
  2. The Spark DateTimeFormatter class can format a Date object but parsing feature (translating a formatted Gregorian or non-Gregorian date string into a Date object) is not available. English Gregorian date string can be parsed through the Date class constructor in some degree.
  3. The availability of alternate calendar support and its behavior is platform dependent. Please check the plat­form if the alternate calendar support is important for your application.

If you would like to know more about alternate calendars, the calendar entries on Wikipedia is a good source.

Difference between Flex SDK’s Matching Collator and Sorting Collator

This article was originally written in English. Text in other languages was provided by machine translation.

Flex SDK has two kinds of collators. Do you know the differences?

First of all, let me explain what a Collator is. The Flex SDK Collators are classes that are designed to compare two strings. Their compare functions return a numeric value to tell which of the two items is smaller or larger.

Here is an example:

<fx:Declarations>
    <s:SortingCollator id="c1"/>
    </fx:Declarations>
    <s:VGroup>
        <s:TextInput id="uiInput1" text="ABC"/>
        <s:TextInput id="uiInput2" text="ABC"/>
        <mx:Text id="uiOutput" text="{c1.compare(uiInput1.text, uiInput2.text)}"/>
    </s:VGroup>

This example shows 0 as the compare result by default. As you alter the inputs, the result becomes -1 if the first input is smaller or 1 if larger. See the screenshots below.

 width=

 width=

 width=

The difference in sorting

Now, let’s talk about the differences of Matching and Sorting Collators. Actually, they are essentially same but they have given some specific initial collation parameters good for general string matching (MatchingCollator) or parameters good for general string sorting (SortingCollator). Example below illustrates why two different collators are useful.

Assume you have following items in your Array. You want to sort the items and find a specific string from the items.

  • naïve
  • Naïve
  • NAÏVE
  • naive
  • Naive
  • NAIVE
  • adolescent
  • youthful

If you sort items using a SortingCollator class with “en_US” (English spoken in U.S.) locale, you get following sort result.

  • adolescent
  • naive
  • Naive
  • NAIVE
  • naïve
  • Naïve
  • NAÏVE
  • youthful

This ordering makes sense for most usages. (At least that is what we have hoped.) Lowercase letters come first over upper cases; letters without accent come first over ones with accent.

On the other hand, if you sort the items using a MatchingCollator, you get following result. (Result may vary as some attributes are ignored.)

  • adolescent
  • Naïve
  • NAÏVE
  • naive
  • naïve
  • NAIVE
  • Naive
  • youthful

You may notice that upper/lowercase ordering and accent character ordering are not consistent with a MatchingCollator class. In fact, the MachingCollator class is not designed for sorting.

The difference in matching

Now, assume you want to search a specific string, “naive“, from the list. With a SortingCollator class, you get following result:

  • naive

Yes, only one string with a SortingCollator class.

On the other hand, with a MatchingCollator class, you get following result.

  • Naïve
  • NAÏVE
  • naive
  • naïve
  • NAIVE
  • Naive

As you can see, the string comparison was done in more lenient manner with MatchingCollator class. Often such leniency is desired when searching strings.

Although SortingCollator and MatchingCollator behave differently as you have seen above, those classes are pretty much same underneath. In fact, they can mute to the other sibling by setting their properties. If you need to control more details of sorting/matching behavior, you also manipulate the properties. Please see the Flex SDK references for more details.

References

The example program used in this article

<?xml version="1.0" encoding="utf-8"?>
   <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
   >
   <fx:Declarations>
      <s:SortingCollator id="sortingCollator" locale="en_US"/>
      <s:MatchingCollator id="matchingCollator" locale="en_US"/>
      <s:Sort id="sort"/>
      <s:ArrayCollection id="arrayCollection" sort="{sort}" source="{wordList}"/>
   </fx:Declarations>
   <fx:Script>
      <![CDATA[
         private static const wordList:Array = [
            "naïve", "Naïve", "NAÏVE",
            "naive", "Naive", "NAIVE",
            "adolescent", "youthful" ];
         private function setCollator(useSortingCollator:Boolean):void
         {
            const collator:Object = useSortingCollator ?
            sortingCollator : matchingCollator;
            sort.compareFunction = function (a:Object, b:Object, fields:Array):int
               { return collator.compare(a as String, b as String); }
            arrayCollection.refresh();
            uiResult.text = "Sort Result:n" + arrayCollection.toString();
            uiResult.text += "nnStinrgs equal to 'naive' are:n";
            for (var i:uint = 0; i < arrayCollection.length; i++)
            {
               if (!collator.compare(arrayCollection[i], "naive"))
               uiResult.text += arrayCollection[i] + "n";
            }
         }
      ]]>
   </fx:Script>
   <s:VGroup paddingTop="20" paddingBottom="20"
         paddingLeft="20" paddingRight="20" height="100%">
      <s:Button label="Use SortingCollator" click="setCollator(true)"/>
      <s:Button label="Use MatchingCollator" click="setCollator(false)"/>
      <s:TextArea id="uiResult" height="100%"/>
   </s:VGroup>
    </s:Application>

The differences of three globalization packages in Flash platform

This article was originally written in English. Text in other languages was provided by machine translation.

Developers who are looking at the Flex SDK Hero releases noticed that we have three NumberFormatters (and other globalization-related classes) in the Flash Platform. If you’re wondering why, here’s the explanation.

The Flash platform has the following sets of globalization-related classes for different use cases.

  1. flash.globalization: Flash Player built-in
  2. mx.formatters: Flex SDK MX namespace
  3. spark.formatters/validators/globalization: Flex SDK Spark namespace

The flash.globalization package is implemented as native code in the Flash Player. As with other player classes such as Sprite, you link against playerglobal.swc or airglobal.swc to use it. This package is a recent addition to Flash Player. You need Flash Player 10.1 or AIR 2.0 (or newer versions of these) and a corresponding version of playerglobal.swc or airglobal.swc. They utilize the globalization features provided by the underlying operating system rather than using Flex’s ResourceManager. Therefore you can use any locale supported by the OS, not just the locales for which you built your application. However, these player APIs can produce different results on different platforms. For example, a Greek date might get formatted differently on Macintosh, Windows, Android, etc.

The second set of the globalization classes is provided by the Flex SDK and in the MX namespace. Actually, this MX set is the first globalization classes we provided in the Flash platform. The MX globalization classes provide some formatters for such as number, currency, date and so on. These classes use very limited locale information in the ResourceManager. If you want to do Greek formatting, you have to have Greek resource bundles (which Adobe doesn’t currently provide, although it does provide 16 other locales). Also, locale-aware collation and case conversion were not offered by these classes.

The third set of the globalization classes is also provided by the Flex SDK (beginning with version 4.5) and in the Spark namespace. This is our latest addition in terms of globalization classes. This set acts as glue between the flash.globalization features and the Flex SDK. This Flex Spark version has some advantage compared to the built-in Flash Player globalization features. In particular, they are about the compliance with the MXML syntax and the style inheritance. Those are indeed necessary to make the globalization feature as a part of the Flex SDK UI infrastructure.

Here is a summary comparing the three APIs:

Item Flash Player built-in globalization feature Flex  SDK MX globalization feature Flex SDK Spark globalization feature
Namespace flash.globalization mx.formatters and mx.validators spark.globalization, spark.formatters, spark.validators and others
Required minimum Flex SDK version N/A Flex 3 Flex 4.5
Required minimum Flash Player version Flash Player 10.1
AIR 2
Flash Player 9
AIR 1.1
Flash Player 10.1
AIR 2
Number formatter Yes Yes Yes
Currency formatter Yes Yes Yes
Date time formatter Yes Yes Yes
Number validator No Yes Yes
Currency validator No Yes Yes
Collator Yes No Yes
UI support N/A No

Yes

(DataGrid, Sort, SortField)

Supported locales Depends on underlying OS 16 Depends on underlying OS
Use in MXML No Yes Yes
Use in Script Yes Yes Yes
Locale style inheri­tance N/A No Yes

References

  • flash.globalization package document

http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/globalization/package-detail.html

  • Flex SDK mx.formatters package document

http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/formatters/package-detail.html

  • Flex SDK mx.validators package document

http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/validators/package-detail.html

  • Flex SDK Hero (Beta) spark.globalization package document

http://help.adobe.com/en_US/FlashPlatform/beta/reference/actionscript/3/spark/globalization/package-detail.html

  • Flex SDK Hero (Beta) spark.formatters package document

http://help.adobe.com/en_US/FlashPlatform/beta/reference/actionscript/3/spark/formatters/package-detail.html

  • Flex SDK Hero (Beta) spark.validators package document (Not yet available as of the writing)

http://help.adobe.com/en_US/FlashPlatform/beta/reference/actionscript/3/spark/validators/package-detail.html

New Globalization Features in Flex SDK “Hero”

This article was originally written in English. Text in other languages was provided by machine translation.

 

In June of this year, Flash® Player 10.1, was released that contained a new set of ActionScript classes which aid the creation of applications that support multiple languages and regions. The new classes were put in the flash.globalization package and they provide language and region specific formatting of dates, times, numbers, and currencies as well as alanguage specific sorting and conversion between uppercase and lowercase letters. The classes use the underlying capabilities of the operating system that Flash Player is running on. Therefore Flash based applications can be created that have locale support that is the same as provided by the operating system. Since these classes are built into the player, they can be used with native ActionScript code by applications built with either Flash Professional or with applications that use the Flex SDK. This version of the Flash Player was also incorporated into Adobe AIR version 2.0 and thus both browser based applications and AIR applications can make use of this new functionality.

During the Adobe Max 2010, the Flex SDK Hero preview release was made available to the conference attendees as well as posted on the Adobe Labs website. Hero is the code-name for the next version of the Flex SDK. Hero reflects the next step in making improvements to the Flex ecosystem for creating world ready applications. This release incorporates a new set of classes that make use of the flash.globalization package available in Flash Player 10.1. These new classes make it easier to use the flash.globalization functionality in MXML declarations and provide a way to set a common locale to be used by the entire application or portions of the application.

The new classes in the Flex SDK have been added to two new packages:

  • spark.formatters package contains NumberFormatter, CurrencyFormatter, and DateTimeFormatterclasses
  • spark.globalization package contains SortingCollator, MatchingCollator, and StringTools classes

Those of you familiar with Flex, will know that it already contains a set of formatters and validators in the mx namespace. These mx formatters have not been modified in the Hero version of the Flex SDK and they still behave as earlier versions of the Flex SDK. The main difference between these two sets of formatters is that the new spark formatters make use of the formatting functionality provided by the operating system (via the flash.globalization package) where as the MX formatters use the ResourceManager and resource bundles for the locale specific data used in formatting. The Flex SDK is delivered with data for a limited set of locales for the mx formatters. On the other hand, depending on the operating system, the new spark formatters may have access to hundreds of locales. Additionally the new spark formatters also have access to the end user’s international preferences and settings or custom locales that they may have installed on their operating system.

The language specific string comparison capability provided by the flash.globalization classes and the new spark SortingCollator and MatchingCollator classes are also new in the Hero version of the Flex SDK. This linguistically correct comparison is critical when displaying lists of strings to a user.

Unlike the flash.globalization classes, the new spark classes can be declared in the <fx:Declarations> section of an MXML file and by default they determine the locale from the “locale” style. The locale identifies the language, script, region and optionally other values that impact the behavior of these classes. When the locale style is updated, the spark classes will generate change events that can be used when binding the results to the property of a UIComponent or other binding target.

Here is an example of how the NumberFormatter and DateTimeFormatter might be used:

<fx:Declarations>
	<s:NumberFormatter id="nf" fractionalDigits="0"/>
	<s:DateTimeFormatter id="df" dateStyle="long" timestyle="none"/>
</fx:Declarations>
<mx:Text text="{nf.format(myNumCandles)}"/>
<mx:Text text="{df.format(myBirthday)}"/>

and here is an example of how the SortingCollator might be used:

<fx:Declarations>
	<s:SortingCollator id="sc"/>
</fx:Declarations>
<mx:DataGrid id="dg">
	<mx:columns>
		<mx:DataGridColumn sortCompareFunction="{sc.compare}"/>
	</mx:columns>
</mx:DataGrid>

In both of these cases, the locale is inherited from the application, module, or component that includes the declarations. The locale is set using a style declaration or via ActionScript code as the following examples illustrate:

<fx:Style>
	global
	{
		locale: "fr-FR";
	}
</fx:Style>

or

private function initApp(): void
{
	setStyle("locale","fr-FR");
}

The style can also be specified directly in the declaration as follows:

<fx:Declarations>
	<s:DateTimeFormatter id="df" dateStyle="long" timestyle="none" style="fr-FR"/>
</fx:Declarations>

Here’s a complete example that sets the global locale to French as used in France (fr-FR) and formats a number, a date, and provides a comparison function for sorting for a DataGridColumn:

<?xml version="1.0" encoding="utf-8"?>
<s:Application
	xmlns:fx="http://ns.adobe.com/mxml/2009"
	xmlns:s="library://ns.adobe.com/flex/spark"
	xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">
	<fx:Style>
		@namespace s "library://ns.adobe.com/flex/spark";
		@namespace mx "library://ns.adobe.com/flex/mx";
		global
		{
			locale: "fr-FR";
		}
	</fx:Style>
	<fx:Declarations>
		<s:NumberFormatter id="nf" fractionalDigits="0"/>
		<s:DateTimeFormatter id="df" dateStyle="long" timeStyle="none"/>
		<s:SortingCollator id="sc"/>
	</fx:Declarations>
	<fx:Script>
		<![CDATA[
			import mx.collections.ArrayCollection;
			[Bindable]
			private var myNumCandles:int = 10;
			[Bindable]
			private var myBirthday:Date = new Date(2000, 0, 1);
			[Bindable]
			private var friends:ArrayCollection = new ArrayCollection
				([
					"Frédérique", "Valentine", "Grégoire", "Jérôme",
					"André", "Noémie", "Eugène", "Jean", "René",
					"Valérie", "Noëlle"
				]);
		]]>
	</fx:Script>
	<s:VGroup>
		<mx:Text text="{nf.format(myNumCandles)}"/>
		<mx:Text text="{df.format(myBirthday)}"/>
		<mx:DataGrid id="dg" dataProvider="{friends}"
			rowCount="11" width="150">
			<mx:columns>
				<mx:DataGridColumn
					headerText="click here to sort"
					sortCompareFunction="{sc.compare}"/>
			</mx:columns>
		</mx:DataGrid>
	</s:VGroup>

</s:Application>

 

There are more examples and the full documentation in the ASDoc provided with the Flex SDK. We invite you to download the Flex SDK Hero release, try it out and let us know what you think.