AMFDateConverter – Convert PHP AMF to Flex Date Class
One of the frustrating things about AMF is that there is no mapping to the Flex Date class from PHP. Unlike converting to an ArrayCollection which utilizes the flex.messaging.io.ArrayCollection class in PHP to automatically map everything for you, there appears to be no support for Date serialization. So, a few months back, I figured out a relatively easy way to do the conversion on the Flex end without much trouble. This method involves receiving either UTC Date timestamps (“MM/DD/YYYY LL:NN:SS A“), or UNIX timestamps (# of millis since 1970) and converting them to a Date in the setter function for your property.
The first issue involves creating a getter/setter on your Flex end which can “set” values of any kind, but at the same time can “get” values of type: Date. We are looking for something like this…
1 2 3 4 5 6 7 8 9 10 11 | private var _myDate:Date; public function get myDate():Date { return _myDate; } public function set myDate(value:*):void { // Convert to Date Class } |
The reason we need a type agnostic setter is because we may not know the type of data we are receiving (String, Number, etc), and since the getter is typed as Date, the Flex compiler will throw an error, since the setter’s parameter is typed differently from the return type on the getter. The only exception is if one of the values is untyped (*), which is what I did here.
The next step is converting the data we receive in the setter to an actual Date object that we can use in our application. I wrote a helper class to facilitate this transition.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | public class AMFDateConverter { public static function convert(value:*):Date { if (value is Number) { // The backend value is based in milliseconds, which is PHP's // Unix timestamp multiplied by 1000. return new Date(value as Number); } else if (value is String) { var millis:Number = parseInt(value); // Are milliseconds typed as a String? if (isNaN(millis)) { // The date string is empty so return null if (value == "") { return null; } // Check to see if it is UTC format... var df:DateFormatter = new DateFormatter(); df.formatString = "MM/DD/YYYY LL:NN:SS A"; return new Date(df.format(value)); } else { return new Date(millis); } } else if (value is Date) { // If it is a Date, just return it (for internal use). return value as Date; } else { return null; } } } |
Now our getters/setters will look like this…
1 2 3 4 5 6 7 8 9 10 11 | private var _myDate:Date; public function get myDate():Date { return _myDate; } public function set myDate(value:*):void { _myDate = AMFDateConverter.convert(value); } |
Hope this helps. Any other ideas or improvements to this code are welcomed…
i tried your funciton, but didn’t work as fine as i’d like.
here, you can see an alternative:
http://www.actionscript.org/forums/showthread.php3?p=755574
and so i did one function that receives a string (cause from amfphp it cames as string):
public function transformDate(timestamp_in_seconds:String):String
{
//unix timestamp -> human date
var currDate:Date = new Date(parseInt(timestamp_in_seconds)*1000);
//timestamp_in_seconds*1000 – if you use a result of PHP time function,
//which returns it in seconds, and Flash uses milliseconds
var D:int = currDate.getDate();
var M:int = currDate.getMonth()+ 1;
//because Returns the month (0 for January, 1 for February, and so on)
var Y:int = currDate.getFullYear();
var H:int = currDate.getHours();
var N:int = currDate.getMinutes();
var Min:String;
if (N <10) {
Min = “0″ + N;
}
else {
Min = N.toString();
}
var theDate:String = (M + “/” + D + “/” + Y + ” – ” + H + “:” + Min);
return theDate;
}
@Carlos,
Ultimately that depends on how you are dealing with the data on the PHP backend. In some circumstances, you may want to multiply by 1000 on the PHP-end and if that is the case, the Flex-end might send a Number instead of a String.
This DateConverter class simply takes a few possible options that could be received from PHP and converts them to a Date class in Flex.
This DateConverter assumes any timestamp that it receives is based on System time, or the number of milliseconds since the epoch (Jan 1, 1970). Although you could easily modify the DateConverter to multiply by 1000 if you wish, I felt that this was a task more appropriate for PHP backend since Actionscript deals with timestamps differently than PHP’s Unix Timestamp does.
ZendAmf convert Dates from PHP datetime to AS3 Date Class.
But datetime is available only since PHP 5.2
There is still a lot of PHP 5.1.6 installations out there.
To use ZendAMF on those, you need to convert dates as integer before sending them.
I use a similar technique as yours with getters and setters
Hey Nate,
My knowledge level is not so far, as to understand what your doing I gust started playing with flex amfphp, I thing your AMFDateConverter could be the solution i am looking for.
I am trying to get records from my table between two dates with UTC Date timestamps.
[code]
public function SelectReceiptsFilter ($Date1, $Date2) {
$query = "SELECT * FROM records_closed WHERE date BETWEEN '$Date1' AND '$Date2'";
return mysql_query($query);
}
If I hardcode ($Date1 = ’2010-03-11 00:00:00’;) the dates is php, I get the expected results in the browser.
Any ideas?
Thanks in advance
Dimitris.