Archive

Archive for December, 2008

Flex Date Utils – dayOfYear and weekOfYear

December 29th, 2008 Gareth 17 comments

2 more methods for today’s post. These may or may not be useful to people. I don’t think I have yet to use them in any of my code (maybe one time using the ColdFusion equivalents), but I thought I would translate them to Flex all the same.

/**
 * Gets the ordinal value or day of the year
 *
 * @param date	The date for which to get the day of the year
 * 
 * @return		A number representing the day of the year, 1 to 365 or 366 for a leap year
 */
public static function dayOfYear( date:Date ):Number {
	// add one as it has to include first of year
	return DateUtils.dateDiff( DateUtils.DAY_OF_MONTH, new Date( date.fullYear, DateUtils.monthAsNumber( DateUtils.JANUARY ), 1 ), date ) + 1;
}

This method takes a date and calculates the ordinal day of the year that that date represents, from 1 to 365 or 366 in a leap year. This just uses the dateDiff method to subtract the number of days between the 1st of the year, and the date parameter (and adds one to include the first day of the year).

To implement, first import the package:

import com.flexoop.utilities.dateutils.DateUtils;

then:

private var _dayOfYear:Number = DateUtils.dayOfYear( new Date() );
/**
 * Gets the week of the year
 * 
 * @param date	The date for which to get the week of the year
 * 
 * @return		A number representing the week of the year, 1 to 53 ( as there are slightly more than 52 weeks of days in a year)
 */
public static function weekOfYear( date:Date ):Number {
	return Math.ceil( DateUtils.dayOfYear( date ) / 7 );
}

This method works very similarly to the dayOfYear method except that it calculates which week of the year the date falls in, and returns a number from 1 to 53.

To implement, first import the package:

import com.flexoop.utilities.dateutils.DateUtils;

then:

private var _weekOfYear:Number = DateUtils.weekOfYear( new Date() );

All methods in this series are describing code in the FlexDateUtils package I put on Google code.

Flex Date Utils – DateDiff fix

December 23rd, 2008 Gareth 9 comments

I thought I would take a small break in the middle of my posts for the Flex Date Utils library to go over a fix I just had to make to the dateDiff method in the DateUtils class. I hadn’t really noticed this issue until I was reviewing my code for another fix I had put in previously (that was also not working correctly).

The main issue that cropped up was that to get the year, I was just subtracting the endDate year from the startDate year. However, when you think about this, it is a very inaccurate way of treating year. As year and months can vary in length, I couldn’t just use the Milliseconds contained within it to determine whether a year or month had occurred. I had to just subtract one year or month from another. However, if 2 months fall on separate years, but are not > 1 year apart, it will return 1, even though they could only be a month or so apart. e.g. December 2008 to February 2009 is nowhere near 1 year apart, but subtracting 2008 from 2009, returns 1.

In order to fix this problem, I decided to check the total months that had passed also. I then ran into yet another snag. What if the month was the same, but the day of the month had not passed. e.g. July 16 2007 to July 5 2008 would not be 1 year, although if just using the months and year, it might suggest that it was 1 year apart. To fix this problem, I decided to also check the milliseconds difference between the 2 dates. This now fixes any dates that have different times within them also.

The dateDiff( MONTH ) was having a similar issue so this now fixes that problem also.

I put this fix up on the FlexDateUtils code and also updated the demo so that the issue would be fixed there also.

Make sure to download the latest code and you shouldn’t have any more issues with the dateDiff.

Flex Date Utils – Date and Time Format (Part II)

December 15th, 2008 Gareth 4 comments

This post is the second part of my description of the date and time format methods contained in the DateUtils class. I will be going over the public methods this time and showing how to call them from your code.

// Date masks
public static const SHORT_DATE_MASK:String	= "MM/DD/YY";
public static const MEDIUM_DATE_MASK:String	= "MMM D, YYYY";
public static const LONG_DATE_MASK:String	= "MMMM D, YYYY";
public static const FULL_DATE_MASK:String	= "EEEE, MMMM D, YYYY";
 
