views:

471

answers:

5

How can I create an array of dates, one for every day, starting Jan 1st 2008 to Dec 31st 2008 in ActionScript 3?

It would be ideal if it worked on any date range...

A: 

There's nothing fancy to it: just use two for loops, with the inner loop checking the month index ("Thirty days has September, April, June and November") and accounting for leap year (I believe this year is one), remembering ActionScript's Date object doesn't use zero-based indexes for days (though it does for months):

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" initialize="app_init()">
    <mx:Script>
     <![CDATA[

      private function app_init():void
      {
       var dates:Array = new Array();

       for (var month:int = 0; month < 12; month++)
       {
        for (var day:int = 1; day <= 31; day++)
        {
         var date:Date = new Date(2008, month, day);

         // 30 days has September (8), April (3), June (5) and November (10)... 
         if ((month == 8 || month == 3 || month == 5 || month == 10) && day == 31)
         {
          break;
         }
         // Leap year      
         else if (month == 1 && day > 29)
         {
          break;
         }

         dates.push(date);
        }
       }

       for each (var d:Date in dates)
       {
        trace(d);
       }
      }

     ]]>
    </mx:Script>
</mx:Application>

Make sense? (If there's a more elegant way, I'm not aware of it.)

Christian Nunciato
Christian: Thank you for your comment on my answer. I have deleted it since it wasn't compatible with Actionscript3.
some
+5  A: 

How about this :

function getDateArray(start:Date, end:Date):Array
{
    var result:Array = new Array();
    var iter:Date = new Date(start); //you could remove or standardise time info here
    while (iter <= end)
    {
     result.push(new Date(iter));
     iter.setDate(iter.getDate() + 1);
    }
    return result;
}

Let the AS3 Date class deal with the actual issue of number of days per month, leap years etc.

There may well be a better way to do whatever requires you to have an array of dates, but I'm sure I've used something like this before for legitimate reasons.

inferis
Yeah, that is more elegant. Nicely done.
Christian Nunciato
+3  A: 

Just wondering why you would need an array of dates. Not saying there probably isn't a good reason for it, but it just seems a bit odd is all. If you have a start and end date then chances are there's probably a better method at doing whatever it is you're trying to do. Any more info?

James Hay
I fully agree. All you would need is a range of time and how many milliseconds a day has. With that knowledge you can calculate every day in that range without needing an array.
Luke
+1  A: 

I needed an array of days between 2 dates because my application has a custom hSlider with 2 thumbs which allow the user to change the range of date they wish to bind the data to. (think google finanace) ...

My solution:

var startDate:Date = Application.application._model.minDate;
  var endDate:Date = Application.application._model.maxDate;

  var timespan:Number = endDate.getTime() - startDate.getTime();
  var aDay:Number = 86400000;
  var days:Number = timespan / aDay;
  dateData.length = 0;
  var i:int = 0;
  dateData.push(new Date(startDate));
  dateData.push(new Date(endDate));

  for(i = 0; i < days; i++){
   var newDate:Date = new Date(startDate.getTime() + i * aDay);
   dateData.push(newDate);
  }

  slider.setThumbValueAt(0, Number(dateData[0]));
  slider.setThumbValueAt(1, Number(dateData[i]));
+1  A: 

Obviously this may not fit in with your application, but for arguments sake if I wanted to have an hSlider that controlled a date value within a given range, I would set the slider up to return a value between 0 and 1 and use that as a percentage of milliseconds between two dates. An example of this would be:

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical">
<mx:Script>
 <![CDATA[
  import mx.events.SliderEvent;

  private static var START_DATE : Date = new Date(2009,0);
  private static var END_DATE : Date = new Date(2010,0);

  [Bindable]
  protected var currentDate : Date;

  protected function dateSliderChangeHandler(event : SliderEvent) : void
  {
   var differenceInMilli : Number = END_DATE.time - START_DATE.time;
   var percantageMilli : Number = differenceInMilli * event.value;
   var currentDateInMilli : Number = START_DATE.time + percantageMilli;

   currentDate = new Date(currentDateInMilli);
  }

 ]]>
</mx:Script>


<mx:HSlider id="dateSlider" 
 width="200" 
 minimum="0"
 maximum="1"
 change="dateSliderChangeHandler(event)" />
<mx:Label text="{currentDate}" />

That way i don't have to create an array of all the dates. Obviously if you only needed a certain accuracy in the date then you would need some extra logic to round the dates up or down.

James Hay