diff --git a/org.adempiere.base/src/org/compiere/model/MAssignmentSlot.java b/org.adempiere.base/src/org/compiere/model/MAssignmentSlot.java index 495506b4e4..b4524ed190 100644 --- a/org.adempiere.base/src/org/compiere/model/MAssignmentSlot.java +++ b/org.adempiere.base/src/org/compiere/model/MAssignmentSlot.java @@ -140,15 +140,15 @@ public class MAssignmentSlot implements Comparator /** toString displays formatted time from */ public static final int DISPLAY_TIME_FROM = 1; /** toString displays formatted time from-to */ - public static final int DISPLAY_TIME_FROM_TO = 1; + public static final int DISPLAY_TIME_FROM_TO = 2; /** toString displays formatted day time from-to */ - public static final int DISPLAY_DATETIME_FROM_TO = 1; + public static final int DISPLAY_DATETIME_FROM_TO = 3; /** toString displays name */ - public static final int DISPLAY_NAME = 1; + public static final int DISPLAY_NAME = 4; /** toString displays name and optional description */ - public static final int DISPLAY_NAME_DESCRIPTION = 1; + public static final int DISPLAY_NAME_DESCRIPTION = 5; /** toString displays formatted all info */ - public static final int DISPLAY_FULL = 1; + public static final int DISPLAY_FULL = 6; /** DisplayMode */ private int m_displayMode = DISPLAY_FULL; diff --git a/org.adempiere.base/src/org/compiere/util/TimeUtil.java b/org.adempiere.base/src/org/compiere/util/TimeUtil.java index 5b6c522d07..94a300013b 100644 --- a/org.adempiere.base/src/org/compiere/util/TimeUtil.java +++ b/org.adempiere.base/src/org/compiere/util/TimeUtil.java @@ -29,6 +29,7 @@ import org.compiere.model.MCountry; * Time Utilities * * @author Jorg Janke + * @author Teo Sarca, SC ARHIPAC SERVICE SRL * @version $Id: TimeUtil.java,v 1.3 2006/07/30 00:54:35 jjanke Exp $ */ public class TimeUtil @@ -91,7 +92,6 @@ public class TimeUtil static public Calendar getToday () { GregorianCalendar cal = new GregorianCalendar(Language.getLoginLanguage().getLocale()); - // cal.setTimeInMillis(System.currentTimeMillis()); cal.set(Calendar.HOUR_OF_DAY, 0); cal.set(Calendar.MINUTE, 0); cal.set(Calendar.SECOND, 0); @@ -119,9 +119,9 @@ public class TimeUtil } // getNextDay /** - * Get earliest time of next day + * Get earliest time of previous day * @param day day - * @return next day with 00:00 + * @return previous day with 00:00 */ static public Timestamp getPreviousDay (Timestamp day) { @@ -135,12 +135,12 @@ public class TimeUtil cal.set(Calendar.SECOND, 0); cal.set(Calendar.MILLISECOND, 0); return new Timestamp (cal.getTimeInMillis()); - } // getNextDay + } // getPreviousDay /** * Get last date in month * @param day day - * @return last day with 00:00 + * @return last day of month with 00:00 */ static public Timestamp getMonthLastDay (Timestamp day) { @@ -157,7 +157,7 @@ public class TimeUtil cal.set(Calendar.DAY_OF_MONTH, 1); // first cal.add(Calendar.DAY_OF_YEAR, -1); // previous return new Timestamp (cal.getTimeInMillis()); - } // getNextDay + } // getMonthLastDay /** * Return the day and time @@ -181,7 +181,6 @@ public class TimeUtil cal_2.get(Calendar.SECOND)); cal.set(Calendar.MILLISECOND, 0); Timestamp retValue = new Timestamp(cal.getTimeInMillis()); - // log.fine( "TimeUtil.getDayTime", "Day=" + day + ", Time=" + time + " => " + retValue); return retValue; } // getDayTime @@ -208,16 +207,13 @@ public class TimeUtil // case a if (!end_2.after(start_1)) // end not including { - // log.fine( "TimeUtil.InRange - No", start_1 + "->" + end_1 + " " + start_2 + "->" + end_2); return false; } // case c if (!start_2.before(end_1)) // end not including { - // log.fine( "TimeUtil.InRange - No", start_1 + "->" + end_1 + " " + start_2 + "->" + end_2); return false; } - // log.fine( "TimeUtil.InRange - Yes", start_1 + "->" + end_1 + " " + start_2 + "->" + end_2); return true; } // inRange @@ -254,69 +250,55 @@ public class TimeUtil // On same day if (calStart.get(Calendar.YEAR) == calEnd.get(Calendar.YEAR) && calStart.get(Calendar.MONTH) == calEnd.get(Calendar.MONTH) - && calStart.get(Calendar.DAY_OF_MONTH) == calEnd.get(Calendar.DAY_OF_YEAR)) + && calStart.get(Calendar.DAY_OF_MONTH) == calEnd.get(Calendar.DAY_OF_MONTH)) { - if ((!OnSaturday && dayStart == Calendar.SATURDAY) - || (!OnSunday && dayStart == Calendar.SUNDAY) - || (!OnMonday && dayStart == Calendar.MONDAY) - || (!OnTuesday && dayStart == Calendar.TUESDAY) - || (!OnWednesday && dayStart == Calendar.WEDNESDAY) - || (!OnThursday && dayStart == Calendar.THURSDAY) - || (!OnFriday && dayStart == Calendar.FRIDAY)) + if ((OnSaturday && dayStart == Calendar.SATURDAY) + || (OnSunday && dayStart == Calendar.SUNDAY) + || (OnMonday && dayStart == Calendar.MONDAY) + || (OnTuesday && dayStart == Calendar.TUESDAY) + || (OnWednesday && dayStart == Calendar.WEDNESDAY) + || (OnThursday && dayStart == Calendar.THURSDAY) + || (OnFriday && dayStart == Calendar.FRIDAY)) { - // log.fine( "TimeUtil.InRange - SameDay - Yes", start + "->" + end + " - " - // + OnMonday+"-"+OnTuesday+"-"+OnWednesday+"-"+OnThursday+"-"+OnFriday+"="+OnSaturday+"-"+OnSunday); return true; } - // log.fine( "TimeUtil.InRange - SameDay - No", start + "->" + end + " - " - // + OnMonday+"-"+OnTuesday+"-"+OnWednesday+"-"+OnThursday+"-"+OnFriday+"="+OnSaturday+"-"+OnSunday); return false; } - // - // log.fine( "TimeUtil.inRange - WeekDay Start=" + dayStart + ", Incl.End=" + dayEnd); // Calendar.SUNDAY=1 ... SATURDAY=7 BitSet days = new BitSet (8); // Set covered days in BitArray if (dayEnd <= dayStart) dayEnd += 7; - for (int i = dayStart; i < dayEnd; i++) + for (int i = dayStart; i <= dayEnd; i++) { int index = i; if (index > 7) index -= 7; days.set(index); - // System.out.println("Set index=" + index + " i=" + i); } - // for (int i = Calendar.SUNDAY; i <= Calendar.SATURDAY; i++) - // System.out.println("Result i=" + i + " - " + days.get(i)); - // Compare days to availability - if ((!OnSaturday && days.get(Calendar.SATURDAY)) - || (!OnSunday && days.get(Calendar.SUNDAY)) - || (!OnMonday && days.get(Calendar.MONDAY)) - || (!OnTuesday && days.get(Calendar.TUESDAY)) - || (!OnWednesday && days.get(Calendar.WEDNESDAY)) - || (!OnThursday && days.get(Calendar.THURSDAY)) - || (!OnFriday && days.get(Calendar.FRIDAY))) + if ((OnSaturday && days.get(Calendar.SATURDAY)) + || (OnSunday && days.get(Calendar.SUNDAY)) + || (OnMonday && days.get(Calendar.MONDAY)) + || (OnTuesday && days.get(Calendar.TUESDAY)) + || (OnWednesday && days.get(Calendar.WEDNESDAY)) + || (OnThursday && days.get(Calendar.THURSDAY)) + || (OnFriday && days.get(Calendar.FRIDAY))) { - // log.fine( "MAssignment.InRange - Yes", start + "->" + end + " - " - // + OnMonday+"-"+OnTuesday+"-"+OnWednesday+"-"+OnThursday+"-"+OnFriday+"="+OnSaturday+"-"+OnSunday); return true; } - // log.fine( "MAssignment.InRange - No", start + "->" + end + " - " - // + OnMonday+"-"+OnTuesday+"-"+OnWednesday+"-"+OnThursday+"-"+OnFriday+"="+OnSaturday+"-"+OnSunday); return false; - } // isRange + } // inRange /** * Is it the same day * @param one day * @param two compared day - * @return true if the same day + * @return true if one and two is same day */ static public boolean isSameDay (Timestamp one, Timestamp two) { @@ -334,10 +316,10 @@ public class TimeUtil } // isSameDay /** - * Is it the same hour + * Is it the same day and same hour * @param one day/time * @param two compared day/time - * @return true if the same day + * @return true if one and two is same day and hour */ static public boolean isSameHour (Timestamp one, Timestamp two) { @@ -411,8 +393,6 @@ public class TimeUtil calEnd.set(Calendar.SECOND, 0); calEnd.set(Calendar.MILLISECOND, 0); - // System.out.println("Start=" + start + ", End=" + end + ", dayStart=" + cal.get(Calendar.DAY_OF_YEAR) + ", dayEnd=" + calEnd.get(Calendar.DAY_OF_YEAR)); - // in same year if (cal.get(Calendar.YEAR) == calEnd.get(Calendar.YEAR)) { @@ -578,7 +558,7 @@ public class TimeUtil * Is it valid today? * @param validFrom valid from * @param validTo valid to - * @return true if walid + * @return true if today is between validFrom and validTo */ public static boolean isValid (Timestamp validFrom, Timestamp validTo) { @@ -590,7 +570,7 @@ public class TimeUtil * @param validFrom valid from * @param validTo valid to * @param testDate Date - @return true if walid + * @return true if testDate is null or between validFrom and validTo */ public static boolean isValid (Timestamp validFrom, Timestamp validTo, Timestamp testDate) { @@ -637,10 +617,10 @@ public class TimeUtil public static final String TRUNC_YEAR = "Y"; /** - * Get truncated day/time + * Get truncated timestamp (without time) * @param dayTime day - * @param trunc how to truncate TRUNC_* - * @return next day with 00:00 + * @param trunc {@link #TRUNC_DAY}, {@link #TRUNC_WEEK}, {@link #TRUNC_MONTH}, {@link #TRUNC_QUARTER} or {@link #TRUNC_YEAR} + * @return truncated timestamp (without time) */ static public Timestamp trunc (Timestamp dayTime, String trunc) { @@ -669,14 +649,14 @@ public class TimeUtil if (trunc.equals(TRUNC_QUARTER)) { int mm = cal.get(Calendar.MONTH); - if (mm < 4) - mm = 1; - else if (mm < 7) - mm = 4; - else if (mm < 10) - mm = 7; + if (mm < Calendar.APRIL) + mm = Calendar.JANUARY; + else if (mm < Calendar.JULY) + mm = Calendar.APRIL; + else if (mm < Calendar.OCTOBER) + mm = Calendar.JULY; else - mm = 10; + mm = Calendar.OCTOBER; cal.set(Calendar.MONTH, mm); return new Timestamp (cal.getTimeInMillis()); } @@ -685,14 +665,14 @@ public class TimeUtil } // trunc /** - * Returns the day border by combining the date part from dateTime and time part form timeSlot. - * If timeSlot is null, then first milli of the day will be used (if end == false) - * or last milli of the day (if end == true). + * Returns timestamp by combining the date part from dateTime and time part form timeSlot. + * If timeSlot is null, then first millisecond of the day will be used (if end == false) + * or last millisecond of the day (if end == true). * * @param dateTime * @param timeSlot * @param end - * @return + * @return {@link Timestamp} */ public static Timestamp getDayBorder(Timestamp dateTime, Timestamp timeSlot, boolean end) { @@ -729,32 +709,11 @@ public class TimeUtil } - /** - * Test - * @param args ignored - */ - public static void main (String[] args) - { - Timestamp t1 = getDay(01, 01, 01); - Timestamp t2 = getDay(02, 02, 02); - Timestamp t3 = getDay(03, 03, 03); - - Timestamp t4 = getDay(01, 01, 01); - Timestamp t5 = getDay(02, 02, 02); - - System.out.println(t1 + " - " + t3); - System.out.println(t2 + " - " + isValid (t1,t3, t2)); - System.out.println(isSameDay(t1, t4) + " == true" ); - System.out.println(isSameDay(t2, t5) + " == true"); - System.out.println(isSameDay(t3, t5) + " == false"); - } // main - // ARHIPAC: TEO: ADDITION ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ /** * [ ARHIPAC ] Gets calendar instance of given date * @param date calendar initialization date; if null, the current date is used * @return calendar - * author Teo Sarca, SC ARHIPAC SERVICE SRL */ static public Calendar getCalendar(Timestamp date) { @@ -790,7 +749,6 @@ public class TimeUtil * @param day Day; if null current time will be used * @param offset months offset * @return Day + offset (time will be 00:00) - * @return Teo Sarca, SC ARHIPAC SERVICE SRL */ static public Timestamp addMonths (Timestamp day, int offset) { @@ -809,6 +767,12 @@ public class TimeUtil return new Timestamp (cal.getTimeInMillis()); } // addMonths + /** + * + * @param start + * @param end + * @return number of months between start and end + */ public static int getMonthsBetween (Timestamp start, Timestamp end) { Calendar startCal = getCalendar(start); @@ -818,7 +782,14 @@ public class TimeUtil - (startCal.get(Calendar.YEAR) * 12 + startCal.get(Calendar.MONTH)); } - /** Returns start date + nbDays which cannot be saturday or sunday or non business days */ + /** + * + * @param startDate + * @param nbDays number of days + * @param clientID AD_Client_ID + * @param trxName + * @return start date + nbDays which cannot be saturday or sunday or non business days + */ public static Timestamp addOnlyBusinessDays(Timestamp startDate, int nbDays, int clientID, String trxName) { Timestamp retValue = startDate; @@ -831,13 +802,28 @@ public class TimeUtil return retValue; } - /** Returns number of non business days between 2 dates for the country based on current tenant language */ + /** + * + * @param startDate + * @param endDate + * @param clientID + * @param trxName + * @return number of business days between 2 dates for the country based on current default country + */ public static int getBusinessDaysBetween(Timestamp startDate, Timestamp endDate, int clientID, String trxName) { return getBusinessDaysBetween(startDate, endDate, clientID, MCountry.getDefault().getC_Country_ID(), trxName); } - /** Returns number of non business days between 2 dates for a specified country */ + /** + * + * @param startDate + * @param endDate + * @param clientID + * @param countryID + * @param trxName + * @return number of business days between 2 dates for a specified country + */ public static int getBusinessDaysBetween(Timestamp startDate, Timestamp endDate, int clientID, int countryID, String trxName) { int retValue = 0; @@ -870,7 +856,7 @@ public class TimeUtil calEnd.set(Calendar.SECOND, 0); calEnd.set(Calendar.MILLISECOND, 0); - while (cal.before(calEnd) || cal.equals(calEnd)) { + while (cal.before(calEnd)) { if (nbd == null || !nbd.contains(new Timestamp(cal.getTimeInMillis()))) { if (cal.get(Calendar.DAY_OF_WEEK) != Calendar.SATURDAY && cal.get(Calendar.DAY_OF_WEEK) != Calendar.SUNDAY) { retValue++; diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/WSchedule.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/WSchedule.java index 6fb0a44333..a7ba3f43f5 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/WSchedule.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/WSchedule.java @@ -266,24 +266,8 @@ public class WSchedule extends Window implements EventListener for(MAssignmentSlot mas : list) { SimpleCalendarEvent event = new SimpleCalendarEvent(); - Timestamp startTime = mas.getStartTime(); - Timestamp endTime = mas.getEndTime(); - Calendar calStart = Calendar.getInstance(); - calStart.setTime(startTime); - Calendar calEnd = Calendar.getInstance(); - calEnd.setTime(endTime); - - calStart.add(Calendar.DAY_OF_MONTH, 1); - if (calStart.get(Calendar.YEAR) == calEnd.get(Calendar.YEAR) && calStart.get(Calendar.MONTH) == calEnd.get(Calendar.MONTH) - && calStart.get(Calendar.DAY_OF_MONTH) == calEnd.get(Calendar.DAY_OF_MONTH)) { - if (calEnd.get(Calendar.HOUR_OF_DAY) == 0 && calEnd.get(Calendar.MINUTE) == 0) { - calEnd.add(Calendar.DAY_OF_MONTH, -1); - calEnd.set(Calendar.HOUR_OF_DAY, 23); - } - } - - event.setBeginDate(startTime); - event.setEndDate(calEnd.getTime()); + event.setBeginDate(mas.getStartTime()); + event.setEndDate(mas.getEndTime()); event.setTitle(mas.getName()); event.setContent(mas.getDescription() != null ? mas.getDescription() : mas.getName()); event.setHeaderColor('#'+ZkCssHelper.createHexColorString(mas.getColor(true))); diff --git a/org.idempiere.test/src/org/idempiere/test/DictionaryIDs.java b/org.idempiere.test/src/org/idempiere/test/DictionaryIDs.java index 98117fb4fd..3f7456a3fa 100644 --- a/org.idempiere.test/src/org/idempiere/test/DictionaryIDs.java +++ b/org.idempiere.test/src/org/idempiere/test/DictionaryIDs.java @@ -117,6 +117,16 @@ public final class DictionaryIDs { } } + public enum C_Calendar { + GARDENWORLD_CALENDAR(102); + + public final int id; + + private C_Calendar(int id) { + this.id = id; + } + } + public enum C_Charge { BANK(100), COMMISSIONS(101), diff --git a/org.idempiere.test/src/org/idempiere/test/base/TimeUtilTest.java b/org.idempiere.test/src/org/idempiere/test/base/TimeUtilTest.java new file mode 100644 index 0000000000..0aa28a09eb --- /dev/null +++ b/org.idempiere.test/src/org/idempiere/test/base/TimeUtilTest.java @@ -0,0 +1,272 @@ +/*********************************************************************** + * This file is part of iDempiere ERP Open Source * + * http://www.idempiere.org * + * * + * Copyright (C) Contributors * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301, USA. * + * * + * Contributors: * + * - hengsin * + **********************************************************************/ +package org.idempiere.test.base; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; + +import java.sql.Timestamp; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.GregorianCalendar; + +import org.compiere.model.X_C_NonBusinessDay; +import org.compiere.util.DB; +import org.compiere.util.Env; +import org.compiere.util.Language; +import org.compiere.util.TimeUtil; +import org.idempiere.test.AbstractTestCase; +import org.idempiere.test.DictionaryIDs; +import org.junit.jupiter.api.Test; + +public class TimeUtilTest extends AbstractTestCase { + + public TimeUtilTest() { + } + + @Test + public void testTrunc() { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); + + try { + GregorianCalendar cal = new GregorianCalendar(Language.getLoginLanguage().getLocale()); + Timestamp source = Timestamp.from(sdf.parse("2022-10-28 11:11:00.000").toInstant()); + + Timestamp dayTarget = Timestamp.from(sdf.parse("2022-10-28 00:00:00.000").toInstant()); + Timestamp truncated = TimeUtil.trunc(source, TimeUtil.TRUNC_DAY); + assertEquals(dayTarget, truncated, "TRUNC_DAY not working as expected"); + + Timestamp weekTarget = null; + if (cal.getFirstDayOfWeek() == Calendar.SUNDAY) + weekTarget = Timestamp.from(sdf.parse("2022-10-23 00:00:00.000").toInstant()); + else + weekTarget = Timestamp.from(sdf.parse("2022-10-24 00:00:00.000").toInstant()); + truncated = TimeUtil.trunc(source, TimeUtil.TRUNC_WEEK); + assertEquals(weekTarget, truncated, "TRUNC_WEEK not working as expected"); + + Timestamp monthTarget = Timestamp.from(sdf.parse("2022-10-01 00:00:00.000").toInstant()); + truncated = TimeUtil.trunc(source, TimeUtil.TRUNC_MONTH); + assertEquals(monthTarget, truncated, "TRUNC_MONTH not working as expected"); + + Timestamp yearTarget = Timestamp.from(sdf.parse("2022-01-01 00:00:00.000").toInstant()); + truncated = TimeUtil.trunc(source, TimeUtil.TRUNC_YEAR); + assertEquals(yearTarget, truncated, "TRUNC_YEAR not working as expected"); + + Timestamp quarter4 = Timestamp.from(sdf.parse("2022-10-01 00:00:00.000").toInstant()); + truncated = TimeUtil.trunc(source, TimeUtil.TRUNC_QUARTER); + assertEquals(quarter4, truncated, "TRUNC_QUARTER not working as expected for October"); + + source = Timestamp.from(sdf.parse("2022-09-28 11:11:00.000").toInstant()); + Timestamp quarter3 = Timestamp.from(sdf.parse("2022-07-01 00:00:00.000").toInstant()); + truncated = TimeUtil.trunc(source, TimeUtil.TRUNC_QUARTER); + assertEquals(quarter3, truncated, "TRUNC_QUARTER not working as expected for September"); + + source = Timestamp.from(sdf.parse("2022-06-28 11:11:00.000").toInstant()); + Timestamp quarter2 = Timestamp.from(sdf.parse("2022-04-01 00:00:00.000").toInstant()); + truncated = TimeUtil.trunc(source, TimeUtil.TRUNC_QUARTER); + assertEquals(quarter2, truncated, "TRUNC_QUARTER not working as expected for June"); + + source = Timestamp.from(sdf.parse("2022-03-28 11:11:00.000").toInstant()); + Timestamp quarter1 = Timestamp.from(sdf.parse("2022-01-01 00:00:00.000").toInstant()); + truncated = TimeUtil.trunc(source, TimeUtil.TRUNC_QUARTER); + assertEquals(quarter1, truncated, "TRUNC_QUARTER not working as expected for March"); + } catch (ParseException e) { + fail(e); + } + } + + @Test + public void testGetDay() { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); + try { + Timestamp source = Timestamp.from(sdf.parse("2022-10-28 11:11:00.000").toInstant()); + Timestamp dayTarget = Timestamp.from(sdf.parse("2022-10-28 00:00:00.000").toInstant()); + assertEquals(dayTarget, TimeUtil.getDay(source), "getDay not working as expected"); + + Timestamp nextDayTarget = Timestamp.from(sdf.parse("2022-10-29 00:00:00.000").toInstant()); + assertEquals(nextDayTarget, TimeUtil.getNextDay(source), "getNextDay not working as expected"); + + Timestamp previousDayTarget = Timestamp.from(sdf.parse("2022-10-27 00:00:00.000").toInstant()); + assertEquals(previousDayTarget, TimeUtil.getPreviousDay(source), "getPreviousDay not working as expected"); + + Timestamp monthLastDayTarget = Timestamp.from(sdf.parse("2022-10-31 00:00:00.000").toInstant()); + assertEquals(monthLastDayTarget, TimeUtil.getMonthLastDay(source), "getMonthLastDay not working as expected"); + + Timestamp monthFirstDayTarget = Timestamp.from(sdf.parse("2022-10-01 00:00:00.000").toInstant()); + assertEquals(monthFirstDayTarget, TimeUtil.getMonthFirstDay(source), "getMonthFirstDay not working as expected"); + + Timestamp from = Timestamp.from(sdf.parse("2022-10-01 00:00:00.000").toInstant());; + Timestamp to = source; + assertEquals(27, TimeUtil.getDaysBetween(from, to), "getDaysBetween not working as expected for positive difference"); + assertEquals(-27, TimeUtil.getDaysBetween(to, from), "getDaysBetween not working as expected for negative difference"); + + from = Timestamp.from(sdf.parse("2021-10-01 00:00:00.000").toInstant()); + assertEquals(392, TimeUtil.getDaysBetween(from, source), "getDaysBetween not working as expected for cross year positive difference"); + assertEquals(-392, TimeUtil.getDaysBetween(source, from), "getDaysBetween not working as expected for cross year negative difference"); + assertEquals(12, TimeUtil.getMonthsBetween(from, source), "getMonthsBetween not working as expected"); + + Timestamp datePart = Timestamp.from(sdf.parse("2022-09-28 00:00:00.000").toInstant()); + Timestamp timePart = source; + Timestamp combine = Timestamp.from(sdf.parse("2022-09-28 11:11:00.000").toInstant()); + assertEquals(combine, TimeUtil.getDayBorder(datePart, timePart, false), "getDayBorder doesn't combine date part and time part as expected"); + assertEquals(combine, TimeUtil.getDayTime(datePart, timePart), "getDayTime doesn't combine date part and time part as expected"); + assertEquals(datePart, TimeUtil.getDayBorder(combine, null, false), "getDayBorder doesn't return start of day date as expected"); + Timestamp endOfDay = Timestamp.from(sdf.parse("2022-09-28 23:59:59.999").toInstant()); + assertEquals(endOfDay, TimeUtil.getDayBorder(combine, null, true), "getDayBorder doesn't return end of day date as expected"); + } catch (ParseException e) { + fail(e); + } + } + + @Test + public void testValidation() { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); + + try { + //end1 in range2 + Timestamp from1 = Timestamp.from(sdf.parse("2022-10-20 00:00:00.000").toInstant()); + Timestamp to1 = Timestamp.from(sdf.parse("2022-10-25 00:00:00.000").toInstant()); + Timestamp from2 = Timestamp.from(sdf.parse("2022-10-24 00:00:00.000").toInstant()); + Timestamp to2 = Timestamp.from(sdf.parse("2022-10-28 00:00:00.000").toInstant()); + assertTrue(TimeUtil.inRange(from1, to1, from2, to2), "Wrong inRange validation"); + + //range1 before range2 + to1 = Timestamp.from(sdf.parse("2022-10-23 00:00:00.000").toInstant()); + assertFalse(TimeUtil.inRange(from1, to1, from2, to2), "Wrong inRange validation"); + + //start1 in range2 + from1 = Timestamp.from(sdf.parse("2022-10-26 00:00:00.000").toInstant()); + to1 = Timestamp.from(sdf.parse("2022-10-30 00:00:00.000").toInstant()); + assertTrue(TimeUtil.inRange(from1, to1, from2, to2), "Wrong inRange validation"); + + //start1 = end of range2 + from1 = Timestamp.from(sdf.parse("2022-10-28 00:00:00.000").toInstant()); + assertFalse(TimeUtil.inRange(from1, to1, from2, to2), "Wrong inRange validation"); + + //end1 = start of range2 + from1 = Timestamp.from(sdf.parse("2022-10-20 00:00:00.000").toInstant()); + to1 = Timestamp.from(sdf.parse("2022-10-24 00:00:00.000").toInstant()); + assertFalse(TimeUtil.inRange(from1, to1, from2, to2), "Wrong inRange validation"); + + //range1 after range2 + from1 = Timestamp.from(sdf.parse("2022-10-25 00:00:00.000").toInstant()); + to1 = Timestamp.from(sdf.parse("2022-10-27 00:00:00.000").toInstant()); + assertTrue(TimeUtil.inRange(from1, to1, from2, to2), "Wrong inRange validation"); + + //in range for test against day of week + Calendar cal = TimeUtil.getToday(); + cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY); + from1 = new Timestamp(cal.getTimeInMillis()); + cal.set(Calendar.DAY_OF_WEEK, Calendar.WEDNESDAY); + to1 = new Timestamp(cal.getTimeInMillis()); + assertFalse(TimeUtil.inRange(from1, to1, false, false, false, false, true, true, true), "Invalid inRange validation"); + assertTrue(TimeUtil.inRange(from1, to1, false, true, false, false, false, false, false), "Invalid inRange validation"); + + //same day and same hour check + from1 = Timestamp.from(sdf.parse("2022-10-20 00:00:00.000").toInstant()); + to1 = Timestamp.from(sdf.parse("2022-10-24 00:00:00.000").toInstant()); + assertFalse(TimeUtil.isSameDay(from1, to1), "Invalid isSameDay validation"); + + from1 = Timestamp.from(sdf.parse("2022-10-20 00:00:00.000").toInstant()); + to1 = Timestamp.from(sdf.parse("2022-10-20 00:00:00.000").toInstant()); + assertTrue(TimeUtil.isSameDay(from1, to1), "Invalid isSameDay validation"); + + from1 = Timestamp.from(sdf.parse("2022-10-20 01:00:00.000").toInstant()); + to1 = Timestamp.from(sdf.parse("2022-10-24 01:00:00.000").toInstant()); + assertFalse(TimeUtil.isSameHour(from1, to1), "Invalid isSameHour validation"); + + to1 = Timestamp.from(sdf.parse("2022-10-20 02:00:00.000").toInstant()); + assertFalse(TimeUtil.isSameHour(from1, to1), "Invalid isSameHour validation"); + + to1 = Timestamp.from(sdf.parse("2022-10-20 01:00:00.000").toInstant()); + assertTrue(TimeUtil.isSameHour(from1, to1), "Invalid isSameHour validation"); + + //is all day + from1 = Timestamp.from(sdf.parse("2022-10-20 00:00:00.000").toInstant()); + to1 = Timestamp.from(sdf.parse("2022-10-20 00:00:00.000").toInstant()); + assertFalse(TimeUtil.isAllDay(from1, to1), "Invalid isAllDay validation"); + + to1 = Timestamp.from(sdf.parse("2022-10-21 00:00:00.000").toInstant()); + assertTrue(TimeUtil.isAllDay(from1, to1), "Invalid isAllDay validation"); + + //isvalid + from1 = TimeUtil.getDay(System.currentTimeMillis()); + to1 = TimeUtil.addDays(from1, 1); + assertTrue(TimeUtil.isValid(from1, to1), "Invalid isValid validation"); + + from1 = TimeUtil.addDays(from1, -2); + to1 = TimeUtil.addDays(from1, 1); + assertFalse(TimeUtil.isValid(from1, to1), "Invalid isValid validation"); + + Timestamp test1 = TimeUtil.addDays(to1, 1); + assertFalse(TimeUtil.isValid(from1, to1, test1), "Invalid isValid validation"); + + test1 = TimeUtil.addDays(from1, 1); + to1 = TimeUtil.addDays(from1, 1); + assertTrue(TimeUtil.isValid(from1, to1, test1), "Invalid isValid validation"); + + to1 = TimeUtil.addDays(to1, 1); + assertTrue(TimeUtil.isValid(from1, to1, test1), "Invalid isValid validation"); + } catch (ParseException e) { + fail(e); + } + } + + @Test + public void testNonBusinessDays() { + Calendar cal = TimeUtil.getToday(); + cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY); + Timestamp from = new Timestamp(cal.getTimeInMillis()); + cal.set(Calendar.DAY_OF_WEEK, Calendar.FRIDAY); + Timestamp to = new Timestamp(cal.getTimeInMillis()); + //make sure no non business days records + DB.executeUpdateEx("DELETE FROM C_NonBusinessDay WHERE AD_Client_ID=? AND Date1 BETWEEN ? AND ?", new Object[] {getAD_Client_ID(), from, to}, getTrxName()); + + //test add + cal.set(Calendar.DAY_OF_WEEK, Calendar.WEDNESDAY); + Timestamp expected = new Timestamp(cal.getTimeInMillis()); + assertEquals(expected, TimeUtil.addOnlyBusinessDays(from, 2, getAD_Client_ID(), getTrxName())); + + X_C_NonBusinessDay nbd = new X_C_NonBusinessDay(Env.getCtx(), 0, getTrxName()); + nbd.setName("testNonBusinessDays1"); + cal.set(Calendar.DAY_OF_WEEK, Calendar.TUESDAY); + nbd.setDate1(new Timestamp(cal.getTimeInMillis())); + nbd.setC_Calendar_ID(DictionaryIDs.C_Calendar.GARDENWORLD_CALENDAR.id); + nbd.saveEx(); + cal.set(Calendar.DAY_OF_WEEK, Calendar.THURSDAY); + expected = new Timestamp(cal.getTimeInMillis()); + assertEquals(expected, TimeUtil.addOnlyBusinessDays(from, 2, getAD_Client_ID(), getTrxName())); + + //get business days + to = expected; + assertEquals(2, TimeUtil.getBusinessDaysBetween(from, to, getAD_Client_ID(), getTrxName())); + nbd.deleteEx(true); + assertEquals(3, TimeUtil.getBusinessDaysBetween(from, to, getAD_Client_ID(), getTrxName())); + } +} +