1. 程式人生 > >Flex3選擇某一週的小控制元件.

Flex3選擇某一週的小控制元件.

(本人第一次寫部落格,第一次接觸Flex可能不是很專業,如若程式有問題, 還望大家指出不足,以鞭策我進步.)

在業務中的時間是按照一週一週來算的話,那麼可能需要使用到這種小控制元件.使用起來還是比較方便的.


話不多說,直接內容.

首先,這個控制元件是預設載入當前對應的下一週的情況(可以根據需求自己改.)

然後預設將每週的星期一作為一週的第一天(如果想要將週末視為一週的第一天,那麼也可以改,只是改動較大.)

關於周的計算,稍微麻煩一些的是兩個月的月頭和月尾.這時,我採用的是過半法,也就是說,哪個月的日期佔了四天以上就視這周是哪個月的.

圖片中有顯示這種情況

.


最後是程式碼.

<?xml version="1.0" encoding="utf-8"?>
<mx:HBox  xmlns:mx="http://www.adobe.com/2006/mxml" width="100%" creationComplete="init()" height="100%" horizontalAlign="left" xmlns:controls="components.controls.*">
	<controls:CustomDateFormatter  id="dDate" formatString="YYYY-MM-01"/><!--得到每個月的第一天-->
	<controls:CustomDateFormatter id="fDate" formatString="YYYY年MM月"/><!--格式化月份需要-->
	<controls:CustomDateFormatter id="eDate" formatString="YYYY-MM-DD"/><!--格式化天的時候需要.-->
	<mx:Script>
		<![CDATA[
			import mx.collections.ArrayCollection;
			import mx.controls.Alert;
			[Bindable]
			private var currentDate:Date=new Date;//當前日期.
			[Bindable]
			private var yearMonth:String;//年月的str
			[Bindable]
			private var week:String;//周的str;
			[Bindable]
			public var loadFunction:Function;//傳過來的,要呼叫的方法.
			[Bindable]
			public var weekDatesStr:ArrayCollection=new ArrayCollection;//當前周對應的日期的Str
			/**
			 * 初始化
			 * */
			private function init():void{
				eNextWeek();
			}
			/***
			 * 呼叫傳遞的引數的方法.
			 * */
			private function loadData():void
			{
				if(this.loadFunction != null) {
					loadFunction();
				}
			}
			/***
			 * 前一週
			 * */
			private function ePrevWeek():void
			{
				currentDate=new Date(currentDate.fullYear,currentDate.month,currentDate.date-7);
				yearMonth=currentMonth(currentDate);
				week=currentWeek(currentDate);
				DayOfWeekDate(currentDate);
				loadData();
			}
			/**
			 * 點選下一週執行的方法.
			 * */
			private function eNextWeek():void
			{
				currentDate=new Date(currentDate.fullYear,currentDate.month,currentDate.date+7);
				yearMonth=currentMonth(currentDate);
				week=currentWeek(currentDate);
				DayOfWeekDate(currentDate);
				loadData();
			}
			
			/**
			 *月份.
			 * 格式化月份.普通情況就直接格式化月份.
			 * 主要是防止第一週,這個第一個周是上個月的還是下個月的.如果是上個月的,然後月份就上個月的.
			 * 
			 * */
			private function currentMonth(date:Date):String
			{
				var dateOneStr:String=dDate.format(date); //根據七天後的日期,得到這個月的第一天.
				var dateOneDate:Date=dDate.convertToDate(dateOneStr);//得到這個月的1號.
				var temp:Date=new Date(date.getFullYear(),date.getMonth(),date.getDate());//預設的月份是當前月,如果選中的是這個月的頭一週,但是這一週又不是這個月的就是上個月的了.
				var dateMax:Date=new Date(date.getFullYear(),date.getMonth(),getMaxDay(date));//得到這個月的最後一天.如果是這個月的最後一週,同時這周又不屬於這個月,那麼就是下個月的了.
				// 得到當天之後的第七天,然後-1 然後+這個月的第一個天.
				if((date.day>=5||date.day==0) && date.date-dateOneDate.date<=2 &&(dateOneDate.day>=5||dateOneDate.day==0)){
					//如果當前月份的1號是 星期五 到 日,同時當前日期也是和一號同一個星期.那麼,這時,這個月份應該是算是算上個月的最後一個星期,月份也要顯示為上個月.
					temp=new Date(date.getFullYear(),date.getMonth()-1,date.getDate());
				}else if(dateMax.date-date.date<=2 && date.day<=3 && date.day!=0 && dateMax.day<=3 && dateMax.day!=0 ){
					//如果選擇的是這個月的最後一週,同樣需要判斷這周應該是屬於哪個月.
					//如果這個月的最後一週是週一 到週三之間,同時當前調整後的日期和最後一天是同一周,那麼這周應該是屬於下個月的.
					temp=new Date(date.getFullYear(),date.getMonth()+1,date.getDate());
				}	
				return fDate.format(temp);
			}
			/***
			 * 得對應的週數.
			 * 既需要考慮到第一週,也需要考慮到最後一週.
			 * 主要預防這個月的最後一週不是算在這個月裡,而是算在下個月裡的情況.
			 * 判斷依據,如果最後一天的週數,小於等於3,大於0表示最後一週不是這個月的,是下個月的.
			 * 
			 * */
			private function currentWeek(date:Date):String
			{
				var index:int=0;
				var weeks:Array=['第一週','第二週','第三週','第四周','第五週','第六週','第七週'];
				var dateOneStr:String=dDate.format(date); //根據七天後的日期,得到這個月的第一天.
				var dateOneDate:Date=dDate.convertToDate(dateOneStr);//得到這個月的1號.
				var dateMax:Date=new Date(date.getFullYear(),date.getMonth(),getMaxDay(date));//得到這個月的最後一天.如果是這個月的最後一週,同時這周又不屬於這個月,那麼就是下個月的了.
				// 得到當天之後的第七天,然後-1 然後+這個月的第一個天.
				var yssj:Number=Math.ceil(((date.date-1)+dateOneDate.day)/7);
				if((date.day>=5||date.day==0) && date.date-dateOneDate.date<=2 &&(dateOneDate.day>=5||dateOneDate.day==0)){//月頭.
					//如果當前月份的1號是 星期五 到 日,同時當前日期也是和一號同一個星期.那麼,這時,這個月份應該是算是算上個月的最後一個星期,月份也要顯示為上個月.
					//星期就是上個月的最後一個月,至於算第幾周,那麼就需要判斷了.
					 var preMonth:Date=new Date(date.getFullYear(),date.getMonth()-1,1);//得到上個月的物件.
					 var preMonthMin:Date=dDate.convertToDate(dDate.format(preMonth));//得到上個月的一號.
					 var preTotalDay:Number=getMaxDay(preMonthMin);
					 var perMonthMax:Date=new Date(preMonthMin.getFullYear(),preMonthMin.getMonth(),preTotalDay);//得到這個月的最後一天.
					 var weekNum:int=0;//表示週數.
					 if(preMonthMin.day>=1&&preMonthMin.day<=4){//看第一週算不上它的,星期一到星期五之間都算它的.
					 	weekNum++;
					 }
					 if(preMonthMin.day!=0){//不是週末,用8減
						 preTotalDay=preTotalDay-(8-preMonthMin.day);//減去第一週浪費的天數.
					 }else{
					 	preTotalDay--;// 是週末,只浪費了一天.
					 }
					 var moreDay:Number=preTotalDay%7;//將剩下的天數對7取模
					 preTotalDay=preTotalDay-moreDay;//然後減去.除不盡的
					 weekNum=weekNum+preTotalDay/7;
					 //最後判斷一下最後一週算不算它的
					 weekNum++;//最後一週也算它的.正是因為這個條件才進來的
					 index=weekNum-1;
				}else if(dateMax.date-date.date<=2 && date.day<=3 && date.day!=0 && dateMax.day<=3 && dateMax.day!=0 ){//月尾
					//如果選擇的是這個月的最後一週,同樣需要判斷這周應該是屬於哪個月.
					//如果這個月的最後一週是週一 到週三之間,同時當前調整後的日期和最後一天是同一周,那麼這周應該是屬於下個月的.第一週.
					  index=0;
				}else {//本月之內的.只需要判斷第一個星期是不是自己的.然後操作.
					var weekNum_:int=0;//表示週數.
					if(dateOneDate.day>=1&&dateOneDate.day<=4){//看第一週算不上它的,星期一到星期五之間都算它的.
					 	weekNum_++;
					}
					var total:Number=date.getDate();//得到當前日期的天數.
					if(dateOneDate.day!=0){//不等於0 表示是週一到週五,直接用8減.
						total=total-(8-dateOneDate.day);//減去第一週浪費的天數.
					}else{//等於0 表示是週末,所以只浪費了一天.
						total--;
					}
					var moreDay_:Number=total%7;//將剩下的天數對7取模
					if(moreDay_>=1){//只要還有餘數,標識正在下一週的進行時,所以加1
						weekNum_++;
					}
					total=total-moreDay_;//然後減去.除不盡的
					weekNum_=weekNum_+total/7;
					//最後判斷一下最後一週算不算它的
					index=weekNum_-1;
				}
				 return weeks[index];
			}
			/**
			 * 得到對應的一週的日期
			 * */
			private function DayOfWeekDate(date:Date):void
			{
				weekDatesStr.removeAll();//移除所有.
				var dateDay:Number=date.getDay();
				if(dateDay==0){//如果dateDay為週末,就需要
					dateDay=7;//將dateDay設定為0,方便計算.
				}
//				Alert.show(eDate.format(date));
				for(var index:int=1;index<=7;index++){//從週一到週六
					var preDate:Date=new Date(date.getFullYear(),date.getMonth(),date.getDate()+(index-dateDay));
					var str:String=eDate.format(preDate);
//					Alert.show(str);
					weekDatesStr.addItem(str);
				}
			}
			
			/**
			 * 根據日期得到這個月的天數.
			 * */
			private function getMaxDay(date:Date):Number{
				 var nowMonth:Date=new Date(date.getFullYear(),date.getMonth(),1);
				 var nextMonth:Date=new Date(date.getFullYear(),date.getMonth()+1,1); 
				 var nowStr:String=eDate.format(nowMonth);
				 var nextStr:String=eDate.format(nextMonth);
				 var dates:Number=((nextMonth.getTime()-nowMonth.getTime())/(60*60*24*1000));//在Flex中的getTime得到的是毫秒數.所以需要乘以1000
				 return dates;
			}
		]]>
	</mx:Script>
	
	
	<mx:Grid  width="400" height="85">
		<mx:GridRow>
			<mx:GridItem width="100%">
				<mx:HBox width="400" height="85">
					<mx:Text id="cPrevious" text="◀" useHandCursor="true" click="ePrevWeek()"/>
					<mx:Text id="cMonth" text="{yearMonth}"/><mx:Spacer/>
					<mx:Text id="cWeek" text="{week}"/>
					<mx:Text id="cNext" text="▶" useHandCursor="true" click="eNextWeek()"/>
				</mx:HBox>
			</mx:GridItem>
		</mx:GridRow>
	</mx:Grid>
</mx:HBox>


如有任何問題,歡迎提出友好的建議.

如有任何問題,歡迎提出友好的建議.