31
Jul
07

Calculating the number of days between two selected dates in a DateChooser control

Here’s a marginally more interesting sample. I was playing around with the DateChooser (calendar) control and the selectableRange property and figured I’d make a simple application to calculate the differences between two selected dates. The example creates a selectable range of dates from the current date to current date plus 1 year. Users can select any single or range of dates between the start date and end date, and Flex calculates the number of days the user selected using some basic math.

Full code after the jump.

View MXML

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" verticalAlign="middle" backgroundColor="white">

    <mx:Script>
        <![CDATA[
            import mx.controls.dataGridClasses.DataGridColumn;

            /* Number of milliseconds in a day. (1000 milliseconds per second * 60 seconds per minute * 60 minutes per hour * 24 hours per day) */
            private const MS_PER_DAY:uint = 1000 * 60 * 60 * 24;

            [Bindable]
            private var startDate:Date = new Date();

            [Bindable]
            private var endDate:Date = new Date(startDate.fullYear + 1, startDate.month, startDate.date);

            /* Default label function for the DataGrid. Basically just calls the DateFormatter on the current column's contents. */
            private function cellDateFormatter(item:Object, column:DataGridColumn):String {
                var columnDataField:String = column.dataField;
                return dateFormatter.format(item[columnDataField]);
            }

            /* Custom label function for the last column. Calculates the number of days between the start date and end date. */
            private function calculateDays(item:Object, column:DataGridColumn):String {
                var tempDate:Date = new Date(item.rangeEnd - item.rangeStart);
                return Math.round((tempDate.time / MS_PER_DAY) + 1).toString();
            }
        ]]>
    </mx:Script>

    <mx:DateFormatter id="dateFormatter" formatString="MMM D, YYYY" />

    <mx:HBox>
        <mx:DateChooser id="dateChooser" selectableRange="{{rangeStart:startDate, rangeEnd:endDate}}" allowMultipleSelection="true" />

        <mx:DataGrid id="selDates" dataProvider="{dateChooser.selectedRanges}" labelFunction="cellDateFormatter" verticalScrollPolicy="on" height="{dateChooser.height}">
            <mx:columns>
                <mx:DataGridColumn dataField="rangeStart" headerText="Range Start:" />
                <mx:DataGridColumn dataField="rangeEnd" headerText="Range End:" />
                <mx:DataGridColumn labelFunction="calculateDays" headerText="Number Days:" />
            </mx:columns>
        </mx:DataGrid>
    </mx:HBox>

</mx:Application>

View source enabled in the following example.


