Skip to content

Commit

Permalink
Add holiday list for month only display
Browse files Browse the repository at this point in the history
Added maven enforcer plugin requiring mvn >= v3.2.5
Show holidays for the active month in the month only display
Moves display holidays code to the holiay class
Display locale when in debug mode (near the command line switch output)
Tweaked month validation when both month & year are given
Added another calendar output test (for Nov 2026)
  • Loading branch information
frossm committed Dec 13, 2023
1 parent 1260730 commit 8972e32
Show file tree
Hide file tree
Showing 7 changed files with 234 additions and 57 deletions.
28 changes: 27 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

<groupId>org.fross</groupId>
<artifactId>cal</artifactId>
<version>2.5.5</version>
<version>2.5.6</version>
<packaging>jar</packaging>

<name>cal</name>
Expand Down Expand Up @@ -36,6 +36,7 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.release>11</maven.compiler.release>
<maven.version.minimum>3.2.5</maven.version.minimum>
</properties>

<build>
Expand All @@ -47,6 +48,31 @@
</resources>

<plugins>
<!-- ========================================================================================== -->
<!-- Ensure the minimum Maven version is enforced -->
<!-- https://mvnrepository.com/artifact/org.apache.maven.plugins/maven-enforcer-plugin/3.4.1 -->
<!-- ========================================================================================== -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>3.4.1</version>
<executions>
<execution>
<id>enforce-maven</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<requireMavenVersion>
<version>${maven.version.minimum}</version>
</requireMavenVersion>
</rules>
</configuration>
</execution>
</executions>
</plugin>

<!-- ========================================================================================== -->
<!-- https://mvnrepository.com/artifact/org.codehaus.mojo/versions-maven-plugin -->
<!-- ========================================================================================== -->
Expand Down
2 changes: 1 addition & 1 deletion snap/snapcraft.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: fcal
version: '2.5.5'
version: '2.5.6'
summary: Command line calendar display
description: |
fCal is a command line calendar utility. It will display a
Expand Down
61 changes: 9 additions & 52 deletions src/main/java/org/fross/cal/Calendar.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
import java.util.TreeMap;

import org.fross.library.Date;
import org.fross.library.Format;
import org.fross.library.Output;
import org.fusesource.jansi.Ansi;
import org.fusesource.jansi.Ansi.Attribute;
Expand Down Expand Up @@ -124,6 +123,13 @@ public static void printMonth(int month, int year) {
for (int i = 0; i <= (days.length - 1); i++) {
Output.printColorln(Ansi.Color.WHITE, days[i]);
}

// If display holidays is enabled, display the list after the calendar
if (Holidays.queryHolidaysEnabled() == true) {
StringBuilder sb = Holidays.queryHolidayListMonth(month);
Output.printColorln(Ansi.Color.CYAN, sb.toString());
}

}