// Time masks
public static const SHORT_TIME_MASK:String	= "L:NN A";
public static const MEDIUM_TIME_MASK:String	= "L:NN:SS A";
// TZD = TimeZoneDesignation = GMT + or - X hours, non-standard, requires a slight hack
public static const LONG_TIME_MASK:String	= MEDIUM_TIME_MASK + " TZD";

These are the constants that can be used to denote the masks to use when calling the date and time formatters. This makes the coder less prone to typing out incorrect values when entering a date. User defined masks can still be passed as parameters, but the predefined masks should cover 99% of everyone’s needs.

/**
 * Formats a time into a certain time format
 * 
 * @param date	The date to format
 * @param mask	How the date should be formatted
 * 
 * @return		A formatted time
 */
public static function timeFormat( date:Date, mask:String=DateUtils.SHORT_TIME_MASK ):String {
	return buildDateTime( date, mask, "(A|:|J|H|K|L|N|S|TZD|\\s)+", DateUtils.SHORT_TIME_MASK );
}

This method formats the date to a specified time. The standard output uses the SHORT_TIME_MASK (L:NN A which creates in the format 12:05 am), but can be altered to whatever format the programmer wants. I pass the date to the buildDateTime method (described in a previous post) to build the time, making sure to pass what constitutes a valid mask in the regular expression pattern. The default is the SHORT_TIME_MASK again.

To use this method, import the package:

import com.flexoop.utilities.dateutils.DateUtils;

then:

private var _formatted:String = DateUtils.timeFormat( new Date() );

This would take the current time and would output it like this: 11:16 pm

/**
 * Formats a date into a certain date format
 * 
 * @param date	The date to format
 * @param mask	How the date should be formatted
 * 
 * @return		A formatted date
 */
public static function dateFormat( date:Date, mask:String=DateUtils.SHORT_DATE_MASK ):String {
	return buildDateTime( date, mask, "(Y|M|D|E|\\W)+", DateUtils.SHORT_DATE_MASK );
}

This method formats the date to a specified time. The standard output uses the SHORT_DATE_MASK (MM/DD/YY which creates in the format 12/15/08), but can be altered to whatever format the programmer wants. I pass the date to the buildDateTime method (described in a previous post) to build the date, making sure to pass what constitutes a valid mask in the regular expression pattern. The default is the SHORT_DATE_MASK again.

To use this method, import the package:

import com.flexoop.utilities.dateutils.DateUtils;

then:

private var _formatted:String = DateUtils.dateFormat( new Date() );

This would take the current date and would output it like this: 12/15/08

/**
 * Formats a date into a certain date/time format
 * 
 * @param date	The date to format
 * @param mask	How the date should be formatted
 * 
 * @return		A formatted date
 */
public static function dateTimeFormat( date:Date, mask:String="MM/DD/YYYY L:NN:SS A" ):String {
	return buildDateTime( date, mask, "(Y|M|D|E|A|J|H|K|L|N|S|TZD|\\W)+", DateUtils.SHORT_DATE_MASK + ' ' + DateUtils.SHORT_TIME_MASK );
}

And finally,
This method formats the date to a specified date and time. The standard output uses a combination of the SHORT_DATE_MASK (MM/DD/YY which creates in the format 12/15/08) and the SHORT_TIME_MASK (L:NN A which creates in the format 12:05 am), but can be altered to whatever format the programmer wants. I pass the date to the buildDateTime method (described in a previous post) to build the date and time, making sure to pass what constitutes a valid mask in the regular expression pattern. The default is the SHORT_DATE_MASK and the DateUtils.SHORT_TIME_MASK again.

To use this method, import the package:

import com.flexoop.utilities.dateutils.DateUtils;

then:

private var _formatted:String = DateUtils.dateTimeFormat( new Date() );

This would take the current date and would output it like this: 12/15/08 11:20 pm

Once again, a very useful function that did not get included in the Flex framework for whatever reason, but now can easily be include in anyone’s code.

All methods in this series are describing code in the FlexDateUtils package I put on Google code.