16 Responses to “Calculating the number of days between two selected dates in a DateChooser control”


  1. 1 Odo Aug 1st, 2007 at 1:09 am

    Hmm…this do not work. It only reports 1 day for every selection !

  2. 2 peterd Aug 1st, 2007 at 5:37 am

    Odo,

    Hold down the Shift key.

  3. 3 Odo Aug 1st, 2007 at 7:01 am

    Ok thnx :) That works.

  4. 4 Sandeep Aug 3rd, 2007 at 9:36 pm

    how do u select the range here.

  5. 5 peterd Aug 3rd, 2007 at 10:00 pm

    Sandeep,

    Try clicking on Aug 6th, pressing the Shift key, and then pressing on Aug 22nd.
    It should highlight each of the days between the two dates, set the range, and list the number of days as 17.

    If you press the Ctrl key, I believe it selects each day individually instead of as a range/series.

  6. 6 Sergey Nov 20th, 2007 at 8:36 am

    How its working?

  7. 7 libran Mar 19th, 2008 at 11:16 pm

    good!^_^

  8. 8 Rhoby Apr 29th, 2008 at 3:20 am

    Bonjour,

    How to loop for each day between 2 dates ?
    thanks you very much.

  9. 9 peterd Apr 29th, 2008 at 12:18 pm

    Rhoby,

    I’m sure there is a better, more efficient way, but maybe this helps:

    <?xml version="1.0" encoding="utf-8"?>
    <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
            layout="vertical"
            verticalAlign="middle"
            backgroundColor="white">
    
        <mx:Script>
            <![CDATA[
                import mx.events.CalendarLayoutChangeEvent;
                import mx.utils.ObjectUtil;
    
                private var msInDay:uint = 1000 * 60 * 60 * 24;
    
                private function dateChooser_change(evt:CalendarLayoutChangeEvent):void {
                    // textArea.text = ObjectUtil.toString(dateChooser.selectedRanges);
                    textArea.text = "";
                    if (dateChooser.selectedRanges.length > 0) {
                        var ranges:Object = dateChooser.selectedRanges[0];
                        var numDays:uint = (ranges.rangeEnd.time - ranges.rangeStart.time) / msInDay;
                        var idx:uint;
                        var retDate:Date;
                        for (idx = 0; idx <= numDays; idx++) {
                            retDate = new Date(ranges.rangeStart.time);
                            retDate.date += idx;
                            textArea.text += retDate.toDateString() + "n";
                        }
                    }
                }
            ]]>
        </mx:Script>
    
        <mx:DateChooser id="dateChooser"
                allowMultipleSelection="true"
                change="dateChooser_change(event);" />
    
        <mx:TextArea id="textArea"
                editable="false"
                selectable="false"
                width="320"
                height="240" />
    
    </mx:Application>
    

    Peter

  10. 10 Rhoby Apr 30th, 2008 at 3:30 am

    Hello Petered

    First, very big thank you for having responded …
    I never thought you were answering me still thank you very much
    This site told me everything about Flex and I hope with all my heart that will never end …
    This is the solution that I was looking for …
    You are the best, MANY THANKS

  11. 11 Anonymous Mar 17th, 2009 at 8:01 am

    Hello Petered,

    We are working with Flex Builder 3 and We need to select multiple days in a calendar
    without pressing the Ctrl or Shift keys. Is it possible?

    Thanks

  12. 12 Nate Mar 24th, 2009 at 10:11 am

    Your example seems to demonstrate the same bug(?) I’m experiencing. When the selectableRange is defined on a DateChooser and allowMultipleSelection=”true”, the selectedRanges do not include the rangeStart. In fact, in your example (at least on my machine), you can’t even select a range that includes the rangeStart date. Anyone else experiencing this?

  13. 13 ABC May 7th, 2009 at 6:10 am

    Is this suppose to display the date selected or find the range. I m confused.

  14. 14 Peter deHaan May 7th, 2009 at 8:19 am

    ABC,

    Try clicking on Aug 6th, pressing the Shift key, and then pressing on Aug 22nd.
    It should highlight each of the days between the two dates, set the range, and list the number of days as 17.

    If you press the Ctrl key, I believe it selects each day individually instead of as a range/series.

    Peter

  15. 15 flex_learner Jun 4th, 2009 at 6:10 am

    Is it possible to show the selected value dynamically in date choosed control

  16. 16 Peter deHaan Jun 4th, 2009 at 8:06 am

    flex_learner,

    You could do something like the following, which will set the selected date to July 4, 1980 and then set the DateChooser control’s displayed month and year to that same date:

    <?xml version="1.0" encoding="utf-8"?>
    <mx:Application name="DateChooser_selectedDate_test"
            xmlns:mx="http://www.adobe.com/2006/mxml"
            layout="vertical"
            verticalAlign="middle"
            backgroundColor="white">
    
        <mx:Date id="dat" fullYear="1980" month="6" date="4" />
    
        <mx:DateChooser id="dateChooser"
                selectedDate="{dat}"
                displayedYear="{dat.fullYear}"
                displayedMonth="{dat.month}" />
    
    </mx:Application>
    

    The previous code will give a couple of binding warnings saying:
    (a) Data binding will not be able to detect assignments to “fullYear”.
    (b) Data binding will not be able to detect assignments to “month”.

    The example still works, but if you don’t like those warnings, you could always set the properties using ActionScript instead, as seen in the following example:

    <?xml version="1.0" encoding="utf-8"?>
    <mx:Application name="DateChooser_selectedDate_test"
            xmlns:mx="http://www.adobe.com/2006/mxml"
            layout="vertical"
            verticalAlign="middle"
            backgroundColor="white">
    
        <mx:Script>
            <![CDATA[
                import mx.events.CalendarLayoutChangeEvent;
    
                private function dateChooser_change(evt:CalendarLayoutChangeEvent):void {
                    var selDat:Date = dateChooser.selectedDate;
                    dateChooser.displayedYear = selDat.fullYear;
                    dateChooser.displayedMonth = selDat.month;
                }
            ]]>
        </mx:Script>
    
        <mx:DateChooser id="dateChooser"
                change="dateChooser_change(event);">
            <mx:selectedDate>
                <mx:Date fullYear="1980" month="6" date="4" />
            </mx:selectedDate>
        </mx:DateChooser>
    
        <mx:Button id="btn"
                label="Set new selectedDate"
                click="dateChooser.selectedDate = new Date(1976, 8, 9);" />
    
    </mx:Application>
    

    Peter

Leave a Reply

This blog is terrible at eating HTML tags. If you plan on posting code/XML, please escape your "<" characters as "&lt;" and your ">" characters as "&gt;".




July 2007
M T W T F S S
    Aug »
 1
2345678
9101112131415
16171819202122
23242526272829
3031  

Badge Farm

  • Powered by Redoable 1.2
  • Cornify
  • Feeds burnt by Feedburner
  • Feed