{"id":1467,"date":"2009-01-26T05:00:18","date_gmt":"2009-01-26T12:00:18","guid":{"rendered":"http:\/\/kodegeek.com\/blog\/?p=1467"},"modified":"2009-01-23T20:22:21","modified_gmt":"2009-01-24T03:22:21","slug":"%c2%bfcomo-encontrar-el-ultimo-dia-habil-del-mes-en-java","status":"publish","type":"post","link":"http:\/\/kodegeek.com\/blog\/2009\/01\/26\/%c2%bfcomo-encontrar-el-ultimo-dia-habil-del-mes-en-java\/","title":{"rendered":"\u00bfComo encontrar el \u00faltimo d\u00eda h\u00e1bil del mes en Java?"},"content":{"rendered":"<p>Quizas a usted alguna vez le toco programar como encontrar el \u00faltimo d\u00eda h\u00e1bil del mes. La definici\u00f3n:<\/p>\n<blockquote><p>Es el \u00faltimo d\u00eda del mes, que no cae un fin de semana y que no es un d\u00eda feriado.<\/p><\/blockquote>\n<p>Para trabajar este ejemplo utilizaremos fechas de los Estados Unidos, mercado de finanzas. En el caso de los d\u00edas feriados, vamos a utilizar <a href=\"http:\/\/www.optionsclearing.com\/market\/infomemos\/2008\/oct\/24961.pdf\" target=\"_blank\">el calendario de OCC<\/a> (<a href=\"http:\/\/www.nasdaq.com\/personal-finance\/credit-card-glossary.stm\" target=\"_blank\">Options Clearing Corporation<\/a>). Dependiendo del \u00e1rea y pa\u00eds en donde usted trabaje el calendario de las fechas ser\u00e1 distinto (por ejemplo Estados Unidos y Venezuela).<\/p>\n<p>La soluci\u00f3n en Java es sencilla, usando la clase<a href=\"http:\/\/java.sun.com\/j2se\/1.5.0\/docs\/api\/java\/util\/Calendar.html\" target=\"_blank\"> Calendar<\/a>. Despu\u00e9s de jugar un poco al final termin\u00e9 escribiendo esta clase que muestra el \u00faltimo d\u00eda h\u00e1bil del mes y le dice a usted si la fecha entrada por el teclado es un d\u00eda h\u00e1bil o no:<\/p>\n<pre lang=\"Java\">package com.kodegeek.blog.finance;\r\n\r\nimport java.text.DateFormat;\r\nimport java.text.ParseException;\r\nimport java.text.SimpleDateFormat;\r\nimport java.util.Calendar;\r\nimport java.util.Date;\r\nimport java.util.HashSet;\r\nimport java.util.ResourceBundle;\r\nimport java.util.Scanner;\r\nimport java.util.Set;\r\nimport java.util.logging.Logger;\r\n\r\n\/**\r\n * Helper date methods tailored for the financial industry.\r\n * License: LGPL\r\n * BLOG: http:\/\/kodegeek.com\r\n * @author josevnz@kodegeek.com\r\n *\r\n *\/\r\npublic final class DateHelper {\r\n\r\n\tprivate final static ResourceBundle BUNDLE;\r\n\tprivate final static Logger log;\r\n\tprivate static final Set holidays;\r\n\r\n\tstatic {\r\n\r\n\t\tBUNDLE = ResourceBundle.getBundle(DateHelper.class.getName());\r\n\r\n\t\tlog = Logger.getLogger(DateHelper.class.getName());\r\n\r\n\t\t\/\/ Populate the holidays set\r\n\t\tholidays = new HashSet();\r\n\t\tfor (String dateStr: BUNDLE.getString(\"com.kodegeek.blog.finance.DateHelper.holidays\").split(\";\\\\s*\", -1)) {\r\n\t\t\ttry {\r\n\t\t\t\tholidays.add(DateFormat.getDateInstance(DateFormat.DEFAULT).parse(dateStr));\r\n\t\t\t} catch (ParseException e) {\r\n\t\t\t\tlog.warning(String.format(BUNDLE.getString(\"com.kodegeek.blog.finance.DateHelper.error.badDate\"), dateStr));\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t}\r\n\r\n\t\/**\r\n\t * Default constructor\r\n\t *\/\r\n\tprivate DateHelper() {\r\n\t\t\/\/ Only static methods go on this class\r\n\t}\r\n\r\n\t\/**\r\n\t * Check if a given date is the last business day of the month\r\n\t * @param aDate The date to test\r\n\t * @return True if is the last day of the month, false otherwise\r\n\t *\/\r\n\tpublic final static boolean isLastBusinessDayOfMonth(final Date aDate) {\r\n\t\tboolean isLastBusinessDay = false;\r\n\r\n\t\t\/\/ Can do a comparison?\r\n\t\tif (aDate == null) {\r\n\t\t\treturn isLastBusinessDay;\r\n\t\t}\r\n\r\n\t\tCalendar calendar = Calendar.getInstance();\r\n\r\n\t\t\/\/ Current date on a weekend\r\n\t\tcalendar.setTime(aDate);\r\n\t\tint day = calendar.get(Calendar.DAY_OF_MONTH);\r\n\t\tint month = calendar.get(Calendar.MONTH);\r\n\t\tint year =  calendar.get(Calendar.YEAR);\r\n\r\n\t\tint lastbusinessDayOfMonth = getLastBusinessDayOfMonth(month, year);\r\n\t\tif (lastbusinessDayOfMonth == day) {\r\n\t\t\tisLastBusinessDay = true;\r\n\t\t}\r\n\r\n\t\treturn isLastBusinessDay;\r\n\t}\r\n\r\n\t\/**\r\n\t * Get the last business day of the month for a given month \/ year combination\r\n\t * @param month The month\r\n\t * @param year The year\r\n\t * @return The last business day\r\n\t *\/\r\n\tpublic static int getLastBusinessDayOfMonth(final int month, final int year) {\r\n\t\tint day = -1;\r\n\t\tCalendar calendar = Calendar.getInstance();\r\n\t\tcalendar.set(Calendar.MONTH, month);\r\n\t\tcalendar.set(Calendar.YEAR, year);\r\n\t\tcalendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));\r\n\r\n\t\t\/\/ Keep looking backwards until the day is not a weekend or a holiday\r\n\t\twhile(true) {\r\n\t\t\tif (calendar.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY) {\r\n\t\t\t\tcalendar.add(Calendar.DAY_OF_MONTH, -1);\r\n\t\t\t\tcontinue;\r\n\t\t\t} else if (calendar.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) {\r\n\t\t\t\tcalendar.add(Calendar.DAY_OF_MONTH, -2);\r\n\t\t\t\tcontinue;\r\n\t\t\t} else if (holidays.contains(calendar.getTime())) {\r\n\t\t\t\tcalendar.add(Calendar.DAY_OF_MONTH, -1);\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\t\t\tbreak;\r\n\t\t} \/\/ End while\r\n\t\tday = calendar.get(Calendar.DAY_OF_MONTH);\r\n\t\treturn day;\r\n\t}\r\n\r\n\t\/**\r\n\t * Unit test, load today date and check if is a end of the month\r\n\t * @param args The date to test from the command line\r\n\t * @throws Exception If the date is invalid for the given local\r\n\t *\/\r\n\tpublic static void main(String [] args) throws Exception {\r\n\t\tScanner scan = new Scanner(System.in);\r\n\t\tdo {\r\n\t\t\tString currDateStr = null;\r\n\t\t\tSimpleDateFormat format = new SimpleDateFormat(\"yy-M-d\");\r\n\t\t\ttry {\r\n\t\t\t\tSystem.out.println(\"Please enter a date to check (YYYY-MM-DD, Ctrl-C to exit):\");\r\n\t\t\t\tcurrDateStr = scan.nextLine();\r\n\t\t\t\tDate date = format.parse(currDateStr);\r\n\r\n\t\t\t\tif (date != null) {\r\n\t\t\t\t\tCalendar calendar = Calendar.getInstance();\r\n\t\t\t\t\tcalendar.setTime(date);\r\n\t\t\t\t\tint month = calendar.get(Calendar.MONTH);\r\n\t\t\t\t\tint year =  calendar.get(Calendar.YEAR);\r\n\t\t\t\t\tSystem.out.println(String.format(\"Last business day of the month: %d\", getLastBusinessDayOfMonth(month, year)));\r\n\t\t\t\t\tSystem.out.println(String.format(\"%s %s\", currDateStr,isLastBusinessDayOfMonth(date) == true? \"Is the last business day\": \"Is not the last business day\"));\r\n\t\t\t\t}\r\n\t\t\t} catch (ParseException pExp) {\r\n\t\t\t\tSystem.err.println(String.format(\"Ignoring bad date: '%s'\", currDateStr));\r\n\t\t\t}\r\n\t\t} while (true);\r\n\t}\r\n\r\n}<\/pre>\n<p>El resource bundle lo \u00fanico que contiene son los d\u00edas feriados:<\/p>\n<pre lang=\"Java\"># Bank holidays per OCC calendar 2009 - http:\/\/www.optionsclearing.com\/market\/infomemos\/2008\/oct\/24961.pdf\r\ncom.kodegeek.blog.finance.DateHelper.holidays=Jan 01, 2009;January 19, 2009; Feb 26, 2009;Apr 10, 2009;May 25, 2009;July 3, 2009; Sep 7, 2009; Nov 26, 2009; Dec 25, 2009; Oct 12, 2009; Nov 11, 2009\r\ncom.kodegeek.blog.finance.DateHelper.error.badDate=Got bad date '%s' from property<\/pre>\n<p>La idea es buscar el \u00faltimo d\u00eda del mes y de all\u00ed contar hacia atr\u00e1s, esquivando fines de semana y d\u00edas feriados.<\/p>\n<blockquote><p>Please enter a date to check (YYYY-MM-DD, Ctrl-C to exit):<br \/>\n<span style=\"color: #ff0000;\">2009-02-27<\/span><br \/>\nLast business day of the month: 27<br \/>\n2009-02-27 Is the last business day<\/p><\/blockquote>\n<p>En una siguiente entrega les mostrar\u00e9 como hacer lo mismo en Ruby.<\/p>\n<p>Blogalaxia:<a rel=\"tag\" href=\"http:\/\/www.blogalaxia.com\/tags\/calendar\">calendar<\/a>, <a rel=\"tag\" href=\"http:\/\/www.blogalaxia.com\/tags\/calendario\">calendario<\/a>, <a rel=\"tag\" href=\"http:\/\/www.blogalaxia.com\/tags\/java.perl.ruby\">java.perl.ruby<\/a>, <a rel=\"tag\" href=\"http:\/\/www.blogalaxia.com\/tags\/occ\">occ<\/a><br \/>\nTechnorati:<a rel=\"tag\" href=\"http:\/\/technorati.com\/tag\/calendar\">calendar<\/a>, <a rel=\"tag\" href=\"http:\/\/technorati.com\/tag\/calendario\">calendario<\/a>, <a rel=\"tag\" href=\"http:\/\/technorati.com\/tag\/java.perl.ruby\">java.perl.ruby<\/a>, <a rel=\"tag\" href=\"http:\/\/technorati.com\/tag\/occ\">occ<\/a><br \/>\nTo2blogs:<a rel=\"tag\" href=\"http:\/\/www.to2blogs.com\/tag\/calendar\">calendar<\/a>, <a rel=\"tag\" href=\"http:\/\/www.to2blogs.com\/tag\/calendario\">calendario<\/a>, <a rel=\"tag\" href=\"http:\/\/www.to2blogs.com\/tag\/java.perl.ruby\">java.perl.ruby<\/a>, <a rel=\"tag\" href=\"http:\/\/www.to2blogs.com\/tag\/occ\">occ<\/a><br \/>\nDel.icio.us:<a rel=\"tag\" href=\"http:\/\/del.icio.us\/tag\/calendar\">calendar<\/a>, <a rel=\"tag\" href=\"http:\/\/del.icio.us\/tag\/calendario\">calendario<\/a>, <a rel=\"tag\" href=\"http:\/\/del.icio.us\/tag\/java.perl.ruby\">java.perl.ruby<\/a>, <a rel=\"tag\" href=\"http:\/\/del.icio.us\/tag\/occ\">occ<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Quizas a usted alguna vez le toco programar como encontrar el \u00faltimo d\u00eda h\u00e1bil del mes. La definici\u00f3n: Es el \u00faltimo d\u00eda del mes, que no cae un fin de semana y que no es un d\u00eda feriado. Para trabajar este ejemplo utilizaremos fechas de los Estados Unidos, mercado de finanzas. En el caso de <a class=\"read-more\" href=\"http:\/\/kodegeek.com\/blog\/2009\/01\/26\/%c2%bfcomo-encontrar-el-ultimo-dia-habil-del-mes-en-java\/\">[&hellip;]<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[9,10,438,449],"tags":[451,450,757,452],"_links":{"self":[{"href":"http:\/\/kodegeek.com\/blog\/wp-json\/wp\/v2\/posts\/1467"}],"collection":[{"href":"http:\/\/kodegeek.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/kodegeek.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/kodegeek.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/kodegeek.com\/blog\/wp-json\/wp\/v2\/comments?post=1467"}],"version-history":[{"count":20,"href":"http:\/\/kodegeek.com\/blog\/wp-json\/wp\/v2\/posts\/1467\/revisions"}],"predecessor-version":[{"id":1542,"href":"http:\/\/kodegeek.com\/blog\/wp-json\/wp\/v2\/posts\/1467\/revisions\/1542"}],"wp:attachment":[{"href":"http:\/\/kodegeek.com\/blog\/wp-json\/wp\/v2\/media?parent=1467"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/kodegeek.com\/blog\/wp-json\/wp\/v2\/categories?post=1467"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/kodegeek.com\/blog\/wp-json\/wp\/v2\/tags?post=1467"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}