Remove View Source From Context Menu

December 14th, 2008 Gareth 1 comment

I had decided to create a demo application for my Flex Date Utils library. I thought it might be nice for people to just be able to see exactly what the library can do without having to download it and compile it. Right now it is just for the DateUtils portion of the library, but I’ll be adding Holiday and BusinessDay to the mix soon.

In order to make what I did more visible, I decided to enable the source code view when exporting the release build of the project. After exporting the file and FTP’ing it to the server, I started to have some difficulties getting the source code view working properly. Rather than wasting more time trying to get it working, I decided to just uncheck the Enable View Source check box, and re-export the project. However, when I went to my swf and right clicked on it, “View Source” was still an option in the Context Menu. I went back and tried cleaning my project, re-exporting it, deleting the swf and recreating the project. Nothing seemed to be working.

I then figured I would try creating a new project and placing it under there. As I was pasting the new application file, I noticed one new line had been added to my file
viewSourceURL=”srcview/index.html”

Apparently when the compiler enabled “View Source”, it adds this line of code. However, when it re-compiles the code with “View Source” disabled, it does not remove that attribute from the application tag. 30 minutes and lots of yelling later, this has now fixed the problem. It would be nice if Adobe included this little tidbit in their livedocs as “make sure to check this”.

The demo app can be viewed here for anyone interested.

Flex Date Utils – Date and Time Format (Part I)

December 12th, 2008 Gareth No comments

I will have to split this post into 2 separate parts, as there are several methods that are all related, and this post would be huge. In this post I will go over what is happening behind the scenes when date, time, and dateTimeFormat are called. All of these methods are private, so other than explaining how and why they work, nothing will be accessible outside of the DateUtils class.

// Internal variable used in date/time formatting
private static var _dateFormatter:DateFormatter;
private static function get dateFormatter():DateFormatter {
	if ( !_dateFormatter ) {
		_dateFormatter = new DateFormatter;
	}
	return _dateFormatter;
}

I use a static getter for a DateFormatter instantiation so that I can use the built in features of the DateFormatter class to format my dates. I figure, why reinvent the wheel, when it has been done so well in Flex already :)

/**
 * @private
 * 
 * Calculates a timeZoneOffset, and converts it to a string, in standard GMT XX:XX format
 * 
 * @param date	The date on which to calculate the offset
 * 
 * @return		The formatted time zone designation
 */
private static function buildTimeZoneDesignation( date:Date ):String {
	if ( !date ) {
		return "";
	}
	var timeZoneAsString:String = "GMT ";
	// timezoneoffset is the number that needs to be added to the local time to get to GMT, so
	// a positive number would actually be GMT -X hours
	if ( date.getTimezoneOffset() / 60 > 0 && date.getTimezoneOffset() / 60 < 10 ) {
		timeZoneAsString += "-0" + ( date.getTimezoneOffset() / 60 ).toString();
	} else if ( date.getTimezoneOffset() < 0 && date.timezoneOffset / 60 > -10 ) {
		timeZoneAsString += "0" + ( -1 * date.getTimezoneOffset() / 60 ).toString();
	}
	// add zeros to match standard format
	timeZoneAsString += "00";
	return timeZoneAsString;
}

As the description states, this method takes a date and builds the time zone designation in the GMT -XX:00 timezone offset. If date is null, then it returns an empty string.

/**
 * @private
 * 
 * This function will remove any invalid characters from the date/time mask based upon a pattern
 * 
 * @param mask			The string for matching
 * @param pattern		The valid characters for this mask
 * @param defaultValue	The default value to return to the calling page should the mask not match the pattern
 * 
 * @return				Returns a validated <code>mask</code> based upon the original pattern
 */
private static function removeInvalidDateTimeCharacters( mask:String, pattern:String, defaultValue:String ):String {
	// test for invalid date and time characters
	if ( mask.replace( new RegExp( pattern, "ig" ), "" ).length > 0 ) {
		// if user is passing an invalid mask, default to defaultValue
		mask = defaultValue;
	}
	// temporarily replace TZD with lowercase tzd for replacing later
	return mask.replace( new RegExp( "TZD", "i" ), "tzd" );
}

