/**
* Utility function to determine if a four character expiration date is valid OR not!
*
* @param s
* <p>Date string in format MMyy. e.g., '0609' as date 'June 2009'.</p>
* @return <code>boolean</code> flag indicating if expiration date is valid or not.
*/
public static boolean isValidExpiration(String s) {
// use SimpleDateFormat to parse values like '0609' as date 'June 2009'
java.text.DateFormat sdf = new java.text.SimpleDateFormat("MMyy");
// establish current date as last day of previous month at 23:59:59
java.util.Calendar now = java.util.Calendar.getInstance();
now.set(now.get(java.util.Calendar.YEAR), now.get(java.util.Calendar.MONTH), 0, 23, 59, 59);
try {
// actual parsing of the date, wrapped in try/catch
// parses as 1st day of month at midnight since only providing month and year
// e.g., '0609' becomes 'June 01, 2009 00:00:00'
java.util.Date exp = sdf.parse(s);
// if parsed date is before current month, then return invalid!
if (exp.before(now.getTime())) return false;
} catch (java.text.ParseException e) {
return false; // if not MMYY then reject
}
// valid if made it this far, can do in reverse by using !exp.before and return true above.
return true;
}
Monday, July 27, 2009
Expiration Date Validation Example
Here is a simple example of a utility that can validate expirations dates like '0609' or '0710' as being valid expiration dates (i.e., is the date before the current month or not).
Thursday, June 04, 2009
Tuesday, November 11, 2008
Java Custom Comparators: Sorting Text and Numbers Independently
Comparing strings and sorting lists of strings in Java is normally very simple as the API provides a nice means of comparing two strings as text. However, the need occasionally arises when we have values stored that can be either numeric or text or a combination thereof.
Say we have the above input array of string values that we have converted to an ArrayList as shown and now want to sort. In steps custom comparators. The easiest way to implement one is using an anonymous nested class at the point of use which will allow the flexibility of sorting differently each time Collections.sort() is called. If you find you need this more often, then convert this to a standalone class that implements the Comparator interface.
The above does the following:
Hope that helps.
Happy coding!
References:
String[] inputStringArray = { "1", "19", "2", "3pt1", "3", "5pt1", "6pt2", "7pt3", "7pt3", "10", "10x1", "15", "7", "A7", "B87", "10pt5" };
// The input is a String array. Make that an ArrayList:
java.util.List<String> inputList = new java.util.ArrayList<String>(java.util.Arrays.asList(inputStringArray));
Say we have the above input array of string values that we have converted to an ArrayList
public static java.util.List<String> sort(java.util.List<String> list) {
java.util.Collections.sort(list, new java.util.Comparator<String>() {
/**
* Custom compare to sort numbers as numbers.
* Strings as strings, with numbers ordered before strings.
*
* @param o1
* @param o2
* @return
*/
@Override
public int compare(String o1, String o2) {
boolean isFirstNumeric, isSecondNumeric;
isFirstNumeric = o1.matches("\\d+");
isSecondNumeric = o2.matches("\\d+");
if (isFirstNumeric) {
if (isSecondNumeric) {
return Integer.valueOf(o1).compareTo(Integer.valueOf(o2));
} else {
return -1; // numbers always smaller than letters
}
} else {
if (isSecondNumeric) {
return 1; // numbers always smaller than letters
} else {
isFirstNumeric = o1.split("[^0-9]")[0].matches("\\d+");
isSecondNumeric = o2.split("[^0-9]")[0].matches("\\d+");
if (isFirstNumeric) {
if (isSecondNumeric) {
int intCompare = Integer.valueOf(o1.split("[^0-9]")[0]).compareTo(Integer.valueOf(o2.split("[^0-9]")[0]));
if (intCompare == 0) {
return o1.compareToIgnoreCase(o2);
}
return intCompare;
} else {
return -1; // numbers always smaller than letters
}
} else {
if (isSecondNumeric) {
return 1; // numbers always smaller than letters
} else {
return o1.compareToIgnoreCase(o2);
}
}
}
}
}
});
return list;
}
The above does the following:
- Determines if the strings being compared are numeric values or not, using regular expression to match on \d which signifies a numeric digit.
- If both values are numeric, then we compare as integers using its already implemented compareTo function.
- If only one of the values is numeric, then it is the smallest as we want the numbers to sort first.
- If both are non-numeric, then we simply compare as strings. However, to show extended support for our third case of blended numbers and text, we go through same logic as above on the two string values: if both begin with numbers, then compare as integers with difference that equal numbers then need to sort by text; if one begins with a number, then it is smaller; if both are text, then just compare as strings.
Hopefully that is clear, but to test the results, you can use the following code:
java.util.List<String> sortedList = sort(inputList);
System.out.println("Numbers and text sorted!");
for (String s : sortedList) {
System.out.println(s);
}
Hope that helps.
Happy coding!
References:
Sunday, October 12, 2008
String to Value Algorithm
Well continuing on the thought of conversion routines, here is an example of taking a string value in Transact-SQL on Microsoft SQL Server (may work on other platforms that support same functions) and creating a unique integer value.
Code listing:
Code listing:
DECLARE @text nvarchar(100), @value bigint
SET @text = 'Smith'
SET @value = 0
WHILE LEN(@text) > 0
BEGIN
SET @value = @value + ASCII(LEFT(@text, 1)) * square(LEN(@text))
SET @text = RIGHT(@text, LEN(@text) - 1)
END
SELECT @value
Very simple hopefully. The basis is using the length of the string, create a large integer value that is multiplied against the ascii value of each letter in the string. I was asked this as a question, so I have not explored all of the uses of a function like this; however, as a quick hash it seems to work fine.
Again, just posting for the learning of some of the tools available in SQL like the ASCII and SQUARE functions. Hopefully making the life of some other DBA or programmer a little easier.
References:
Sunday, September 21, 2008
Converting Between String, ASCII, And Hex In .NET
Welcome again to my twisted mind. This post is just a quick example on converting between string, ascii and hexadecimal values using the .NET, specifically visual basic .NET programming.
This is not rocket science by any stretch, but like posting things like this even as simple as it is so I for one don't forget it and to help another programmer get started on something more complex.
Anyway, for now that is it.
As you can see above, .NET provides some nice conversion utilities for ascii value of a character and converting a decimal value to hexidecimal making the solution very straightforward as we just need to create a character array from string value and then convert each character to its ascii equivalent. Furthermore, we can quickly get the hexidecimal value for the character.
Dim strOrig As String = "Hello"
Dim decimals As New List(Of Decimal)()
Dim hexStrs As New List(Of String)()
Dim intCurrent As Double
For Each c As Char In strOrig.ToCharArray()
intCurrent = Strings.Asc(c)
decimals.Add(intCurrent)
hexStrs.Add(Conversion.Hex(intCurrent))
Next
If hexStrs.Count > 0 Then
Console.Write("Hex: " & hexStrs(0))
For i As Integer = 1 To (hexStrs.Count - 1)
Console.Write(" " & hexStrs(i))
Next
Console.WriteLine("")
End If
If decimals.Count > 0 Then
Console.Write("Decimals: " & decimals(0))
For i As Integer = 1 To (decimals.Count - 1)
Console.Write(" " & decimals(i))
Next
Console.WriteLine("")
End If
Console.ReadLine()
This is not rocket science by any stretch, but like posting things like this even as simple as it is so I for one don't forget it and to help another programmer get started on something more complex.
Anyway, for now that is it.
Happy programming.
References:
Subscribe to:
Posts (Atom)