/**
Expand Down Expand Up @@ -177,56 +183,7 @@ public static void printYear(int year) {
// If display holidays is enabled, display the list after the calendar
if (Holidays.queryHolidaysEnabled() == true) {
int displayWidth = (CALENDARWIDTH + SPACESBETWEENCALS) * calsPerRow;
Output.debugPrintln("Width of calendar display for centering: " + displayWidth);

// Display the holiday display header
String header = year + " holidays for " + Holidays.queryCountry();
try {
Output.printColorln(Ansi.Color.YELLOW, Format.CenterText(displayWidth, header));
} catch (Exception ex) {
Output.printColorln(Ansi.Color.YELLOW, header);
}

// List the holidays
Object[] keySet = holidayList.keySet().toArray();
String keyLeft = "";
String keyRight = "";
for (int l = 0; l < ((holidayList.size() + 1) / 2); l++) {
try {
keyLeft = keySet[l].toString();

// Process odd numbers and even numbers differently
if ((holidayList.size() % 2) == 0) {
keyRight = keySet[keySet.length / 2 + l].toString();
} else {
keyRight = keySet[(keySet.length + 1) / 2 + l].toString();
}

// Build output data removing the year as it's redundant
String outputLeft = keyLeft.substring(5) + "|" + holidayList.get(keyLeft);
String outputRight = keyRight.substring(5) + "|" + holidayList.get(keyRight);

// Shorten the holiday name if it's longer than 1/2 the display width
if (outputLeft.length() > (displayWidth / 2 - 1)) {
outputLeft = outputLeft.substring(0, displayWidth / 2 - 5);
outputLeft = outputLeft + "..>";
}

// Display the left item and the spacer
Output.printColor(Ansi.Color.CYAN, outputLeft);
Output.print(" ".repeat((displayWidth / 2) - outputLeft.length()));

// Display the Right column item
Output.printColorln(Ansi.Color.CYAN, outputRight);

} catch (ArrayIndexOutOfBoundsException ex) {
// Display the left side and nothing on the right for odd number of holidays
Output.printColor(Ansi.Color.CYAN, keyLeft.substring(5) + "|" + holidayList.get(keyLeft));

} catch (IllegalArgumentException ex) {
Output.printColorln(Ansi.Color.RED, "ERROR: Could not display holiday list correctly");
}
}
Holidays.printHolidayListYear(year, displayWidth);
}
}

Expand Down Expand Up @@ -277,7 +234,7 @@ public static String[] getCalDays(int month, int year) {
if (Holidays.queryHolidaysEnabled() == true) {
holidayList = Holidays.getHolidays(year);
}

// Determine the which day of the week the 1st fall upon
int firstDayOfMon = getDayOfWeek(month, 1, year);
Output.debugPrintln("Firstday for " + month + "/" + year + ": " + firstDayOfMon);
Expand Down
85 changes: 85 additions & 0 deletions src/main/java/org/fross/cal/Holidays.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import java.util.Locale;
import java.util.TreeMap;

import org.fross.library.Format;
import org.fross.library.Output;
import org.fross.library.URLOperations;
import org.fusesource.jansi.Ansi;
Expand Down Expand Up @@ -114,6 +115,90 @@ public static TreeMap<String, String> getHolidays(int year) {

}

/**
* printHolidayListYear(): Print a 2 column list of holidays for the given year
*
* @param year
* @param displayWidth
*/
public static void printHolidayListYear(int year, int displayWidth) {
Output.debugPrintln("Width of calendar display for centering: " + displayWidth);

// Display the holiday display header
String header = year + " holidays for " + Holidays.queryCountry();
try {
Output.printColorln(Ansi.Color.YELLOW, Format.CenterText(displayWidth, header));
} catch (Exception ex) {
Output.printColorln(Ansi.Color.YELLOW, header);
}

// List the holidays
Object[] keySet = holidays.keySet().toArray();
String keyLeft = "";
String keyRight = "";
for (int l = 0; l < ((holidays.size() + 1) / 2); l++) {
try {
keyLeft = keySet[l].toString();

// Process odd numbers and even numbers differently
if ((holidays.size() % 2) == 0) {
keyRight = keySet[keySet.length / 2 + l].toString();
} else {
keyRight = keySet[(keySet.length + 1) / 2 + l].toString();
}

// Build output data removing the year as it's redundant
String outputLeft = keyLeft.substring(5) + "|" + holidays.get(keyLeft);
String outputRight = keyRight.substring(5) + "|" + holidays.get(keyRight);

// Shorten the holiday name if it's longer than 1/2 the display width
if (outputLeft.length() > (displayWidth / 2 - 1)) {
outputLeft = outputLeft.substring(0, displayWidth / 2 - 5);
outputLeft = outputLeft + "..>";
}

// Display the left item and the spacer
Output.printColor(Ansi.Color.CYAN, outputLeft);
Output.print(" ".repeat((displayWidth / 2) - outputLeft.length()));

// Display the Right column item
Output.printColorln(Ansi.Color.CYAN, outputRight);

} catch (ArrayIndexOutOfBoundsException ex) {
// Display the left side and nothing on the right for odd number of holidays
Output.printColor(Ansi.Color.CYAN, keyLeft.substring(5) + "|" + holidays.get(keyLeft));

} catch (IllegalArgumentException ex) {
Output.printColorln(Ansi.Color.RED, "ERROR: Could not display holiday list correctly");
}
}
}

/**
* queryHolidayListMonth(): Return the holidays for the month provided
*
* @param month
*/
public static StringBuilder queryHolidayListMonth(int mon) {
String month = "";
StringBuilder sb = new StringBuilder();

// Convert the month integer to a string
month = String.valueOf(mon);

Output.printColorln(Ansi.Color.YELLOW, "\nHolidays");

// Loop through the holidays for the current year, printing those in the given month
for (String key : holidays.keySet()) {
if (key.split("-")[1].compareTo(month) == 0) {
// Output.printColorln(Ansi.Color.CYAN, key + " | " + holidays.get(key));
sb.append(key + " | " + holidays.get(key));
sb.append("\n");
}
}
return sb;
}