I use this method to remove any bad characters that may have been passed in to the date/time formatters. It takes a mask, a pattern, and a default value. The default value is my fallback in case an invalid characters have been passed in. First I replace all characters based upon the pattern passed to the method. If any characters are left, then it is a bad pattern, and it uses the default value. I then replace TZD and switch it to lowercase so that it can be replaced with the actual time zone designation at a later point (and the dateformatter does not balk at it when it comes across it).

/**
 * @private
 * 
 * Formats a date into a certain date/time format
 * 
 * @param date			The date to format
 * @param mask			The string for matching
 * @param pattern		The valid characters for this mask
 * @param defaultValue	The default value to return to the calling page should the mask not match the pattern
 * 
 * @return		A formatted date
 */
private static function buildDateTime( date:Date, mask:String, pattern:String, defaultValue:String ):String {
	dateFormatter.formatString = removeInvalidDateTimeCharacters( mask, pattern, defaultValue );
 
	return dateFormatter.format( date ).replace( new RegExp( "TZD", "i" ), buildTimeZoneDesignation( date ) );
}

This is where the dateformat “magic” happens :) The function receives a date, the mask of how to format the date, a pattern that determines which characters are valid characters, and a default value to use should there be any invalid characters.

This sets the formatString of the static dateFormatter and removes any invalid characters. Then it formats the date based upon that formatString, and finally replaces any TZD it finds (which would have been lowercased in the removeInvalidDateTimeCharacters method) with the actual timezone designation, if there was a time zone designation requested in the mask.

Even though none of these methods are available outside of the DateUtils class, I always like to know how things are working under the hood, and hopefully others do too.

All methods in this series are describing code in the FlexDateUtils package I put on Google code.

Flex Date Utils – dayOfWeekAsNumber

December 12th, 2008 Gareth No comments
// Days of week
public static const MONDAY:String	= "monday";
public static const TUESDAY:String	= "tuesday";
public static const WEDNESDAY:String	= "wednesday";
public static const THURSDAY:String	= "thursday";
public static const FRIDAY:String	= "friday";
public static const SATURDAY:String	= "saturday";
public static const SUNDAY:String	= "sunday";
 
// a generic object for holding day of the week values
private static var _objDaysOfWeek:Object = null;
public static function get objDaysOfWeek():Object {
	if ( !_objDaysOfWeek ) {
		_objDaysOfWeek = {};
		_objDaysOfWeek[ DateUtils.SUNDAY ]	= 0;
		_objDaysOfWeek[ DateUtils.MONDAY ]	= 1;
		_objDaysOfWeek[ DateUtils.TUESDAY ]	= 2;
		_objDaysOfWeek[ DateUtils.WEDNESDAY ]	= 3;
		_objDaysOfWeek[ DateUtils.THURSDAY ]	= 4;
		_objDaysOfWeek[ DateUtils.FRIDAY ]	= 5;
		_objDaysOfWeek[ DateUtils.SATURDAY ]	= 6;
	}
	return _objDaysOfWeek;
}
 
/**
 * Formats a date to the numeric version of the day of the week
 * 
 * @param strDayOfWeek	The day of week to convert
 * 
 * @return		A formatted day of week or -1 if day not found
 */
public static function dayOfWeekAsNumber( strDayOfWeek:String ):Number {
	return ( objDaysOfWeek[ strDayOfWeek ] >= 0 ) ? objDaysOfWeek[ strDayOfWeek ] : -1;
}

This method will actually take a string that represents the day of the week, and will convert that to the numeric representation in Flex for that day of the week, ranging from 0-6.

I actually created a generic object that would hold all of the values for the days of the week to make my life easier when trying to return and reference values in it. I also created constants for all of the days of the week, so anyone calling any method that needs a string of the day of the week, can simply reference the constants, instead of trying to guess what I called the days of the week.

