views:

194

answers:

3

Im using the following code to make a simple countdown time for a website:

//Create your Date() object
var endDate:Date = new Date(2009,8,5);
//Create your Timer object
//The time being set with milliseconds(1000 milliseconds = 1 second)
var countdownTimer:Timer = new Timer(1000);

//Adding an event listener to the timer object
countdownTimer.addEventListener(TimerEvent.TIMER, updateTime);
//Initializing timer object
countdownTimer.start();
//Calculate the time remaining as it is being updated
function updateTime(e:TimerEvent):void
{
//Current time
    var now:Date = new Date();
    var timeLeft:Number = endDate.getTime() - now.getTime();
    //Converting the remaining time into seconds, minutes, hours, and days
    var seconds:Number = Math.floor(timeLeft / 1000);
    var minutes:Number = Math.floor(seconds / 60);
    var hours:Number = Math.floor(minutes / 60);
    var days:Number = Math.floor(hours / 24);

//Storing the remainder of this division problem
seconds %= 60;
minutes %= 60;
hours %= 24;

//Converting numerical values into strings so that
//we string all of these numbers together for the display
var sec:String = seconds.toString();
var min:String = minutes.toString();
var hrs:String = hours.toString();
var d:String = days.toString();

//Setting up a few restrictions for when the current time reaches a single digit
if (sec.length < 2) {
 sec = "0" + sec;
}

if (min.length < 2) {
 min = "0" + min;
}

if (hrs.length < 2) {
 hrs = "0" + hrs;
}

if (d.length < 2) {
 d = "0" + d;
}


//Stringing all of the numbers together for the display
var time:String = d + ":" + hrs + ":" + min + ":" + sec;
//Setting the string to the display
time_txt.text = time;
}

Which works fine.

I want to be able to input the date to count down to from and xml file (so it can be changed without having to mess with the fla)

I have tried the following:

//load in xml
var xml:int = 0
var loader:URLLoader = new URLLoader();
loader.addEventListener(Event.COMPLETE, loadXML);
loader.load(new URLRequest("countdown.xml"));
function loadXML(e:Event):void
{
    var xml= new XML(e.target.data) ;
    trace(xml);
}

//Create your Date() object
var endDate:Date = new Date(xml);

(rest of the code as above but omitted for example)

The trace statement shows that the right date is being loaded from the xml file but the countdown is out by a few thousand days!

I was thinking that it may have something to do with the data type being an int rather than a string, but not too sure. Any ideas how to make this work?


Edit:

Here is the XML format for the original question:

<countdown> 2009,8,5 </countdown>
A: 

Likely you are going to need to parse your resulting xml string and create the date in a more explicit manner:

var endDate:Date = new Date(xml.@year, xml.@month, xml.@date, xml.@hour, xml.@minutes, xml.@seconds, xml.@ms)

Be sure to keep in mind that several of the date properties are 0 index. Month specifically.

Joel Hooks
Would I therefore need to have the year, month, date, hour...etc within seperate tags in the xml file. Could you give me an example of how to set the xml up because currently I have:<countdown>2009,8,5</countdown>
A: 

What is the format of the date in the XML? If you are using a timestamp passed from C# then you need to know that their format starts on year 0 while ActionScript starts in year 1970. Here is a quick snippet in C# to convert it (from this thread):

public double MilliTimeStamp(DateTime TheDate)
{
    DateTime d1 = new DateTime(1970, 1, 1);
    DateTime d2 = TheDate.ToUniversalTime();
    TimeSpan ts = new TimeSpan(d2.Ticks - d1.Ticks);

    return ts.TotalMilliseconds;
}

Otherwise what Joel suggests is a good solution.


Edit:

Given an xml string like so:

<countdown> 2009,8,5 </countdown>

You could do the following:

// convert it to a string
var dateString:String = String(xml);
// split it into year, month, day on the comma
var parts:Array = dateString.split(",");
// put it into a date object
// NOTE: we -1 from the month since months are 0 based
var endDate:Date = new Date(parts[0], parts[1] - 1, parts[2]);

But I would probably choose a better XML format:

package
{

import flash.display.Sprite;

public class DateTest extends Sprite
{
 public function DateTest()
 {
     var xml:XML = <countdown year='2009' month='8' day='5' />;

     // put it into a date object
     // NOTE: we -1 from the month since months are 0 based
     var endDate:Date = new Date(xml.@year, xml.@month - 1, xml.@day);

     trace(endDate);
 }
}

}
James Fassett
my xml file looks like this:<countdown>2009,8,5</countdown>This is the first time I have tried using xml files so I am unsure of the way to structure this correctly?
+1  A: 

Attention. You have a big error in your code. You are instantiating the endDate before loading the XML. The xml is only loaded when your loadXML is called. This means that xml was null and instantiating the Date with a null value it would give you the begging of the Unix Epoch as a timestamp (Thu Jan 1 02:00:00 GMT+0200 1970) thus the "few thousand" days difference.

I'd just like to point out another obvious error. Loading the xml correctly and tracing (2000,8,5) and then using that value for the countdown is like (wrongly) invoking the Date constructor like this

var endDate:Date = new Date("2009,8,5"); // note the quotes
// because what you trace from the xml is a string

as opposed to the correct call you use in the first example. Otherwise Joel gave you an example of how to easily pass that values to your Date constructor if you were to change the xml structure.

If you were to test your endDate trace output you'd have received an Invalid Date.

If you'd rather not touch your xml, you then can go with something like this.

//load in xml
var xml:int = 0
var loader:URLLoader = new URLLoader();
loader.addEventListener(Event.COMPLETE, loadXML);
loader.load(new URLRequest("countdown.xml"));
var endDate:Date;
function loadXML(e:Event):void
{
    var xml = new XML(e.target.data) ;
    var xmlDate:Array = String(xml).split(",");
    endDate = new Date(parseInt(xmlDate[0]), parseInt(xmlDate[1])-1, parseInt(xmlDate[2]));
    trace(endDate);
}
Virusescu
Thanks, that now works great. I did remove the -1 after the parseInt(xmlDate[1]) though, as this set the date out by 1 month, and wasn't too sure why this was added there.
because, as mentioned by others, the month property is zero index. This of course depends on how you feed your xml. "2009.8.5" as a string makes me think to 5 of August. It was just a thing to keep in mind.
Virusescu