/**
* queryCountry(): Return the current locale country name as defined by the JVM
*
Expand Down
9 changes: 6 additions & 3 deletions src/main/java/org/fross/cal/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

import java.io.IOException;
import java.io.InputStream;
import java.util.Locale;
import java.util.Properties;

import org.fross.library.Debug;
Expand Down Expand Up @@ -67,6 +68,7 @@ public static void main(String[] args) {

// Display some useful information about the environment if in Debug Mode
Debug.displaySysInfo();
Output.debugPrintln("Current locale set to: " + Locale.getDefault().getDisplayCountry());
Output.debugPrintln("Command Line Options");
Output.debugPrintln(" -D: " + Debug.query());
Output.debugPrintln(" -n: " + Calendar.queryCalsPerRow());
Expand All @@ -88,6 +90,10 @@ public static void main(String[] args) {
// Ensure no negative value is provided for the month and/or year
if (monthAndOrYear <= 0) {
Output.fatalError("Month & Year values must be greater than zero", 6);

// Validate the month is between 1 and 12
} else if (CommandLineArgs.queryMonthToUse() < 1 || CommandLineArgs.queryMonthToUse() > 12) {
Output.fatalError(String.format("'%d' is not a valid month number", CommandLineArgs.queryMonthToUse()), 7);
}

} catch (Exception ex) {
Expand Down Expand Up @@ -117,9 +123,6 @@ public static void main(String[] args) {
case 2:
Calendar.printMonth(CommandLineArgs.queryMonthToUse(), CommandLineArgs.queryYearToUse());
break;

}

}

}
9 changes: 9 additions & 0 deletions src/test/java/org/fross/cal/CalendarTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,15 @@ void testGetCalDays() {
assertEquals("22 23 24 25 26 27 28 ", calDays[3]);
assertEquals("", calDays[4]);
assertEquals(" ", calDays[5]);

// Test output for a November 2027
calDays = Calendar.getCalDays(11, 2027);
assertEquals(" 1 2 3 4 5 6 ", calDays[0]);
assertEquals(" 7 8 9 10 11 12 13 ", calDays[1]);
assertEquals("14 15 16 17 18 19 20 ", calDays[2]);
assertEquals("21 22 23 24 25 26 27 ", calDays[3]);
assertEquals("28 29 30 ", calDays[4]);
assertEquals(" ", calDays[5]);

// And one in the past
calDays = Calendar.getCalDays(12, 71);
Expand Down
97 changes: 97 additions & 0 deletions src/test/java/org/fross/cal/HolidaysTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/******************************************************************************
* Cal - A command line calendar utility
*
* Copyright (c) 2019-2024 Michael Fross
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
******************************************************************************/
package org.fross.cal;

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.util.Locale;
import java.util.TreeMap;

import org.fross.library.Output;
import org.junit.jupiter.api.Test;

class HolidaysTest {

// Test holiday list - US
@Test
void holidayListTestUS() {
// ------------------------------------------------------------------------
// For now, skip this test if the JVM does not report it's in the US
// ------------------------------------------------------------------------
if (Locale.getDefault().getDisplayCountry().toString().compareTo("United States") != 0) {
Output.println("Current locale set to: '" + Locale.getDefault().getDisplayCountry() + "' -- Skipping Test");
return;
}

Output.print("Current locale set to: '" + Locale.getDefault().getDisplayCountry() + "'");

// Get the holiday list for the US in 2023
TreeMap<String, String> holidayListUS = Holidays.getHolidays(2023);

// There should be 12 holidays in 2023
assertEquals(12, holidayListUS.size());

String[] correctValuesUS = { "2023-01-02", "2023-01-16", "2023-02-20", "2023-04-07", "2023-05-29", "2023-06-19", "2023-07-04", "2023-09-04",
"2023-10-09", "2023-11-10", "2023-11-23", "2023-12-25" };

// Loop through the results and verify the keys (dates)
int i = 0;
for (String key : holidayListUS.keySet()) {
assertEquals(correctValuesUS[i], key);
i = i + 1;
}
Output.println("...Holiday Test Complete");

}

// // Test holiday list - CA
// @Test
// void holidayListTestCA() {
// // ------------------------------------------------------------------------
// // Set the default country to Canada
// // ------------------------------------------------------------------------
// Locale.setDefault(Locale.CANADA);
// Output.println("Current locale set to: " + Locale.getDefault().getDisplayCountry());
//
// // Get the holiday list for the 2023 Canadian holidays
// TreeMap<String, String> holidayListCA = Holidays.getHolidays(2024);
//
// // There should be 19 holidays in 2023
// assertEquals(19, holidayListCA.size());
//
// String[] correctValuesCA = { "2024-01-01", "2024-02-19", "2024-03-17", "2024-03-29", "2024-04-01", "2024-04-23", "2024-05-20", "2024-06-21",
// "2024-06-24", "2024-07-01", "2024-07-12", "2024-08-05", "2024-08-19", "2024-09-02", "2024-09-30", "2024-10-14", "2024-11-11", "2024-12-25",
// "2024-12-26" };
//
// // Loop through the results and verify the keys (dates)
// int i = 0;
// for (String key : holidayListCA.keySet()) {
// assertEquals(correctValuesCA[i], key);
// i = i + 1;
// }
//
// Output.println("Canada Holiday Test Complete");
// }
}

0 comments on commit 8972e32

Please sign in to comment.