The method tries to reference whatever string is passed to it in the generic dayOfWeek object, and will return the value it finds, or if the object does not contain that string, it will return -1. As long as you use the constants, the -1 should never be returned.

So in order to use this method, first import the package

import com.flexoop.utilities.dateutils.DateUtils;

and then:

private var _dow:Number = DateUtils.dayOfWeekAsNumber( DateUtils.MONDAY );

_dow would now be 1, as _objDaysOfWeek[ DateUtils.MONDAY ] is equal to 1. I tend to use this method whenever I’m passing a day of the week value to one of my other methods, just so I don’t confuse the actual day value ( i.e. using 1-7 instead of 0-6 ).

All methods in this series are describing code in the FlexDateUtils package I put on Google code.

Flex Date Utils – isDate

December 10th, 2008 Gareth 2 comments

2 short methods again today, but one I find is very useful (and the first one that got me started on my date utils library)

/**
 * Determines whether a value is actually a valid date
 * 
 * @param value	The date value
 * 
 * @return		<code>true</code> means this is a valid date, <code>false</code> means it is not a valid date
 */
public static function isDate( value:String ):Boolean {
	return Date.parse( value ) > 0;
}

My isDate method will check whether the value that is passed to it is actually a date or not. I was surprised to find this wasn’t included somewhere in the Flex framework, but quite happy at how easy it was to create it. All that needs to be done is to check whether the date can be parsed by the Date class. If yes, it’s a date, if not, it is not a date.

To implement, first import the package:

import com.flexoop.utilities.dateutils.DateUtils;

then:

private var _validDate:Boolean = DateUtils.isDate( 'this is not a date' );

Straight forward and simple :)

/**
 * Converts the month to a Flex month
 * 
 * @param date	The human readable month
 * 
 * @return		The Flex converted month or 0 aka January
 */
public static function toFlexMonth( localMonth:Number ):Number {
	return ( localMonth > 0 && localMonth < 13 ) ? localMonth - 1 : 0;
}

This method is another one that I created to try to make my life easier when thinking about months, so I didn’t get confused about using 0-11 instead of 1-12. I actually use another method I created instead of this one now, but I thought I should leave it in as it may be useful to someone, even if I don’t use it that much.

This accepts a month, 1-12, and returns the flex value for that month, 0-11.

Once again, to use, import the package:

import com.flexoop.utilities.dateutils.DateUtils;

and then:

private var _newMonth:Number = DateUtils.toFlexMonth( 6 );

And this would return 5. Nothing awe inspiring in that method, but perhaps useful to someone.

All methods in this series are describing code in the FlexDateUtils package I put on Google code.

Flex Date Utils – daysInMonth

December 9th, 2008 Gareth 3 comments
/**
 * Gets the days in the month
 * 
 * @param date	The date to check
 * 
 * @return		The number of days in the month
 */
public static function daysInMonth( date:Date ):Number {
	// get the first day of the next month
	var _localDate:Date = new Date( date.fullYear, DateUtils.dateAdd( DateUtils.MONTH, 1, date ).month, 1 );
	// subtract 1 day to get the last day of the requested month
	return DateUtils.dateAdd( DateUtils.DAY_OF_MONTH, -1, _localDate ).date;
}

I have found method to be quite useful. It returns the number of days in a month based upon the date passed in.

First I create a date to represent the first of the following month, then I subtract 1 day from that month, and return the day that that date represents, which is now the last day of the month requested.

To use this method, first import the package:

import com.flexoop.utilities.dateutils.DateUtils;

and then:

private var _dim:Number = DateUtils.daysInMonth( new Date( 2008, 1 ) );

_dim will now contain 29, as there were 29 days in February, 2008.

All methods in this series are describing code in the FlexDateUtils package I put on Google code.

Flex Date Utils – dayOfWeek

December 8th, 2008 Gareth No comments

These methods are somewhat short so I’ll be going over dayOfWeek, and toFlexDayOfWeek

/**
 * Gets the day of the week
 * 
 * @param date	The date for which to get the day of the week
 * 
 * @return		A number representing the day of the week
 */
public static function dayOfWeek( date:Date ):Number {
	return date.getDay();
}

This one is perhaps not as useful as some of the others, as it can be called directly from the date object itself, but it is contained in the ColdFusion date functions, so I thought I would add it to the FlexDateUtils package, and for me, it is easier to remember DateUtils.dayOfWeek than date.getDay().

It accepts a date and then returns the day of the week as a number that that date represents. Valid return values would be 0 to 6.

To call this method, import the package:

import com.flexoop.utilities.dateutils.DateUtils;

and then:

private var _dow:Number = DateUtils.dayOfWeek( new Date( 2008, 4, 1 ) );

This would return 4 as May 1, 2008 ( dates in Flex also start from zero ) was a Thursday.

/**
 * Converts the day of the week to a Flex day of the week
 * 
 * @param date	The human readable day of week
 * 
 * @return		The Flex converted day of week or 0 aka Sunday
 */
public static function toFlexDayOfWeek( localDayOfWeek:Number ):Number {
	return ( localDayOfWeek > 0 && localDayOfWeek < 8 ) ? localDayOfWeek - 1 : 0;
}

This method is really just a simplification of converting the day of the week from what most people think of, 1 to 7, to what Flex considers a day of the week, 0 to 6. I have another method that I will document in a later post that will convert the string version of a day of the week, to its numeric equivalent.

To call this method, import the package:

import com.flexoop.utilities.dateutils.DateUtils;

and then:

private var _flexDow:Number = DateUtils.toFlexDayOfWeek( 4 );

This would return 3 as 4 (Wednesday, starting from Sunday), would be 3 to Flex.

All methods in this series are describing code in the FlexDateUtils package I put on Google code.

Flex Date Utils – dateAdd

December 7th, 2008 Gareth 5 comments

The first method in this series that I’ll go over is dateAdd.

All of the constants that are referred to in this method are defined in the constants section of the DateUtils class

// Date parts
public static const YEAR:String		= "fullYear";
public static const MONTH:String	= "month";
public static const WEEK:String		= "week";
public static const DAY_OF_MONTH:String	= "date";
public static const HOURS:String	= "hours";
public static const MINUTES:String	= "minutes";
public static const SECONDS:String	= "seconds";
public static const MILLISECONDS:String	= "milliseconds";
public static const DAY_OF_WEEK:String	= "day";
 
/**
 * Adds the specified number of "date parts" to a date, e.g. 6 days
 * 
 * @param datePart	The part of the date that will be added
 * @param number	The total number of "dateParts" to add to the date
 * @param date		The date on which to add
 * 
 * @return			The new date
 */
public static function dateAdd( datePart:String, number:Number, date:Date ):Date {
	var _returnDate:Date = new Date( date );
 
	switch ( datePart ) {
		case DateUtils.YEAR:
		case DateUtils.MONTH:
		case DateUtils.DAY_OF_MONTH:
		case DateUtils.HOURS:
		case DateUtils.MINUTES:
		case DateUtils.SECONDS:
		case DateUtils.MILLISECONDS:
			_returnDate[ datePart ] += number;
			break;
		case DateUtils.WEEK:
			_returnDate[ DateUtils.DAY_OF_MONTH ] += number * 7;
			break;
		default:
			/* Unknown date part, do nothing. */
			break;
	}
	return _returnDate;
}

This is a pretty basic method that accepts the part of the date that you want to add to, how much of that date part you want to add, and the date to which you want to add that date part.

To call this method from your class you would have to first import the class

import com.flexoop.utilities.dateutils.DateUtils;

Then from there

private var _changedDate:Date = DateUtils.dateAdd( DateUtils.WEEK, 3, new Date() );

This would add 3 weeks to the current date/time and return that date to _changedDate.

To return a date before the date you pass in, just set the “number” parameter to a negative, and it will subtract that number, like so:

private var _previousDate:Date = DateUtils.dateAdd( DateUtils.YEAR, -2, new Date() );

This would subtract 2 years from the current date and return it to _previousDate.

All methods in this series are describing code in the FlexDateUtils package I put on Google code.