diff --git a/district-scripts/SWF/GateFlow5.py b/district-scripts/SWF/GateFlow5.py index d0d4e3f..affa042 100644 --- a/district-scripts/SWF/GateFlow5.py +++ b/district-scripts/SWF/GateFlow5.py @@ -2,30 +2,32 @@ def run_calculations(registry): + from datetime import datetime, timedelta, timezone + from zoneinfo import ZoneInfo + # Java imports must happen after regi_session starts the JVM. - from java.util import Calendar - from java.util import TimeZone from usace.rowcps.headless import LoggingOptions - def compute_All_Flowgroups(officeID, location, startCal, endCal): + + def compute_All_Flowgroups(officeID, location, start_date, end_date): # Takes in locations defined by user in group and computes all flow groups try: - gateCalc.computeAll(officeID, location, startCal.getTime(), endCal.getTime()) + gateCalc.computeAll(officeID, location, start_date, end_date) except Exception as e: print("Error Computing all Flow Groups at {0} {1}".format(officeID, location)) print(e) print('') - def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): + def compute_Single_Flowgroup(officeID, location, start_date, end_date, flowGroup): try: - gateCalc.computeFlowGroup(officeID, location, startCal.getTime(), endCal.getTime(), "Flow.{0}.{1}".format(location, flowGroup)) + gateCalc.computeFlowGroup(officeID, location, start_date, end_date, "Flow.{0}.{1}".format(location, flowGroup)) except Exception as e: print("Error Computing Flow Group {0} at {1}".format(officeID, location)) print(e) print('') - # #gateCalc.computeFlowGroup("SWF", "ACTT2", startCal.getTime(), endCal.getTime(), "Flow.ACTT2.Pump_Out_Total") + # #gateCalc.computeFlowGroup("SWF", "ACTT2", start_date, end_date, "Flow.ACTT2.Pump_Out_Total") # Description of: LoggingOptions.setDbMessageLevel(int level) # # Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended @@ -65,30 +67,21 @@ def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): # this retrieves a Gate Flow calculation object gateCalc = registry.getCalculation(1.0, "Gate Flow") - # Time zone must be set because the Solaris time zone is UTC - timeZone = TimeZone.getTimeZone("US/Central") - # the gate flow calculations requires a start and end time. - # here we create a java Calendar object that will be used to create the start Date - startCal = Calendar.getInstance(timeZone) - # startCal.clear() - startCal.add(Calendar.DAY_OF_MONTH, -8) - startCal.set(Calendar.HOUR_OF_DAY, 0) - startCal.set(Calendar.MINUTE, 0) - startCal.set(Calendar.SECOND, 0) - startCal.set(Calendar.MILLISECOND, 0) - # startCal.set(Calendar.YEAR, 2015) - # startCal.set(Calendar.MONTH, 9) - - # create a java Calendar object that will be used to create the end Date - endCal = Calendar.getInstance(timeZone) - # endCal.clear() - endCal.add(Calendar.DAY_OF_MONTH, 1) - endCal.set(Calendar.HOUR_OF_DAY, 0) - endCal.set(Calendar.MINUTE, 0) - endCal.set(Calendar.SECOND, 0) - endCal.set(Calendar.MILLISECOND, 0) - # endCal.set(Calendar.YEAR, 2015) - # endCal.set(Calendar.MONTH, 11) + # Time zone must be set explicitly because the JVM's default timezone is + # UTC, not the district's local time. + central = ZoneInfo("America/Chicago") + + # start of the day 8 days ago, local midnight + start_date_dt = (datetime.now(central) - timedelta(days=8)).replace( + hour=0, minute=0, second=0, microsecond=0 + ) + # end of today: tomorrow's local midnight + end_date_dt = start_date_dt + timedelta(days=9) + # Dates can be adjusted with normal datetime arithmetic/replace, e.g.: + # start_date_dt = start_date_dt.replace(year=2015, month=10) # month is 1-indexed here + + start_date = start_date_dt.astimezone(timezone.utc) + end_date = end_date_dt.astimezone(timezone.utc) officeID = "SWF" @@ -98,7 +91,7 @@ def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): # projectId # startDate # endDate - # gateCalc.computeFlowGroup("SWF", "LEWT2", startCal.getTime(), endCal.getTime(), "Flow.LEWT2.ConduitGate_Total") + # gateCalc.computeFlowGroup("SWF", "LEWT2", start_date, end_date, "Flow.LEWT2.ConduitGate_Total") # By setting the following parameter to True, the following flow groups in the list FlowGroupList will all be calculated. Items can be commented out # or commented back in individually. To turn this option off, set the following parameter to False. User can determine which flow group they want to calculate @@ -189,10 +182,10 @@ def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): if calculateAllFlowGroups: for location in FlowGroupList: print("Now Running", location, "GROUP") - compute_All_Flowgroups(officeID, location, startCal, endCal) + compute_All_Flowgroups(officeID, location, start_date, end_date) - compute_Single_Flowgroup(officeID, "JSPT2", startCal, endCal, "Turbine1") - compute_Single_Flowgroup(officeID, "JSPT2", startCal, endCal, "Turbine2") + compute_Single_Flowgroup(officeID, "JSPT2", start_date, end_date, "Turbine1") + compute_Single_Flowgroup(officeID, "JSPT2", start_date, end_date, "Turbine2") #if calculateSingleFlowGroups: diff --git a/district-scripts/SWF/GateFlow_MonthlyPumpBackFill.py b/district-scripts/SWF/GateFlow_MonthlyPumpBackFill.py index 7bb1ae5..7a0e269 100644 --- a/district-scripts/SWF/GateFlow_MonthlyPumpBackFill.py +++ b/district-scripts/SWF/GateFlow_MonthlyPumpBackFill.py @@ -2,29 +2,32 @@ def run_calculations(registry): + from datetime import datetime, timezone + from zoneinfo import ZoneInfo + # Java imports must happen after regi_session starts the JVM. - from java.util import Calendar from usace.rowcps.headless import LoggingOptions - def compute_All_Flowgroups(officeID, location, startCal, endCal): + + def compute_All_Flowgroups(officeID, location, start_date, end_date): # Takes in locations defined by user in group and computes all flow groups try: - gateCalc.computeAll(officeID, location, startCal.getTime(), endCal.getTime()) + gateCalc.computeAll(officeID, location, start_date, end_date) except Exception as e: print("Error Computing all Flow Groups at {0} {1}".format(officeID, location)) print(e) print('') - def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): + def compute_Single_Flowgroup(officeID, location, start_date, end_date, flowGroup): try: - gateCalc.computeFlowGroup(officeID, location, startCal.getTime(), endCal.getTime(), "Flow.{0}.{1}".format(location, flowGroup)) + gateCalc.computeFlowGroup(officeID, location, start_date, end_date, "Flow.{0}.{1}".format(location, flowGroup)) except Exception as e: print("Error Computing Flow Group {0} at {1}".format(officeID, location)) print(e) print('') - # #gateCalc.computeFlowGroup("SWF", "ACTT2", startCal.getTime(), endCal.getTime(), "Flow.ACTT2.Pump_Out_Total") + # #gateCalc.computeFlowGroup("SWF", "ACTT2", start_date, end_date, "Flow.ACTT2.Pump_Out_Total") # Description of: LoggingOptions.setDbMessageLevel(int level) # # Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended @@ -64,41 +67,22 @@ def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): # this retrieves a Gate Flow calculation object gateCalc = registry.getCalculation(1.0, "Gate Flow") - # the gate flow calculations requires a start and end time. - # here we create a java Calendar object that will be used to create the start Date - startCal = Calendar.getInstance() - # startCal.clear() - startCal.set(Calendar.HOUR, 0) ### set startCal hour/minute/second/millisecond to 0 for midnight - startCal.set(Calendar.MINUTE, 0) - startCal.set(Calendar.SECOND, 0) - startCal.set(Calendar.MILLISECOND, 0) - startCal.add(Calendar.YEAR, -1) ### go back one year to today - startCal.set(Calendar.MONTH, 9) ### change month to month 9 (october) - startCal.set(Calendar.DAY_OF_MONTH, 1) ### change start date to start of the month day 1 - - getYear = startCal.get(Calendar.YEAR) ### get value of startCal year/month/day to print and to initilize endCal - getMonth = startCal.get(Calendar.MONTH) - getDayofMonth = startCal.get(Calendar.DAY_OF_MONTH) - - # create a java Calendar object that will be used to create the end Date - endCal = Calendar.getInstance() - # endCal.clear() - endCal.set(Calendar.HOUR, 0) ### set endCal hour/minute/second/millisecond to 0 for midnight - endCal.set(Calendar.MINUTE, 0) - endCal.set(Calendar.SECOND, 0) - endCal.set(Calendar.MILLISECOND, 0) - ###endCal will be set to current date unless reset with the following 4 lines - #endCal.set(Calendar.YEAR, getYear) ### set endCal year same as startCal - #endCal.set(Calendar.MONTH, getMonth) ### set endCal month same as startCal - #endCal.add(Calendar.MONTH, 12) ##add 1 month to startcal month - #endCal.set(Calendar.DAY_OF_MONTH, 1) ### set to day one - - ### time window starts 01Feb2019(one year ago) and ends 01Mar2019 (one year ago plus one month) - - getEndDay = endCal.get(Calendar.DAY_OF_MONTH) - getEndYear = endCal.get(Calendar.YEAR) - getEndMonth = endCal.get(Calendar.MONTH) + # Time zone must be set explicitly because the JVM's default timezone is + # UTC, not the district's local time. (The previous Calendar.getInstance() + # calls here had no explicit timezone and silently depended on whatever + # timezone the host happened to be configured with.) + central = ZoneInfo("America/Chicago") + today = datetime.now(central) + + # start: October 1st of last year, at midnight + start_date_dt = today.replace( + year=today.year - 1, month=10, day=1, hour=0, minute=0, second=0, microsecond=0 + ) + # end: today, at midnight + end_date_dt = today.replace(hour=0, minute=0, second=0, microsecond=0) + start_date = start_date_dt.astimezone(timezone.utc) + end_date = end_date_dt.astimezone(timezone.utc) officeID = "SWF" @@ -108,7 +92,7 @@ def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): # projectId # startDate # endDate - # gateCalc.computeFlowGroup("SWF", "LEWT2", startCal.getTime(), endCal.getTime(), "Flow.LEWT2.ConduitGate_Total") + # gateCalc.computeFlowGroup("SWF", "LEWT2", start_date, end_date, "Flow.LEWT2.ConduitGate_Total") # By setting the following parameter to True, the following flow groups in the list FlowGroupList will all be calculated. Items can be commented out # or commented back in individually. To turn this option off, set the following parameter to False. User can determine which flow group they want to calculate # by changing the "flowGroup" variable. @@ -191,17 +175,17 @@ def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): if calculateSingleFlowGroups: for location in locationList: print("Now Running", location, "SINGLE") - #compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupGate) - #compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupTotal) - #compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupTurbine) - #compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupUncontrol) - #compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupPumpOutBelow) - compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupPumpOut) - compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupPumpIn) + #compute_Single_Flowgroup(officeID, location, start_date, end_date, flowGroupGate) + #compute_Single_Flowgroup(officeID, location, start_date, end_date, flowGroupTotal) + #compute_Single_Flowgroup(officeID, location, start_date, end_date, flowGroupTurbine) + #compute_Single_Flowgroup(officeID, location, start_date, end_date, flowGroupUncontrol) + #compute_Single_Flowgroup(officeID, location, start_date, end_date, flowGroupPumpOutBelow) + compute_Single_Flowgroup(officeID, location, start_date, end_date, flowGroupPumpOut) + compute_Single_Flowgroup(officeID, location, start_date, end_date, flowGroupPumpIn) if calculateAllFlowGroups: for location in FlowGroupList: print("Now Running", location, "GROUP") - #compute_All_Flowgroups(officeID, location, startCal, endCal) + #compute_All_Flowgroups(officeID, location, start_date, end_date) diff --git a/district-scripts/SWF/GateFlow_PumpBackFill.py b/district-scripts/SWF/GateFlow_PumpBackFill.py index bc58977..bdedf10 100644 --- a/district-scripts/SWF/GateFlow_PumpBackFill.py +++ b/district-scripts/SWF/GateFlow_PumpBackFill.py @@ -2,29 +2,32 @@ def run_calculations(registry): + from datetime import datetime, timedelta, timezone + from zoneinfo import ZoneInfo + # Java imports must happen after regi_session starts the JVM. - from java.util import Calendar from usace.rowcps.headless import LoggingOptions - def compute_All_Flowgroups(officeID, location, startCal, endCal): + + def compute_All_Flowgroups(officeID, location, start_date, end_date): # Takes in locations defined by user in group and computes all flow groups try: - gateCalc.computeAll(officeID, location, startCal.getTime(), endCal.getTime()) + gateCalc.computeAll(officeID, location, start_date, end_date) except Exception as e: print("Error Computing all Flow Groups at {0} {1}".format(officeID, location)) print(e) print('') - def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): + def compute_Single_Flowgroup(officeID, location, start_date, end_date, flowGroup): try: - gateCalc.computeFlowGroup(officeID, location, startCal.getTime(), endCal.getTime(), "Flow.{0}.{1}".format(location, flowGroup)) + gateCalc.computeFlowGroup(officeID, location, start_date, end_date, "Flow.{0}.{1}".format(location, flowGroup)) except Exception as e: print("Error Computing Flow Group {0} at {1}".format(officeID, location)) print(e) print('') - # #gateCalc.computeFlowGroup("SWF", "ACTT2", startCal.getTime(), endCal.getTime(), "Flow.ACTT2.Pump_Out_Total") + # #gateCalc.computeFlowGroup("SWF", "ACTT2", start_date, end_date, "Flow.ACTT2.Pump_Out_Total") # Description of: LoggingOptions.setDbMessageLevel(int level) # # Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended @@ -64,28 +67,20 @@ def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): # this retrieves a Gate Flow calculation object gateCalc = registry.getCalculation(1.0, "Gate Flow") - # the gate flow calculations requires a start and end time. - # here we create a java Calendar object that will be used to create the start Date - startCal = Calendar.getInstance() - # startCal.clear() - startCal.add(Calendar.DAY_OF_MONTH, -1) - startCal.set(Calendar.HOUR, 0) - startCal.set(Calendar.MINUTE, 0) - startCal.set(Calendar.SECOND, 0) - startCal.set(Calendar.MILLISECOND, 0) - # startCal.set(Calendar.YEAR, 2015) - # startCal.set(Calendar.MONTH, 9) - - # create a java Calendar object that will be used to create the end Date - endCal = Calendar.getInstance() - # endCal.clear() - endCal.add(Calendar.DAY_OF_MONTH, 0) - endCal.set(Calendar.HOUR, 0) - endCal.set(Calendar.MINUTE, 0) - endCal.set(Calendar.SECOND, 0) - endCal.set(Calendar.MILLISECOND, 0) - # endCal.set(Calendar.YEAR, 2015) - # endCal.set(Calendar.MONTH, 11) + # Time zone must be set explicitly because the JVM's default timezone is + # UTC, not the district's local time. (The previous Calendar.getInstance() + # calls here had no explicit timezone and silently depended on whatever + # timezone the host happened to be configured with.) + central = ZoneInfo("America/Chicago") + today_midnight = datetime.now(central).replace(hour=0, minute=0, second=0, microsecond=0) + + # start: yesterday, at midnight + start_date_dt = today_midnight - timedelta(days=1) + # end: today, at midnight + end_date_dt = today_midnight + + start_date = start_date_dt.astimezone(timezone.utc) + end_date = end_date_dt.astimezone(timezone.utc) officeID = "SWF" @@ -95,7 +90,7 @@ def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): # projectId # startDate # endDate - # gateCalc.computeFlowGroup("SWF", "LEWT2", startCal.getTime(), endCal.getTime(), "Flow.LEWT2.ConduitGate_Total") + # gateCalc.computeFlowGroup("SWF", "LEWT2", start_date, end_date, "Flow.LEWT2.ConduitGate_Total") # By setting the following parameter to True, the following flow groups in the list FlowGroupList will all be calculated. Items can be commented out # or commented back in individually. To turn this option off, set the following parameter to False. User can determine which flow group they want to calculate # by changing the "flowGroup" variable. @@ -156,36 +151,36 @@ def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): if calculateSingleFlowGroups: for location in locationList: print("Now Running", location, "SINGLE") - #compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupGate) - #compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupTotal) - #compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupTurbine) - #compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupUncontrol) - compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupPumpOutBelow) - compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupPumpOut) - compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupPumpIn) - compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupNTMWD) - compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupUTRWD) - compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupSS) - compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupIrving) - compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupLewisville) - compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupUTRWD_Out) - compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupUTRWD_In) - compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupIrv) - compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupDenton) - compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupBenbrook) - compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupTRWD) - compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupWeatherford) - compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupGeorgetown) - compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupRound_Rock) - compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupBrushy_Ck) - compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupNTMWD_LVN) - compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupCooper) - compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupEast_Fork) - compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroupTawakoni) + #compute_Single_Flowgroup(officeID, location, start_date, end_date, flowGroupGate) + #compute_Single_Flowgroup(officeID, location, start_date, end_date, flowGroupTotal) + #compute_Single_Flowgroup(officeID, location, start_date, end_date, flowGroupTurbine) + #compute_Single_Flowgroup(officeID, location, start_date, end_date, flowGroupUncontrol) + compute_Single_Flowgroup(officeID, location, start_date, end_date, flowGroupPumpOutBelow) + compute_Single_Flowgroup(officeID, location, start_date, end_date, flowGroupPumpOut) + compute_Single_Flowgroup(officeID, location, start_date, end_date, flowGroupPumpIn) + compute_Single_Flowgroup(officeID, location, start_date, end_date, flowGroupNTMWD) + compute_Single_Flowgroup(officeID, location, start_date, end_date, flowGroupUTRWD) + compute_Single_Flowgroup(officeID, location, start_date, end_date, flowGroupSS) + compute_Single_Flowgroup(officeID, location, start_date, end_date, flowGroupIrving) + compute_Single_Flowgroup(officeID, location, start_date, end_date, flowGroupLewisville) + compute_Single_Flowgroup(officeID, location, start_date, end_date, flowGroupUTRWD_Out) + compute_Single_Flowgroup(officeID, location, start_date, end_date, flowGroupUTRWD_In) + compute_Single_Flowgroup(officeID, location, start_date, end_date, flowGroupIrv) + compute_Single_Flowgroup(officeID, location, start_date, end_date, flowGroupDenton) + compute_Single_Flowgroup(officeID, location, start_date, end_date, flowGroupBenbrook) + compute_Single_Flowgroup(officeID, location, start_date, end_date, flowGroupTRWD) + compute_Single_Flowgroup(officeID, location, start_date, end_date, flowGroupWeatherford) + compute_Single_Flowgroup(officeID, location, start_date, end_date, flowGroupGeorgetown) + compute_Single_Flowgroup(officeID, location, start_date, end_date, flowGroupRound_Rock) + compute_Single_Flowgroup(officeID, location, start_date, end_date, flowGroupBrushy_Ck) + compute_Single_Flowgroup(officeID, location, start_date, end_date, flowGroupNTMWD_LVN) + compute_Single_Flowgroup(officeID, location, start_date, end_date, flowGroupCooper) + compute_Single_Flowgroup(officeID, location, start_date, end_date, flowGroupEast_Fork) + compute_Single_Flowgroup(officeID, location, start_date, end_date, flowGroupTawakoni) if calculateAllFlowGroups: for location in FlowGroupList: print("Now Running", location, "GROUP") - #compute_All_Flowgroups(officeID, location, startCal, endCal) + #compute_All_Flowgroups(officeID, location, start_date, end_date) diff --git a/district-scripts/SWF/GateSettings.py b/district-scripts/SWF/GateSettings.py index b94e476..2c714a5 100644 --- a/district-scripts/SWF/GateSettings.py +++ b/district-scripts/SWF/GateSettings.py @@ -2,11 +2,13 @@ def run_calculations(registry): + from datetime import datetime, timedelta, timezone + from zoneinfo import ZoneInfo + # Java imports must happen after regi_session starts the JVM. - # the java Calendar class is used to create java Date objects - from java.util import Calendar from usace.rowcps.headless import LoggingOptions + # Description of: LoggingOptions.setDbMessageLevel(int level) # # Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended @@ -42,42 +44,34 @@ def run_calculations(registry): # this gets a scriptable Gate Settings object gateSettings = registry.getCalculation(1.0, "Gate Settings") - # configure the start calendar - startCal = Calendar.getInstance() - #startCal.clear() - startCal.add(Calendar.DAY_OF_MONTH, -5) - startCal.set(Calendar.HOUR, 0) ######use Calendar.HOUR_OF_DAY - startCal.set(Calendar.MINUTE, 0) - startCal.set(Calendar.SECOND, 0) - startCal.set(Calendar.MILLISECOND, 0) - # create a java Calendar object that will be used to create the end Date - endCal = Calendar.getInstance() - endCal.add(Calendar.DAY_OF_MONTH, 1) - endCal.set(Calendar.HOUR, 0) - endCal.set(Calendar.MINUTE, 0) - endCal.set(Calendar.SECOND, 0) - endCal.set(Calendar.MILLISECOND, 0) - #endCal.clear() - #endCal.set(Calendar.YEAR, 2016) - #endCal.set(Calendar.MONTH, 4) + # Time zone must be set explicitly because the JVM's default timezone is + # UTC, not the district's local time. (The previous Calendar.getInstance() + # calls here had no explicit timezone and silently depended on whatever + # timezone the host happened to be configured with.) + central = ZoneInfo("America/Chicago") + today_midnight = datetime.now(central).replace(hour=0, minute=0, second=0, microsecond=0) + # start: 5 days ago, at midnight + start_date = (today_midnight - timedelta(days=5)).astimezone(timezone.utc) + # end: tomorrow, at midnight + end_date = (today_midnight + timedelta(days=1)).astimezone(timezone.utc) # gateSettings contains four callable methods - # void createGateSettings(String officeId, String locationStr, Date startDate, Date end) throws Exception; - # void createGateSettingsGroup(String officeId, String locationStr, Date startDate, Date end, String groupId) throws Exception; - # void createGateSettingsOutlet(String officeId, String locationStr, Date startDate, Date end, String outletId) throws Exception; - # void createGateSettingsOutletFromTs(String officeId, String locationStr, Date startDate, Date end, String outletId, String tsId) throws Exception; - - gateSettings.createGateSettingsOutletFromTs("SWF", "FFLT2", startCal.getTime(), endCal.getTime(), "Release", "FFLT2.Opening.Const.0.0.Rev-TRWD-Decodes" ) - gateSettings.createGateSettingsOutletFromTs("SWF", "EAMT2", startCal.getTime(), endCal.getTime(), "Release", "EAMT2.Opening.Const.0.0.Rev-TRWD-Decodes" ) - gateSettings.createGateSettingsOutletFromTs("SWF", "TRNT2", startCal.getTime(), endCal.getTime(), "Release", "TRNT2.Opening.Const.0.0.Rev-TRWD-Decodes" ) - gateSettings.createGateSettingsOutletFromTs("SWF", "BPRT2", startCal.getTime(), endCal.getTime(), "Release", "BPRT2.Opening.Const.0.0.Rev-TRWD-Decodes" ) - gateSettings.createGateSettingsOutletFromTs("SWF", "LLST2", startCal.getTime(), endCal.getTime(), "Release", "LLST2.Opening.Const.0.0.Rev-BRA-Decodes" ) - gateSettings.createGateSettingsOutletFromTs("SWF", "GBYT2", startCal.getTime(), endCal.getTime(), "Release", "GBYT2.Opening.Const.0.0.Rev-BRA-Decodes" ) - gateSettings.createGateSettingsOutletFromTs("SWF", "PSMT2", startCal.getTime(), endCal.getTime(), "Release", "PSMT2.Opening.Const.0.0.Rev-BRA-Decodes" ) - gateSettings.createGateSettingsOutletFromTs("SWF", "MSDT2", startCal.getTime(), endCal.getTime(), "Release", "MSDT2.Opening.Const.0.0.Rev-LCRA-Decodes" ) - gateSettings.createGateSettingsOutletFromTs("SWF", "FRHT2", startCal.getTime(), endCal.getTime(), "Release", "FRHT2.Opening.Const.0.0.Raw-Observer" ) - gateSettings.createGateSettingsOutletFromTs("SWF", "GPET2", startCal.getTime(), endCal.getTime(), "Release", "GPET2.Opening.Const.0.0.Raw-Observer" ) + # void createGateSettings(String officeId, String locationStr, Instant startDate, Instant end) throws Exception; + # void createGateSettingsGroup(String officeId, String locationStr, Instant startDate, Instant end, String groupId) throws Exception; + # void createGateSettingsOutlet(String officeId, String locationStr, Instant startDate, Instant end, String outletId) throws Exception; + # void createGateSettingsOutletFromTs(String officeId, String locationStr, Instant startDate, Instant end, String outletId, String tsId) throws Exception; + + gateSettings.createGateSettingsOutletFromTs("SWF", "FFLT2", start_date, end_date, "Release", "FFLT2.Opening.Const.0.0.Rev-TRWD-Decodes" ) + gateSettings.createGateSettingsOutletFromTs("SWF", "EAMT2", start_date, end_date, "Release", "EAMT2.Opening.Const.0.0.Rev-TRWD-Decodes" ) + gateSettings.createGateSettingsOutletFromTs("SWF", "TRNT2", start_date, end_date, "Release", "TRNT2.Opening.Const.0.0.Rev-TRWD-Decodes" ) + gateSettings.createGateSettingsOutletFromTs("SWF", "BPRT2", start_date, end_date, "Release", "BPRT2.Opening.Const.0.0.Rev-TRWD-Decodes" ) + gateSettings.createGateSettingsOutletFromTs("SWF", "LLST2", start_date, end_date, "Release", "LLST2.Opening.Const.0.0.Rev-BRA-Decodes" ) + gateSettings.createGateSettingsOutletFromTs("SWF", "GBYT2", start_date, end_date, "Release", "GBYT2.Opening.Const.0.0.Rev-BRA-Decodes" ) + gateSettings.createGateSettingsOutletFromTs("SWF", "PSMT2", start_date, end_date, "Release", "PSMT2.Opening.Const.0.0.Rev-BRA-Decodes" ) + gateSettings.createGateSettingsOutletFromTs("SWF", "MSDT2", start_date, end_date, "Release", "MSDT2.Opening.Const.0.0.Rev-LCRA-Decodes" ) + gateSettings.createGateSettingsOutletFromTs("SWF", "FRHT2", start_date, end_date, "Release", "FRHT2.Opening.Const.0.0.Raw-Observer" ) + gateSettings.createGateSettingsOutletFromTs("SWF", "GPET2", start_date, end_date, "Release", "GPET2.Opening.Const.0.0.Raw-Observer" ) diff --git a/district-scripts/SWF/InflowCalcComputeEvapAsFlow.py b/district-scripts/SWF/InflowCalcComputeEvapAsFlow.py index fd6f4e3..6406a79 100644 --- a/district-scripts/SWF/InflowCalcComputeEvapAsFlow.py +++ b/district-scripts/SWF/InflowCalcComputeEvapAsFlow.py @@ -2,47 +2,25 @@ def run_calculations(registry): - # Java imports must happen after regi_session starts the JVM. - # the java Calendar class is used to create java Date objects - from java.util import Calendar - from java.util import TimeZone + from datetime import datetime, timedelta, timezone + from zoneinfo import ZoneInfo # this gets a ScriptableInflow instance. inflowCalc = registry.getCalculation(1.0, "Inflow") - # configure the start calendar - ##startCal = Calendar.getInstance(TimeZone.getTimeZone('US/Central')) - ## - ## - ##startCal.clear() - ##startCal.set(Calendar.YEAR, 2018) - ##startCal.set(Calendar.MONTH, 11) - ## - ##endCal = Calendar.getInstance(TimeZone.getTimeZone('US/Central')) - ##endCal.clear() - ##endCal.set(Calendar.YEAR, 2019) - ##endCal.set(Calendar.MONTH, 0) - ##endCal.set(Calendar.DAY_OF_MONTH, 7) - - startCal = Calendar.getInstance(TimeZone.getTimeZone('US/Central')) - # startCal.clear() - startCal.add(Calendar.DAY_OF_MONTH, -5) - startCal.set(Calendar.HOUR_OF_DAY, 0) - startCal.set(Calendar.MINUTE, 0) - startCal.set(Calendar.SECOND, 0) - startCal.set(Calendar.MILLISECOND, 0) - # startCal.set(Calendar.YEAR, 2015) - # startCal.set(Calendar.MONTH, 9) - - # create a java Calendar object that will be used to create the end Date - endCal = Calendar.getInstance(TimeZone.getTimeZone('US/Central')) - # endCal.clear() - endCal.add(Calendar.DAY_OF_MONTH, 1) - endCal.set(Calendar.HOUR_OF_DAY, 0) - endCal.set(Calendar.MINUTE, 0) - endCal.set(Calendar.SECOND, 0) - endCal.set(Calendar.MILLISECOND, 0) + # configure the start/end dates + ##central = ZoneInfo("America/Chicago") + ##start_date = (datetime(2018, 12, 1, tzinfo=central)).astimezone(timezone.utc) + ##end_date = (datetime(2019, 1, 7, tzinfo=central)).astimezone(timezone.utc) + + central = ZoneInfo("America/Chicago") + today_midnight = datetime.now(central).replace(hour=0, minute=0, second=0, microsecond=0) + + # start: 5 days ago, at midnight + start_date = (today_midnight - timedelta(days=5)).astimezone(timezone.utc) + # end: tomorrow, at midnight + end_date = (today_midnight + timedelta(days=1)).astimezone(timezone.utc) locationList = ["WTYT2","JSPT2","TBLT2","SCLT2","TXKT2","BSLT2","JFNT2","CLDL1", "BPRT2","EAMT2","FLWT2","BNBT2","JPLT2","GPET2","RRLT2","LEWT2", @@ -51,7 +29,7 @@ def run_calculations(registry): "SOMT2","LLST2","TBRT2","SAGT2","HORT2","MSDT2","SMCT2"] for loc in locationList: - inflowCalc.computeEvapAsFlow("SWF", loc, startCal.getTime(), endCal.getTime()) + inflowCalc.computeEvapAsFlow("SWF", loc, start_date, end_date) if __name__ == "__main__": diff --git a/district-scripts/SWF/InflowCalcComputedInflow.py b/district-scripts/SWF/InflowCalcComputedInflow.py index 99d5331..cf8e019 100644 --- a/district-scripts/SWF/InflowCalcComputedInflow.py +++ b/district-scripts/SWF/InflowCalcComputedInflow.py @@ -2,42 +2,28 @@ def run_calculations(registry): + from datetime import datetime, timedelta, timezone + from zoneinfo import ZoneInfo + # Java imports must happen after regi_session starts the JVM. - # the java Calendar class is used to create java Date objects - from java.util import Calendar - from java.util import TimeZone from usace.rowcps.headless.calculator.inflow import InflowComputationStorageOption + # this gets a ScriptableInflow instance. inflowCalc = registry.getCalculation(1.0, "Inflow") - # configure the start calendar - ##startCal = Calendar.getInstance(TimeZone.getTimeZone('US/Central')) - ## - ## - ##startCal.clear() - ##startCal.set(Calendar.YEAR, 2019) - ##startCal.set(Calendar.MONTH, 1) - ## - ##endCal = Calendar.getInstance(TimeZone.getTimeZone('US/Central')) - ##endCal.clear() - ##endCal.set(Calendar.YEAR, 2019) - ##endCal.set(Calendar.MONTH, 1) - ##endCal.set(Calendar.DAY_OF_MONTH, 4) + # configure the start/end dates + ##central = ZoneInfo("America/Chicago") + ##start_date = (datetime(2019, 2, 1, tzinfo=central)).astimezone(timezone.utc) + ##end_date = (datetime(2019, 2, 4, tzinfo=central)).astimezone(timezone.utc) + + central = ZoneInfo("America/Chicago") + today_midnight = datetime.now(central).replace(hour=0, minute=0, second=0, microsecond=0) - startCal = Calendar.getInstance(TimeZone.getTimeZone('US/Central')) - startCal.add(Calendar.DAY_OF_MONTH, -4) - startCal.set(Calendar.HOUR, 0) ######use Calendar.HOUR_OF_DAY - startCal.set(Calendar.MINUTE, 0) - startCal.set(Calendar.SECOND, 0) - startCal.set(Calendar.MILLISECOND, 0) - # create a java Calendar object that will be used to create the end Date - endCal = Calendar.getInstance(TimeZone.getTimeZone('US/Central')) - endCal.add(Calendar.DAY_OF_MONTH, 1) - endCal.set(Calendar.HOUR, 0) - endCal.set(Calendar.MINUTE, 0) - endCal.set(Calendar.SECOND, 0) - endCal.set(Calendar.MILLISECOND, 0) + # start: 4 days ago, at midnight + start_date = (today_midnight - timedelta(days=4)).astimezone(timezone.utc) + # end: tomorrow, at midnight + end_date = (today_midnight + timedelta(days=1)).astimezone(timezone.utc) # inflowCalc includes a setComputationStorageOptions function, which takes in either one or many # InflowComputationStorageOption values. This is used by computeInflow to determine if it should save additional @@ -66,7 +52,7 @@ def run_calculations(registry): "GBYT2","ALAT2","ACTT2","PCTT2","BLNT2","STIT2","GGLT2","GNGT2", "SOMT2","LLST2","TBRT2","SAGT2","HORT2","SMCT2","MSDT2"] for loc in locationList: - inflowCalc.computeInflow("SWF", loc, startCal.getTime(), endCal.getTime()) + inflowCalc.computeInflow("SWF", loc, start_date, end_date) if __name__ == "__main__": diff --git a/district-scripts/SWL/Big3-GateFlow.py b/district-scripts/SWL/Big3-GateFlow.py index 3b09287..b4b1eb3 100644 --- a/district-scripts/SWL/Big3-GateFlow.py +++ b/district-scripts/SWL/Big3-GateFlow.py @@ -2,30 +2,32 @@ def run_calculations(registry): + from datetime import datetime, timedelta, timezone + from zoneinfo import ZoneInfo + # Java imports must happen after regi_session starts the JVM. - from java.util import Calendar - from java.util import TimeZone from usace.rowcps.headless import LoggingOptions - def compute_All_Flowgroups(officeID, location, startCal, endCal): + + def compute_All_Flowgroups(officeID, location, start_date, end_date): # Takes in locations defined by user in group and computes all flow groups try: - gateCalc.computeAll(officeID, location, startCal.getTime(), endCal.getTime()) + gateCalc.computeAll(officeID, location, start_date, end_date) except Exception as e: print("Error Computing all Flow Groups at {0} {1}".format(officeID, location)) print(e) print('') - def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): + def compute_Single_Flowgroup(officeID, location, start_date, end_date, flowGroup): try: - gateCalc.computeFlowGroup(officeID, location, startCal.getTime(), endCal.getTime(), "Flow.{0}.{1}".format(location, flowGroup)) + gateCalc.computeFlowGroup(officeID, location, start_date, end_date, "Flow.{0}.{1}".format(location, flowGroup)) except Exception as e: print("Error Computing Flow Group {0} at {1}".format(officeID, location)) print(e) print('') - # #gateCalc.computeFlowGroup("SWF", "ACTT2", startCal.getTime(), endCal.getTime(), "Flow.ACTT2.Pump_Out_Total") + # #gateCalc.computeFlowGroup("SWF", "ACTT2", start_date, end_date, "Flow.ACTT2.Pump_Out_Total") # Description of: LoggingOptions.setDbMessageLevel(int level) # # Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended @@ -65,31 +67,15 @@ def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): # this retrieves a Gate Flow calculation object gateCalc = registry.getCalculation(1.0, "Gate Flow") - # Time zone must be set because the Solaris time zone is UTC - timeZone = TimeZone.getTimeZone("US/Central") - # the gate flow calculations requires a start and end time. - # here we create a java Calendar object that will be used to create the start Date - startCal = Calendar.getInstance(timeZone) - # startCal.clear() - startCal.add(Calendar.DAY_OF_MONTH, -5) - startCal.set(Calendar.HOUR_OF_DAY, 0) - startCal.set(Calendar.MINUTE, 0) - startCal.set(Calendar.SECOND, 0) - # startCal.set(Calendar.YEAR, 2015) - # startCal.set(Calendar.MONTH, 9) - startCal.set(Calendar.MILLISECOND, 0) - - # create a java Calendar object that will be used to create the end Date - endCal = Calendar.getInstance(timeZone) - # endCal.clear() - ##################endCal.add(Calendar.DAY_OF_MONTH, 5) - endCal.add(Calendar.DAY_OF_MONTH, 1) - endCal.set(Calendar.HOUR_OF_DAY, 0) - endCal.set(Calendar.MINUTE, 0) - endCal.set(Calendar.SECOND, 0) - # endCal.set(Calendar.YEAR, 2015) - # endCal.set(Calendar.MONTH, 11) - endCal.set(Calendar.MILLISECOND, 0) + # Time zone must be set explicitly because the JVM's default timezone is + # UTC, not the district's local time. + central = ZoneInfo("America/Chicago") + today_midnight = datetime.now(central).replace(hour=0, minute=0, second=0, microsecond=0) + + # start: 5 days ago, at midnight + start_date = (today_midnight - timedelta(days=5)).astimezone(timezone.utc) + # end: tomorrow, at midnight + end_date = (today_midnight + timedelta(days=1)).astimezone(timezone.utc) officeID = "SWL" @@ -99,7 +85,7 @@ def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): # projectId # startDate # endDate - # gateCalc.computeFlowGroup("SWF", "LEWT2", startCal.getTime(), endCal.getTime(), "Flow.LEWT2.ConduitGate_Total") + # gateCalc.computeFlowGroup("SWF", "LEWT2", start_date, end_date, "Flow.LEWT2.ConduitGate_Total") # By setting the following parameter to True, the following flow groups in the list FlowGroupList will all be calculated. Items can be commented out # or commented back in individually. To turn this option off, set the following parameter to False. User can determine which flow group they want to calculate # by changing the "flowGroup" variable. @@ -128,12 +114,12 @@ def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): if calculateSingleFlowGroups: for location in locationList: print("Now Running", location, "SINGLE") - compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup) + compute_Single_Flowgroup(officeID, location, start_date, end_date, flowGroup) if calculateAllFlowGroups: for location in FlowGroupList: print("Now Running", location, "GROUP") - compute_All_Flowgroups(officeID, location, startCal, endCal) + compute_All_Flowgroups(officeID, location, start_date, end_date) diff --git a/district-scripts/SWL/Big3-InflowCalcMultipleActions.py b/district-scripts/SWL/Big3-InflowCalcMultipleActions.py index 04861a9..bdd7161 100644 --- a/district-scripts/SWL/Big3-InflowCalcMultipleActions.py +++ b/district-scripts/SWL/Big3-InflowCalcMultipleActions.py @@ -2,12 +2,13 @@ def run_calculations(registry): + from datetime import datetime, timedelta, timezone + from zoneinfo import ZoneInfo + # Java imports must happen after regi_session starts the JVM. - # the java Calendar class is used to create java Date objects - from java.util import Calendar - from java.util import TimeZone from usace.rowcps.headless import LoggingOptions + # Description of: LoggingOptions.setDbMessageLevel(int level) # # Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended @@ -43,31 +44,16 @@ def run_calculations(registry): # this gets a scriptable Pool Percent object inflowCalc = registry.getCalculation(1.0, "Inflow") - # configure the start calendar' - #startCal = Calendar.getInstance(TimeZone.getTimeZone('US/Central')) - timeZone = TimeZone.getTimeZone("US/Central") - - #startCal.clear() - #startCal.set(Calendar.YEAR, 2015) - #startCal.set(Calendar.MONTH, 4) - - startCal = Calendar.getInstance(timeZone) - startCal.add(Calendar.DAY_OF_MONTH, -7) - startCal.set(Calendar.HOUR_OF_DAY, 0) - startCal.set(Calendar.MINUTE, 0) - startCal.set(Calendar.SECOND, 0) - startCal.set(Calendar.MILLISECOND, 0) - - endCal = Calendar.getInstance(timeZone) - endCal.add(Calendar.DAY_OF_MONTH, 1) - endCal.set(Calendar.HOUR_OF_DAY, 0) - endCal.set(Calendar.MINUTE, 0) - endCal.set(Calendar.SECOND, 0) - endCal.set(Calendar.MILLISECOND, 0) + # Time zone must be set explicitly because the JVM's default timezone is + # UTC, not the district's local time. + central = ZoneInfo("America/Chicago") + today_midnight = datetime.now(central).replace(hour=0, minute=0, second=0, microsecond=0) officeID = "SWL" - startDate = startCal.getTime() - endDate = endCal.getTime() + # start: 7 days ago, at midnight + startDate = (today_midnight - timedelta(days=7)).astimezone(timezone.utc) + # end: tomorrow, at midnight + endDate = (today_midnight + timedelta(days=1)).astimezone(timezone.utc) # inflowCalc contains 4 callable methods: # autoAdjust diff --git a/district-scripts/SWL/Millwd-Tri-Lks-GateFlow.py b/district-scripts/SWL/Millwd-Tri-Lks-GateFlow.py index 998bddc..e0a90f6 100644 --- a/district-scripts/SWL/Millwd-Tri-Lks-GateFlow.py +++ b/district-scripts/SWL/Millwd-Tri-Lks-GateFlow.py @@ -2,30 +2,32 @@ def run_calculations(registry): + from datetime import datetime, timedelta, timezone + from zoneinfo import ZoneInfo + # Java imports must happen after regi_session starts the JVM. - from java.util import Calendar - from java.util import TimeZone from usace.rowcps.headless import LoggingOptions - def compute_All_Flowgroups(officeID, location, startCal, endCal): + + def compute_All_Flowgroups(officeID, location, start_date, end_date): # Takes in locations defined by user in group and computes all flow groups try: - gateCalc.computeAll(officeID, location, startCal.getTime(), endCal.getTime()) + gateCalc.computeAll(officeID, location, start_date, end_date) except Exception as e: print("Error Computing all Flow Groups at {0} {1}".format(officeID, location)) print(e) print('') - def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): + def compute_Single_Flowgroup(officeID, location, start_date, end_date, flowGroup): try: - gateCalc.computeFlowGroup(officeID, location, startCal.getTime(), endCal.getTime(), "Flow.{0}.{1}".format(location, flowGroup)) + gateCalc.computeFlowGroup(officeID, location, start_date, end_date, "Flow.{0}.{1}".format(location, flowGroup)) except Exception as e: print("Error Computing Flow Group {0} at {1}".format(officeID, location)) print(e) print('') - # #gateCalc.computeFlowGroup("SWF", "ACTT2", startCal.getTime(), endCal.getTime(), "Flow.ACTT2.Pump_Out_Total") + # #gateCalc.computeFlowGroup("SWF", "ACTT2", start_date, end_date, "Flow.ACTT2.Pump_Out_Total") # Description of: LoggingOptions.setDbMessageLevel(int level) # # Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended @@ -65,31 +67,15 @@ def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): # this retrieves a Gate Flow calculation object gateCalc = registry.getCalculation(1.0, "Gate Flow") - # Time zone must be set because the Solaris time zone is UTC - timeZone = TimeZone.getTimeZone("US/Central") - # the gate flow calculations requires a start and end time. - # here we create a java Calendar object that will be used to create the start Date - startCal = Calendar.getInstance(timeZone) - # startCal.clear() - startCal.add(Calendar.DAY_OF_MONTH, -5) - startCal.set(Calendar.HOUR_OF_DAY, 0) - startCal.set(Calendar.MINUTE, 0) - startCal.set(Calendar.SECOND, 0) - # startCal.set(Calendar.YEAR, 2015) - # startCal.set(Calendar.MONTH, 9) - startCal.set(Calendar.MILLISECOND, 0) - - # create a java Calendar object that will be used to create the end Date - endCal = Calendar.getInstance(timeZone) - # endCal.clear() - ##################endCal.add(Calendar.DAY_OF_MONTH, 5) - endCal.add(Calendar.DAY_OF_MONTH, 1) - endCal.set(Calendar.HOUR_OF_DAY, 0) - endCal.set(Calendar.MINUTE, 0) - endCal.set(Calendar.SECOND, 0) - # endCal.set(Calendar.YEAR, 2015) - # endCal.set(Calendar.MONTH, 11) - endCal.set(Calendar.MILLISECOND, 0) + # Time zone must be set explicitly because the JVM's default timezone is + # UTC, not the district's local time. + central = ZoneInfo("America/Chicago") + today_midnight = datetime.now(central).replace(hour=0, minute=0, second=0, microsecond=0) + + # start: 5 days ago, at midnight + start_date = (today_midnight - timedelta(days=5)).astimezone(timezone.utc) + # end: tomorrow, at midnight + end_date = (today_midnight + timedelta(days=1)).astimezone(timezone.utc) officeID = "SWL" @@ -99,7 +85,7 @@ def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): # projectId # startDate # endDate - # gateCalc.computeFlowGroup("SWF", "LEWT2", startCal.getTime(), endCal.getTime(), "Flow.LEWT2.ConduitGate_Total") + # gateCalc.computeFlowGroup("SWF", "LEWT2", start_date, end_date, "Flow.LEWT2.ConduitGate_Total") # By setting the following parameter to True, the following flow groups in the list FlowGroupList will all be calculated. Items can be commented out # or commented back in individually. To turn this option off, set the following parameter to False. User can determine which flow group they want to calculate # by changing the "flowGroup" variable. @@ -129,12 +115,12 @@ def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): if calculateSingleFlowGroups: for location in locationList: print("Now Running", location, "SINGLE") - compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup) + compute_Single_Flowgroup(officeID, location, start_date, end_date, flowGroup) if calculateAllFlowGroups: for location in FlowGroupList: print("Now Running", location, "GROUP") - compute_All_Flowgroups(officeID, location, startCal, endCal) + compute_All_Flowgroups(officeID, location, start_date, end_date) diff --git a/district-scripts/SWL/Millwd-Tri-Lks-InflowCalcMultipleActions.py b/district-scripts/SWL/Millwd-Tri-Lks-InflowCalcMultipleActions.py index fc8a71b..c682ce8 100644 --- a/district-scripts/SWL/Millwd-Tri-Lks-InflowCalcMultipleActions.py +++ b/district-scripts/SWL/Millwd-Tri-Lks-InflowCalcMultipleActions.py @@ -2,12 +2,13 @@ def run_calculations(registry): + from datetime import datetime, timedelta, timezone + from zoneinfo import ZoneInfo + # Java imports must happen after regi_session starts the JVM. - # the java Calendar class is used to create java Date objects - from java.util import Calendar - from java.util import TimeZone from usace.rowcps.headless import LoggingOptions + # Description of: LoggingOptions.setDbMessageLevel(int level) # # Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended @@ -43,31 +44,16 @@ def run_calculations(registry): # this gets a scriptable Pool Percent object inflowCalc = registry.getCalculation(1.0, "Inflow") - # configure the start calendar' - #startCal = Calendar.getInstance(TimeZone.getTimeZone('US/Central')) - timeZone = TimeZone.getTimeZone("US/Central") - - #startCal.clear() - #startCal.set(Calendar.YEAR, 2015) - #startCal.set(Calendar.MONTH, 4) - - startCal = Calendar.getInstance(timeZone) - startCal.add(Calendar.DAY_OF_MONTH, -7) - startCal.set(Calendar.HOUR_OF_DAY, 0) - startCal.set(Calendar.MINUTE, 0) - startCal.set(Calendar.SECOND, 0) - startCal.set(Calendar.MILLISECOND, 0) - - endCal = Calendar.getInstance(timeZone) - endCal.add(Calendar.DAY_OF_MONTH, 1) - endCal.set(Calendar.HOUR_OF_DAY, 0) - endCal.set(Calendar.MINUTE, 0) - endCal.set(Calendar.SECOND, 0) - endCal.set(Calendar.MILLISECOND, 0) + # Time zone must be set explicitly because the JVM's default timezone is + # UTC, not the district's local time. + central = ZoneInfo("America/Chicago") + today_midnight = datetime.now(central).replace(hour=0, minute=0, second=0, microsecond=0) officeID = "SWL" - startDate = startCal.getTime() - endDate = endCal.getTime() + # start: 7 days ago, at midnight + startDate = (today_midnight - timedelta(days=7)).astimezone(timezone.utc) + # end: tomorrow, at midnight + endDate = (today_midnight + timedelta(days=1)).astimezone(timezone.utc) # inflowCalc contains 4 callable methods: # autoAdjust diff --git a/district-scripts/SWL/WhiteR-GateFlow.py b/district-scripts/SWL/WhiteR-GateFlow.py index 270a0f4..c620f43 100644 --- a/district-scripts/SWL/WhiteR-GateFlow.py +++ b/district-scripts/SWL/WhiteR-GateFlow.py @@ -2,30 +2,32 @@ def run_calculations(registry): + from datetime import datetime, timedelta, timezone + from zoneinfo import ZoneInfo + # Java imports must happen after regi_session starts the JVM. - from java.util import Calendar - from java.util import TimeZone from usace.rowcps.headless import LoggingOptions - def compute_All_Flowgroups(officeID, location, startCal, endCal): + + def compute_All_Flowgroups(officeID, location, start_date, end_date): # Takes in locations defined by user in group and computes all flow groups try: - gateCalc.computeAll(officeID, location, startCal.getTime(), endCal.getTime()) + gateCalc.computeAll(officeID, location, start_date, end_date) except Exception as e: print("Error Computing all Flow Groups at {0} {1}".format(officeID, location)) print(e) print('') - def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): + def compute_Single_Flowgroup(officeID, location, start_date, end_date, flowGroup): try: - gateCalc.computeFlowGroup(officeID, location, startCal.getTime(), endCal.getTime(), "Flow.{0}.{1}".format(location, flowGroup)) + gateCalc.computeFlowGroup(officeID, location, start_date, end_date, "Flow.{0}.{1}".format(location, flowGroup)) except Exception as e: print("Error Computing Flow Group {0} at {1}".format(officeID, location)) print(e) print('') - # #gateCalc.computeFlowGroup("SWF", "ACTT2", startCal.getTime(), endCal.getTime(), "Flow.ACTT2.Pump_Out_Total") + # #gateCalc.computeFlowGroup("SWF", "ACTT2", start_date, end_date, "Flow.ACTT2.Pump_Out_Total") # Description of: LoggingOptions.setDbMessageLevel(int level) # # Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended @@ -65,32 +67,15 @@ def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): # this retrieves a Gate Flow calculation object gateCalc = registry.getCalculation(1.0, "Gate Flow") - # Time zone must be set because the Solaris time zone is UTC - timeZone = TimeZone.getTimeZone("US/Central") - # the gate flow calculations requires a start and end time. - # here we create a java Calendar object that will be used to create the start Date - startCal = Calendar.getInstance(timeZone) - # startCal.clear() - startCal.add(Calendar.DAY_OF_MONTH, -5) - startCal.set(Calendar.HOUR_OF_DAY, 0) - startCal.set(Calendar.MINUTE, 0) - startCal.set(Calendar.SECOND, 0) - # startCal.set(Calendar.YEAR, 2015) - # startCal.set(Calendar.MONTH, 9) - startCal.set(Calendar.MILLISECOND, 0) - - # create a java Calendar object that will be used to create the end Date - endCal = Calendar.getInstance(timeZone) - # endCal.clear() - ##################endCal.add(Calendar.DAY_OF_MONTH, 5) - #endCal.add(Calendar.DAY_OF_MONTH, 1) - endCal.add(Calendar.DAY_OF_MONTH, 1) - endCal.set(Calendar.HOUR_OF_DAY, 0) - endCal.set(Calendar.MINUTE, 0) - endCal.set(Calendar.SECOND, 0) - # endCal.set(Calendar.YEAR, 2015) - # endCal.set(Calendar.MONTH, 11) - endCal.set(Calendar.MILLISECOND, 0) + # Time zone must be set explicitly because the JVM's default timezone is + # UTC, not the district's local time. + central = ZoneInfo("America/Chicago") + today_midnight = datetime.now(central).replace(hour=0, minute=0, second=0, microsecond=0) + + # start: 5 days ago, at midnight + start_date = (today_midnight - timedelta(days=5)).astimezone(timezone.utc) + # end: tomorrow, at midnight + end_date = (today_midnight + timedelta(days=1)).astimezone(timezone.utc) officeID = "SWL" @@ -100,7 +85,7 @@ def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): # projectId # startDate # endDate - # gateCalc.computeFlowGroup("SWF", "LEWT2", startCal.getTime(), endCal.getTime(), "Flow.LEWT2.ConduitGate_Total") + # gateCalc.computeFlowGroup("SWF", "LEWT2", start_date, end_date, "Flow.LEWT2.ConduitGate_Total") # By setting the following parameter to True, the following flow groups in the list FlowGroupList will all be calculated. Items can be commented out # or commented back in individually. To turn this option off, set the following parameter to False. User can determine which flow group they want to calculate # by changing the "flowGroup" variable. @@ -131,12 +116,12 @@ def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): if calculateSingleFlowGroups: for location in locationList: print("Now Running", location, "SINGLE") - compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup) + compute_Single_Flowgroup(officeID, location, start_date, end_date, flowGroup) if calculateAllFlowGroups: for location in FlowGroupList: print("Now Running", location, "GROUP") - compute_All_Flowgroups(officeID, location, startCal, endCal) + compute_All_Flowgroups(officeID, location, start_date, end_date) diff --git a/district-scripts/SWL/WhiteR-InflowCalcMultipleActions.py b/district-scripts/SWL/WhiteR-InflowCalcMultipleActions.py index 9b548c0..0765106 100644 --- a/district-scripts/SWL/WhiteR-InflowCalcMultipleActions.py +++ b/district-scripts/SWL/WhiteR-InflowCalcMultipleActions.py @@ -2,12 +2,13 @@ def run_calculations(registry): + from datetime import datetime, timedelta, timezone + from zoneinfo import ZoneInfo + # Java imports must happen after regi_session starts the JVM. - # the java Calendar class is used to create java Date objects - from java.util import Calendar - from java.util import TimeZone from usace.rowcps.headless import LoggingOptions + # Description of: LoggingOptions.setDbMessageLevel(int level) # # Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended @@ -43,31 +44,16 @@ def run_calculations(registry): # this gets a scriptable Pool Percent object inflowCalc = registry.getCalculation(1.0, "Inflow") - # configure the start calendar' - #startCal = Calendar.getInstance(TimeZone.getTimeZone('US/Central')) - timeZone = TimeZone.getTimeZone("US/Central") - - #startCal.clear() - #startCal.set(Calendar.YEAR, 2015) - #startCal.set(Calendar.MONTH, 4) - - startCal = Calendar.getInstance(timeZone) - startCal.add(Calendar.DAY_OF_MONTH, -7) - startCal.set(Calendar.HOUR_OF_DAY, 0) - startCal.set(Calendar.MINUTE, 0) - startCal.set(Calendar.SECOND, 0) - startCal.set(Calendar.MILLISECOND, 0) - - endCal = Calendar.getInstance(timeZone) - endCal.add(Calendar.DAY_OF_MONTH, 1) - endCal.set(Calendar.HOUR_OF_DAY, 0) - endCal.set(Calendar.MINUTE, 0) - endCal.set(Calendar.SECOND, 0) - endCal.set(Calendar.MILLISECOND, 0) + # Time zone must be set explicitly because the JVM's default timezone is + # UTC, not the district's local time. + central = ZoneInfo("America/Chicago") + today_midnight = datetime.now(central).replace(hour=0, minute=0, second=0, microsecond=0) officeID = "SWL" - startDate = startCal.getTime() - endDate = endCal.getTime() + # start: 7 days ago, at midnight + startDate = (today_midnight - timedelta(days=7)).astimezone(timezone.utc) + # end: tomorrow, at midnight + endDate = (today_midnight + timedelta(days=1)).astimezone(timezone.utc) # inflowCalc contains 4 callable methods: # autoAdjust diff --git a/district-scripts/SWT/GateFlowGroup1.py b/district-scripts/SWT/GateFlowGroup1.py index 9018dc7..c9d0cb3 100644 --- a/district-scripts/SWT/GateFlowGroup1.py +++ b/district-scripts/SWT/GateFlowGroup1.py @@ -2,30 +2,32 @@ def run_calculations(registry): + from datetime import datetime, timedelta, timezone + from zoneinfo import ZoneInfo + # Java imports must happen after regi_session starts the JVM. - from java.util import Calendar - from java.util import TimeZone from usace.rowcps.headless import LoggingOptions - def compute_All_Flowgroups(officeID, location, startCal, endCal): + + def compute_All_Flowgroups(officeID, location, start_date, end_date): # Takes in locations defined by user in group and computes all flow groups try: - gateCalc.computeAll(officeID, location, startCal.getTime(), endCal.getTime()) + gateCalc.computeAll(officeID, location, start_date, end_date) except Exception as e: print("Error Computing all Flow Groups at {0} {1}".format(officeID, location)) print(e) print('') - def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): + def compute_Single_Flowgroup(officeID, location, start_date, end_date, flowGroup): try: - gateCalc.computeFlowGroup(officeID, location, startCal.getTime(), endCal.getTime(), "Flow.{0}.{1}".format(location, flowGroup)) + gateCalc.computeFlowGroup(officeID, location, start_date, end_date, "Flow.{0}.{1}".format(location, flowGroup)) except Exception as e: print("Error Computing Flow Group {0} at {1}".format(officeID, location)) print(e) print('') - # #gateCalc.computeFlowGroup("SWF", "ACTT2", startCal.getTime(), endCal.getTime(), "Flow.ACTT2.Pump_Out_Total") + # #gateCalc.computeFlowGroup("SWF", "ACTT2", start_date, end_date, "Flow.ACTT2.Pump_Out_Total") # Description of: LoggingOptions.setDbMessageLevel(int level) # # Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended @@ -65,31 +67,22 @@ def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): # this retrieves a Gate Flow calculation object gateCalc = registry.getCalculation(1.0, "Gate Flow") - # Time zone must be set because the Solaris time zone is UTC - timeZone = TimeZone.getTimeZone("US/Central") + # Time zone must be set explicitly because the JVM's default timezone is + # UTC, not the district's local time. + central = ZoneInfo("America/Chicago") # Defaults to start of the day 5 days ago, and ends at the top of the current hour today - # configure the start calendar - startCal = Calendar.getInstance(timeZone) - startCal.add(Calendar.DAY_OF_MONTH, -5) - #startCal.add(Calendar.HOUR, -7) - startCal.set(Calendar.MINUTE, 0) - startCal.set(Calendar.SECOND, 0) - startCal.set(Calendar.MILLISECOND, 0) - - - # configure the end calendar - endCal = Calendar.getInstance(timeZone) - endCal.set(Calendar.MINUTE, 0) - endCal.set(Calendar.SECOND, 0) - endCal.set(Calendar.MILLISECOND, 0) - #endCal.add(Calendar.MONTH, -3) - - # Calendar can be adjusted using the following functions: - # startCal.set(Calendar.DATE, 1) # Sets the date of the calendar. - # startCal.set(Calendar.HOUR_OF_DAY, 1) # Sets the hour of the day to 0100 (1-24) - # startCal.set(Calendar.YEAR, 2020) # Sets the year - # startCal.set(Calendar.MONTH, 4) # Sets the month (month 4 means May to Java) + end_date_dt = datetime.now(central).replace(minute=0, second=0, microsecond=0) + start_date_dt = end_date_dt - timedelta(days=5) + #start_date_dt = end_date_dt - timedelta(days=5, hours=7) + + start_date = start_date_dt.astimezone(timezone.utc) + end_date = end_date_dt.astimezone(timezone.utc) + + # Dates can be adjusted using normal datetime arithmetic/replace, e.g.: + # start_date_dt = start_date_dt.replace(day=1) # start of month + # start_date_dt = start_date_dt.replace(hour=1) # 0100 local time + # start_date_dt = start_date_dt.replace(year=2020, month=5) # month is 1-indexed here officeID = "SWT" @@ -99,52 +92,52 @@ def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): # projectId # startDate # endDate - # gateCalc.computeFlowGroup("SWF", "LEWT2", startCal.getTime(), endCal.getTime(), "Flow.LEWT2.ConduitGate_Total") + # gateCalc.computeFlowGroup("SWF", "LEWT2", start_date, end_date, "Flow.LEWT2.ConduitGate_Total") # # GROUP 1 PROJECTS (SELF-TIMED TRANSMISSIONS WITHIN THE FIRST 2 MINUTES OF THE TOP OF THE HOUR) # #FOSS - gateCalc.computeFlowGroup("SWT", "FOSS", startCal.getTime(), endCal.getTime(), "Flow.FOSS.Project_Total") - gateCalc.computeFlowGroup("SWT", "FOSS", startCal.getTime(), endCal.getTime(), "Flow.FOSS.Gated_Total") + gateCalc.computeFlowGroup("SWT", "FOSS", start_date, end_date, "Flow.FOSS.Project_Total") + gateCalc.computeFlowGroup("SWT", "FOSS", start_date, end_date, "Flow.FOSS.Gated_Total") #FCOB - gateCalc.computeFlowGroup("SWT", "FCOB", startCal.getTime(), endCal.getTime(), "Flow.FCOB.Project_Total") - gateCalc.computeFlowGroup("SWT", "FCOB", startCal.getTime(), endCal.getTime(), "Flow.FCOB.Gated_Total") + gateCalc.computeFlowGroup("SWT", "FCOB", start_date, end_date, "Flow.FCOB.Project_Total") + gateCalc.computeFlowGroup("SWT", "FCOB", start_date, end_date, "Flow.FCOB.Gated_Total") #SKIA - gateCalc.computeFlowGroup("SWT", "SKIA", startCal.getTime(), endCal.getTime(), "Flow.SKIA.Project_Total") - gateCalc.computeFlowGroup("SWT", "SKIA", startCal.getTime(), endCal.getTime(), "Flow.SKIA.Gated_Total") + gateCalc.computeFlowGroup("SWT", "SKIA", start_date, end_date, "Flow.SKIA.Project_Total") + gateCalc.computeFlowGroup("SWT", "SKIA", start_date, end_date, "Flow.SKIA.Gated_Total") #HEYB - gateCalc.computeFlowGroup("SWT", "HEYB", startCal.getTime(), endCal.getTime(), "Flow.HEYB.Project_Total") - gateCalc.computeFlowGroup("SWT", "HEYB", startCal.getTime(), endCal.getTime(), "Flow.HEYB.Gated_Total") + gateCalc.computeFlowGroup("SWT", "HEYB", start_date, end_date, "Flow.HEYB.Project_Total") + gateCalc.computeFlowGroup("SWT", "HEYB", start_date, end_date, "Flow.HEYB.Gated_Total") #KAWL - gateCalc.computeFlowGroup("SWT", "KAWL", startCal.getTime(), endCal.getTime(), "Flow.KAWL.Project_Total") - gateCalc.computeFlowGroup("SWT", "KAWL", startCal.getTime(), endCal.getTime(), "Flow.KAWL.Gated_Total") - gateCalc.computeFlowGroup("SWT", "KAWL", startCal.getTime(), endCal.getTime(), "Flow.KAWL.Turbine_Total") + gateCalc.computeFlowGroup("SWT", "KAWL", start_date, end_date, "Flow.KAWL.Project_Total") + gateCalc.computeFlowGroup("SWT", "KAWL", start_date, end_date, "Flow.KAWL.Gated_Total") + gateCalc.computeFlowGroup("SWT", "KAWL", start_date, end_date, "Flow.KAWL.Turbine_Total") #OOLO - gateCalc.computeFlowGroup("SWT", "OOLO", startCal.getTime(), endCal.getTime(), "Flow.OOLO.Project_Total") - gateCalc.computeFlowGroup("SWT", "OOLO", startCal.getTime(), endCal.getTime(), "Flow.OOLO.Gated_Total") + gateCalc.computeFlowGroup("SWT", "OOLO", start_date, end_date, "Flow.OOLO.Project_Total") + gateCalc.computeFlowGroup("SWT", "OOLO", start_date, end_date, "Flow.OOLO.Gated_Total") #COPA - gateCalc.computeFlowGroup("SWT", "COPA", startCal.getTime(), endCal.getTime(), "Flow.COPA.Project_Total") - gateCalc.computeFlowGroup("SWT", "COPA", startCal.getTime(), endCal.getTime(), "Flow.COPA.Gated_Total") + gateCalc.computeFlowGroup("SWT", "COPA", start_date, end_date, "Flow.COPA.Project_Total") + gateCalc.computeFlowGroup("SWT", "COPA", start_date, end_date, "Flow.COPA.Gated_Total") #HULA - gateCalc.computeFlowGroup("SWT", "HULA", startCal.getTime(), endCal.getTime(), "Flow.HULA.Project_Total") - gateCalc.computeFlowGroup("SWT", "HULA", startCal.getTime(), endCal.getTime(), "Flow.HULA.Gated_Total") + gateCalc.computeFlowGroup("SWT", "HULA", start_date, end_date, "Flow.HULA.Project_Total") + gateCalc.computeFlowGroup("SWT", "HULA", start_date, end_date, "Flow.HULA.Gated_Total") #ELKC - gateCalc.computeFlowGroup("SWT", "ELKC", startCal.getTime(), endCal.getTime(), "Flow.ELKC.Project_Total") - gateCalc.computeFlowGroup("SWT", "ELKC", startCal.getTime(), endCal.getTime(), "Flow.ELKC.Gated_Total") + gateCalc.computeFlowGroup("SWT", "ELKC", start_date, end_date, "Flow.ELKC.Project_Total") + gateCalc.computeFlowGroup("SWT", "ELKC", start_date, end_date, "Flow.ELKC.Gated_Total") #FALL - gateCalc.computeFlowGroup("SWT", "FALL", startCal.getTime(), endCal.getTime(), "Flow.FALL.Project_Total") - gateCalc.computeFlowGroup("SWT", "FALL", startCal.getTime(), endCal.getTime(), "Flow.FALL.Gated_Total") + gateCalc.computeFlowGroup("SWT", "FALL", start_date, end_date, "Flow.FALL.Project_Total") + gateCalc.computeFlowGroup("SWT", "FALL", start_date, end_date, "Flow.FALL.Gated_Total") diff --git a/district-scripts/SWT/GateFlowGroup2.py b/district-scripts/SWT/GateFlowGroup2.py index 8beac17..d75c4fb 100644 --- a/district-scripts/SWT/GateFlowGroup2.py +++ b/district-scripts/SWT/GateFlowGroup2.py @@ -2,30 +2,32 @@ def run_calculations(registry): + from datetime import datetime, timedelta, timezone + from zoneinfo import ZoneInfo + # Java imports must happen after regi_session starts the JVM. - from java.util import Calendar - from java.util import TimeZone from usace.rowcps.headless import LoggingOptions - def compute_All_Flowgroups(officeID, location, startCal, endCal): + + def compute_All_Flowgroups(officeID, location, start_date, end_date): # Takes in locations defined by user in group and computes all flow groups try: - gateCalc.computeAll(officeID, location, startCal.getTime(), endCal.getTime()) + gateCalc.computeAll(officeID, location, start_date, end_date) except Exception as e: print("Error Computing all Flow Groups at {0} {1}".format(officeID, location)) print(e) print('') - def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): + def compute_Single_Flowgroup(officeID, location, start_date, end_date, flowGroup): try: - gateCalc.computeFlowGroup(officeID, location, startCal.getTime(), endCal.getTime(), "Flow.{0}.{1}".format(location, flowGroup)) + gateCalc.computeFlowGroup(officeID, location, start_date, end_date, "Flow.{0}.{1}".format(location, flowGroup)) except Exception as e: print("Error Computing Flow Group {0} at {1}".format(officeID, location)) print(e) print('') - # #gateCalc.computeFlowGroup("SWF", "ACTT2", startCal.getTime(), endCal.getTime(), "Flow.ACTT2.Pump_Out_Total") + # #gateCalc.computeFlowGroup("SWF", "ACTT2", start_date, end_date, "Flow.ACTT2.Pump_Out_Total") # Description of: LoggingOptions.setDbMessageLevel(int level) # # Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended @@ -65,31 +67,22 @@ def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): # this retrieves a Gate Flow calculation object gateCalc = registry.getCalculation(1.0, "Gate Flow") - # Time zone must be set because the Solaris time zone is UTC - timeZone = TimeZone.getTimeZone("US/Central") + # Time zone must be set explicitly because the JVM's default timezone is + # UTC, not the district's local time. + central = ZoneInfo("America/Chicago") # Defaults to start of the day 5 days ago, and ends at the top of the current hour today - # configure the start calendar - startCal = Calendar.getInstance(timeZone) - startCal.add(Calendar.DAY_OF_MONTH, -5) - #startCal.add(Calendar.HOUR, -7) - startCal.set(Calendar.MINUTE, 0) - startCal.set(Calendar.SECOND, 0) - startCal.set(Calendar.MILLISECOND, 0) - - - # configure the end calendar - endCal = Calendar.getInstance(timeZone) - endCal.set(Calendar.MINUTE, 0) - endCal.set(Calendar.SECOND, 0) - endCal.set(Calendar.MILLISECOND, 0) - #endCal.add(Calendar.MONTH, -3) - - # Calendar can be adjusted using the following functions: - # startCal.set(Calendar.DATE, 1) # Sets the date of the calendar. - # startCal.set(Calendar.HOUR_OF_DAY, 1) # Sets the hour of the day to 0100 (1-24) - # startCal.set(Calendar.YEAR, 2020) # Sets the year - # startCal.set(Calendar.MONTH, 4) # Sets the month (month 4 means May to Java) + end_date_dt = datetime.now(central).replace(minute=0, second=0, microsecond=0) + start_date_dt = end_date_dt - timedelta(days=5) + #start_date_dt = end_date_dt - timedelta(days=5, hours=7) + + start_date = start_date_dt.astimezone(timezone.utc) + end_date = end_date_dt.astimezone(timezone.utc) + + # Dates can be adjusted using normal datetime arithmetic/replace, e.g.: + # start_date_dt = start_date_dt.replace(day=1) # start of month + # start_date_dt = start_date_dt.replace(hour=1) # 0100 local time + # start_date_dt = start_date_dt.replace(year=2020, month=5) # month is 1-indexed here officeID = "SWT" @@ -99,32 +92,32 @@ def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): # projectId # startDate # endDate - # gateCalc.computeFlowGroup("SWF", "LEWT2", startCal.getTime(), endCal.getTime(), "Flow.LEWT2.ConduitGate_Total") + # gateCalc.computeFlowGroup("SWF", "LEWT2", start_date, end_date, "Flow.LEWT2.ConduitGate_Total") # # GROUP 2 PROJECTS (SELF-TIMED TRANSMISSIONS WITHIN THE FIRST 2 - 4 MINUTES OF THE TOP OF THE HOUR) # #ARCA - gateCalc.computeFlowGroup("SWT", "ARCA", startCal.getTime(), endCal.getTime(), "Flow.ARCA.Project_Total") - gateCalc.computeFlowGroup("SWT", "ARCA", startCal.getTime(), endCal.getTime(), "Flow.ARCA.Gated_Total") + gateCalc.computeFlowGroup("SWT", "ARCA", start_date, end_date, "Flow.ARCA.Project_Total") + gateCalc.computeFlowGroup("SWT", "ARCA", start_date, end_date, "Flow.ARCA.Gated_Total") #ARBU - gateCalc.computeFlowGroup("SWT", "ARBU", startCal.getTime(), endCal.getTime(), "Flow.ARBU.Project_Total") - gateCalc.computeFlowGroup("SWT", "ARBU", startCal.getTime(), endCal.getTime(), "Flow.ARBU.Gated_Total") + gateCalc.computeFlowGroup("SWT", "ARBU", start_date, end_date, "Flow.ARBU.Project_Total") + gateCalc.computeFlowGroup("SWT", "ARBU", start_date, end_date, "Flow.ARBU.Gated_Total") #BIRC - gateCalc.computeFlowGroup("SWT", "BIRC", startCal.getTime(), endCal.getTime(), "Flow.BIRC.Project_Total") - gateCalc.computeFlowGroup("SWT", "BIRC", startCal.getTime(), endCal.getTime(), "Flow.BIRC.Gated_Total") + gateCalc.computeFlowGroup("SWT", "BIRC", start_date, end_date, "Flow.BIRC.Project_Total") + gateCalc.computeFlowGroup("SWT", "BIRC", start_date, end_date, "Flow.BIRC.Gated_Total") #ROBE - gateCalc.computeFlowGroup("SWT", "ROBE", startCal.getTime(), endCal.getTime(), "Flow.ROBE.Project_Total") - gateCalc.computeFlowGroup("SWT", "ROBE", startCal.getTime(), endCal.getTime(), "Flow.ROBE.Gated_Total") - gateCalc.computeFlowGroup("SWT", "ROBE", startCal.getTime(), endCal.getTime(), "Flow.ROBE.Turbine_Total") + gateCalc.computeFlowGroup("SWT", "ROBE", start_date, end_date, "Flow.ROBE.Project_Total") + gateCalc.computeFlowGroup("SWT", "ROBE", start_date, end_date, "Flow.ROBE.Gated_Total") + gateCalc.computeFlowGroup("SWT", "ROBE", start_date, end_date, "Flow.ROBE.Turbine_Total") #WAUR - gateCalc.computeFlowGroup("SWT", "WAUR", startCal.getTime(), endCal.getTime(), "Flow.WAUR.Project_Total") - gateCalc.computeFlowGroup("SWT", "WAUR", startCal.getTime(), endCal.getTime(), "Flow.WAUR.Gated_Total") + gateCalc.computeFlowGroup("SWT", "WAUR", start_date, end_date, "Flow.WAUR.Project_Total") + gateCalc.computeFlowGroup("SWT", "WAUR", start_date, end_date, "Flow.WAUR.Gated_Total") diff --git a/district-scripts/SWT/GateFlowGroup3.py b/district-scripts/SWT/GateFlowGroup3.py index cf5a667..28a3b9b 100644 --- a/district-scripts/SWT/GateFlowGroup3.py +++ b/district-scripts/SWT/GateFlowGroup3.py @@ -2,30 +2,32 @@ def run_calculations(registry): + from datetime import datetime, timedelta, timezone + from zoneinfo import ZoneInfo + # Java imports must happen after regi_session starts the JVM. - from java.util import Calendar - from java.util import TimeZone from usace.rowcps.headless import LoggingOptions - def compute_All_Flowgroups(officeID, location, startCal, endCal): + + def compute_All_Flowgroups(officeID, location, start_date, end_date): # Takes in locations defined by user in group and computes all flow groups try: - gateCalc.computeAll(officeID, location, startCal.getTime(), endCal.getTime()) + gateCalc.computeAll(officeID, location, start_date, end_date) except Exception as e: print("Error Computing all Flow Groups at {0} {1}".format(officeID, location)) print(e) print('') - def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): + def compute_Single_Flowgroup(officeID, location, start_date, end_date, flowGroup): try: - gateCalc.computeFlowGroup(officeID, location, startCal.getTime(), endCal.getTime(), "Flow.{0}.{1}".format(location, flowGroup)) + gateCalc.computeFlowGroup(officeID, location, start_date, end_date, "Flow.{0}.{1}".format(location, flowGroup)) except Exception as e: print("Error Computing Flow Group {0} at {1}".format(officeID, location)) print(e) print('') - # #gateCalc.computeFlowGroup("SWF", "ACTT2", startCal.getTime(), endCal.getTime(), "Flow.ACTT2.Pump_Out_Total") + # #gateCalc.computeFlowGroup("SWF", "ACTT2", start_date, end_date, "Flow.ACTT2.Pump_Out_Total") # Description of: LoggingOptions.setDbMessageLevel(int level) # # Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended @@ -65,31 +67,23 @@ def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): # this retrieves a Gate Flow calculation object gateCalc = registry.getCalculation(1.0, "Gate Flow") - # Time zone must be set because the Solaris time zone is UTC - timeZone = TimeZone.getTimeZone("US/Central") + # Time zone must be set explicitly because the JVM's default timezone is + # UTC, not the district's local time. + central = ZoneInfo("America/Chicago") # Defaults to start of the day 5 days ago, and ends at the top of the current hour today - # configure the start calendar - startCal = Calendar.getInstance(timeZone) - startCal.add(Calendar.DAY_OF_MONTH, -5) - #startCal.add(Calendar.HOUR, -7) - startCal.set(Calendar.MINUTE, 0) - startCal.set(Calendar.SECOND, 0) - startCal.set(Calendar.MILLISECOND, 0) - - - # configure the end calendar - endCal = Calendar.getInstance(timeZone) - endCal.set(Calendar.MINUTE, 0) - endCal.set(Calendar.SECOND, 0) - endCal.set(Calendar.MILLISECOND, 0) - #endCal.add(Calendar.DAY_OF_MONTH, -12) - - # Calendar can be adjusted using the following functions: - # startCal.set(Calendar.DATE, 1) # Sets the date of the calendar. - # startCal.set(Calendar.HOUR_OF_DAY, 1) # Sets the hour of the day to 0100 (1-24) - # startCal.set(Calendar.YEAR, 2020) # Sets the year - # startCal.set(Calendar.MONTH, 4) # Sets the month (month 4 means May to Java) + end_date_dt = datetime.now(central).replace(minute=0, second=0, microsecond=0) + start_date_dt = end_date_dt - timedelta(days=5) + #start_date_dt = end_date_dt - timedelta(days=5, hours=7) + #end_date_dt = end_date_dt - timedelta(days=12) + + start_date = start_date_dt.astimezone(timezone.utc) + end_date = end_date_dt.astimezone(timezone.utc) + + # Dates can be adjusted using normal datetime arithmetic/replace, e.g.: + # start_date_dt = start_date_dt.replace(day=1) # start of month + # start_date_dt = start_date_dt.replace(hour=1) # 0100 local time + # start_date_dt = start_date_dt.replace(year=2020, month=5) # month is 1-indexed here officeID = "SWT" @@ -99,40 +93,40 @@ def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): # projectId # startDate # endDate - # gateCalc.computeFlowGroup("SWF", "LEWT2", startCal.getTime(), endCal.getTime(), "Flow.LEWT2.ConduitGate_Total") + # gateCalc.computeFlowGroup("SWF", "LEWT2", start_date, end_date, "Flow.LEWT2.ConduitGate_Total") # # GROUP 3 PROJECTS (SELF-TIMED TRANSMISSIONS WITHIN 5 TO 8 MINUTES OF THE TOP OF THE HOUR) # #COUN - gateCalc.computeFlowGroup("SWT", "COUN", startCal.getTime(), endCal.getTime(), "Flow.COUN.Project_Total") - gateCalc.computeFlowGroup("SWT", "COUN", startCal.getTime(), endCal.getTime(), "Flow.COUN.Gated_Total") + gateCalc.computeFlowGroup("SWT", "COUN", start_date, end_date, "Flow.COUN.Project_Total") + gateCalc.computeFlowGroup("SWT", "COUN", start_date, end_date, "Flow.COUN.Gated_Total") #HUGO - gateCalc.computeFlowGroup("SWT", "HUGO", startCal.getTime(), endCal.getTime(), "Flow.HUGO.Project_Total") - gateCalc.computeFlowGroup("SWT", "HUGO", startCal.getTime(), endCal.getTime(), "Flow.HUGO.Gated_Total") + gateCalc.computeFlowGroup("SWT", "HUGO", start_date, end_date, "Flow.HUGO.Project_Total") + gateCalc.computeFlowGroup("SWT", "HUGO", start_date, end_date, "Flow.HUGO.Gated_Total") #MARI - gateCalc.computeFlowGroup("SWT", "MARI", startCal.getTime(), endCal.getTime(), "Flow.MARI.Project_Total") - gateCalc.computeFlowGroup("SWT", "MARI", startCal.getTime(), endCal.getTime(), "Flow.MARI.Gated_Total") + gateCalc.computeFlowGroup("SWT", "MARI", start_date, end_date, "Flow.MARI.Project_Total") + gateCalc.computeFlowGroup("SWT", "MARI", start_date, end_date, "Flow.MARI.Gated_Total") #PATM - gateCalc.computeFlowGroup("SWT", "PATM", startCal.getTime(), endCal.getTime(), "Flow.PATM.Project_Total") - gateCalc.computeFlowGroup("SWT", "PATM", startCal.getTime(), endCal.getTime(), "Flow.PATM.Gated_Total") + gateCalc.computeFlowGroup("SWT", "PATM", start_date, end_date, "Flow.PATM.Project_Total") + gateCalc.computeFlowGroup("SWT", "PATM", start_date, end_date, "Flow.PATM.Gated_Total") #FSUP - gateCalc.computeFlowGroup("SWT", "FSUP", startCal.getTime(), endCal.getTime(), "Flow.FSUP.Project_Total") - gateCalc.computeFlowGroup("SWT", "FSUP", startCal.getTime(), endCal.getTime(), "Flow.FSUP.Gated_Total") + gateCalc.computeFlowGroup("SWT", "FSUP", start_date, end_date, "Flow.FSUP.Project_Total") + gateCalc.computeFlowGroup("SWT", "FSUP", start_date, end_date, "Flow.FSUP.Gated_Total") #CANT - gateCalc.computeFlowGroup("SWT", "CANT", startCal.getTime(), endCal.getTime(), "Flow.CANT.Project_Total") - gateCalc.computeFlowGroup("SWT", "CANT", startCal.getTime(), endCal.getTime(), "Flow.CANT.Gated_Total") + gateCalc.computeFlowGroup("SWT", "CANT", start_date, end_date, "Flow.CANT.Project_Total") + gateCalc.computeFlowGroup("SWT", "CANT", start_date, end_date, "Flow.CANT.Gated_Total") #HUDS - gateCalc.computeFlowGroup("SWT", "HUDS", startCal.getTime(), endCal.getTime(), "Flow.HUDS.Project_Total") - gateCalc.computeFlowGroup("SWT", "HUDS", startCal.getTime(), endCal.getTime(), "Flow.HUDS.Turbine_Total") - gateCalc.computeFlowGroup("SWT", "HUDS", startCal.getTime(), endCal.getTime(), "Flow.HUDS.Gated_Total") + gateCalc.computeFlowGroup("SWT", "HUDS", start_date, end_date, "Flow.HUDS.Project_Total") + gateCalc.computeFlowGroup("SWT", "HUDS", start_date, end_date, "Flow.HUDS.Turbine_Total") + gateCalc.computeFlowGroup("SWT", "HUDS", start_date, end_date, "Flow.HUDS.Gated_Total") diff --git a/district-scripts/SWT/GateFlowGroup4.py b/district-scripts/SWT/GateFlowGroup4.py index c42c619..5ce4412 100644 --- a/district-scripts/SWT/GateFlowGroup4.py +++ b/district-scripts/SWT/GateFlowGroup4.py @@ -2,30 +2,32 @@ def run_calculations(registry): + from datetime import datetime, timedelta, timezone + from zoneinfo import ZoneInfo + # Java imports must happen after regi_session starts the JVM. - from java.util import Calendar - from java.util import TimeZone from usace.rowcps.headless import LoggingOptions - def compute_All_Flowgroups(officeID, location, startCal, endCal): + + def compute_All_Flowgroups(officeID, location, start_date, end_date): # Takes in locations defined by user in group and computes all flow groups try: - gateCalc.computeAll(officeID, location, startCal.getTime(), endCal.getTime()) + gateCalc.computeAll(officeID, location, start_date, end_date) except Exception as e: print("Error Computing all Flow Groups at {0} {1}".format(officeID, location)) print(e) print('') - def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): + def compute_Single_Flowgroup(officeID, location, start_date, end_date, flowGroup): try: - gateCalc.computeFlowGroup(officeID, location, startCal.getTime(), endCal.getTime(), "Flow.{0}.{1}".format(location, flowGroup)) + gateCalc.computeFlowGroup(officeID, location, start_date, end_date, "Flow.{0}.{1}".format(location, flowGroup)) except Exception as e: print("Error Computing Flow Group {0} at {1}".format(officeID, location)) print(e) print('') - # #gateCalc.computeFlowGroup("SWF", "ACTT2", startCal.getTime(), endCal.getTime(), "Flow.ACTT2.Pump_Out_Total") + # #gateCalc.computeFlowGroup("SWF", "ACTT2", start_date, end_date, "Flow.ACTT2.Pump_Out_Total") # Description of: LoggingOptions.setDbMessageLevel(int level) # # Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended @@ -65,31 +67,22 @@ def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): # this retrieves a Gate Flow calculation object gateCalc = registry.getCalculation(1.0, "Gate Flow") - # Time zone must be set because the Solaris time zone is UTC - timeZone = TimeZone.getTimeZone("US/Central") + # Time zone must be set explicitly because the JVM's default timezone is + # UTC, not the district's local time. + central = ZoneInfo("America/Chicago") # Defaults to start of the day 5 days ago, and ends at the top of the current hour today - # configure the start calendar - startCal = Calendar.getInstance(timeZone) - startCal.add(Calendar.DAY_OF_MONTH, -5) - #startCal.add(Calendar.HOUR, -7) - startCal.set(Calendar.MINUTE, 0) - startCal.set(Calendar.SECOND, 0) - startCal.set(Calendar.MILLISECOND, 0) - - - # configure the end calendar - endCal = Calendar.getInstance(timeZone) - endCal.set(Calendar.MINUTE, 0) - endCal.set(Calendar.SECOND, 0) - endCal.set(Calendar.MILLISECOND, 0) - #endCal.add(Calendar.MONTH, -3) - - # Calendar can be adjusted using the following functions: - # startCal.set(Calendar.DATE, 1) # Sets the date of the calendar. - # startCal.set(Calendar.HOUR_OF_DAY, 1) # Sets the hour of the day to 0100 (1-24) - # startCal.set(Calendar.YEAR, 2020) # Sets the year - # startCal.set(Calendar.MONTH, 4) # Sets the month (month 4 means May to Java) + end_date_dt = datetime.now(central).replace(minute=0, second=0, microsecond=0) + start_date_dt = end_date_dt - timedelta(days=5) + #start_date_dt = end_date_dt - timedelta(days=5, hours=7) + + start_date = start_date_dt.astimezone(timezone.utc) + end_date = end_date_dt.astimezone(timezone.utc) + + # Dates can be adjusted using normal datetime arithmetic/replace, e.g.: + # start_date_dt = start_date_dt.replace(day=1) # start of month + # start_date_dt = start_date_dt.replace(hour=1) # 0100 local time + # start_date_dt = start_date_dt.replace(year=2020, month=5) # month is 1-indexed here officeID = "SWT" @@ -99,7 +92,7 @@ def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): # projectId # startDate # endDate - # gateCalc.computeFlowGroup("SWF", "LEWT2", startCal.getTime(), endCal.getTime(), "Flow.LEWT2.ConduitGate_Total") + # gateCalc.computeFlowGroup("SWF", "LEWT2", start_date, end_date, "Flow.LEWT2.ConduitGate_Total") # @@ -107,27 +100,27 @@ def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): # #DENI - gateCalc.computeFlowGroup("SWT", "DENI", startCal.getTime(), endCal.getTime(), "Flow.DENI.Project_Total") - gateCalc.computeFlowGroup("SWT", "DENI", startCal.getTime(), endCal.getTime(), "Flow.DENI.Turbine_Total") - gateCalc.computeFlowGroup("SWT", "DENI", startCal.getTime(), endCal.getTime(), "Flow.DENI.Gated_Total") + gateCalc.computeFlowGroup("SWT", "DENI", start_date, end_date, "Flow.DENI.Project_Total") + gateCalc.computeFlowGroup("SWT", "DENI", start_date, end_date, "Flow.DENI.Turbine_Total") + gateCalc.computeFlowGroup("SWT", "DENI", start_date, end_date, "Flow.DENI.Gated_Total") #PINE - gateCalc.computeFlowGroup("SWT", "PINE", startCal.getTime(), endCal.getTime(), "Flow.PINE.Project_Total") - gateCalc.computeFlowGroup("SWT", "PINE", startCal.getTime(), endCal.getTime(), "Flow.PINE.Gated_Total") + gateCalc.computeFlowGroup("SWT", "PINE", start_date, end_date, "Flow.PINE.Project_Total") + gateCalc.computeFlowGroup("SWT", "PINE", start_date, end_date, "Flow.PINE.Gated_Total") #BROK - gateCalc.computeFlowGroup("SWT", "BROK", startCal.getTime(), endCal.getTime(), "Flow.BROK.Project_Total") - gateCalc.computeFlowGroup("SWT", "BROK", startCal.getTime(), endCal.getTime(), "Flow.BROK.Turbine_Total") - gateCalc.computeFlowGroup("SWT", "BROK", startCal.getTime(), endCal.getTime(), "Flow.BROK.Gated_Total") + gateCalc.computeFlowGroup("SWT", "BROK", start_date, end_date, "Flow.BROK.Project_Total") + gateCalc.computeFlowGroup("SWT", "BROK", start_date, end_date, "Flow.BROK.Turbine_Total") + gateCalc.computeFlowGroup("SWT", "BROK", start_date, end_date, "Flow.BROK.Gated_Total") #SARD - gateCalc.computeFlowGroup("SWT", "SARD", startCal.getTime(), endCal.getTime(), "Flow.SARD.Project_Total") - gateCalc.computeFlowGroup("SWT", "SARD", startCal.getTime(), endCal.getTime(), "Flow.SARD.Gated_Total") + gateCalc.computeFlowGroup("SWT", "SARD", start_date, end_date, "Flow.SARD.Project_Total") + gateCalc.computeFlowGroup("SWT", "SARD", start_date, end_date, "Flow.SARD.Gated_Total") #EUFA - gateCalc.computeFlowGroup("SWT", "EUFA", startCal.getTime(), endCal.getTime(), "Flow.EUFA.Project_Total") - gateCalc.computeFlowGroup("SWT", "EUFA", startCal.getTime(), endCal.getTime(), "Flow.EUFA.Turbine_Total") - gateCalc.computeFlowGroup("SWT", "EUFA", startCal.getTime(), endCal.getTime(), "Flow.EUFA.Gated_Total") + gateCalc.computeFlowGroup("SWT", "EUFA", start_date, end_date, "Flow.EUFA.Project_Total") + gateCalc.computeFlowGroup("SWT", "EUFA", start_date, end_date, "Flow.EUFA.Turbine_Total") + gateCalc.computeFlowGroup("SWT", "EUFA", start_date, end_date, "Flow.EUFA.Gated_Total") diff --git a/district-scripts/SWT/GateFlowGroup5.py b/district-scripts/SWT/GateFlowGroup5.py index f0133ba..2401e09 100644 --- a/district-scripts/SWT/GateFlowGroup5.py +++ b/district-scripts/SWT/GateFlowGroup5.py @@ -2,30 +2,32 @@ def run_calculations(registry): + from datetime import datetime, timedelta, timezone + from zoneinfo import ZoneInfo + # Java imports must happen after regi_session starts the JVM. - from java.util import Calendar - from java.util import TimeZone from usace.rowcps.headless import LoggingOptions - def compute_All_Flowgroups(officeID, location, startCal, endCal): + + def compute_All_Flowgroups(officeID, location, start_date, end_date): # Takes in locations defined by user in group and computes all flow groups try: - gateCalc.computeAll(officeID, location, startCal.getTime(), endCal.getTime()) + gateCalc.computeAll(officeID, location, start_date, end_date) except Exception as e: print("Error Computing all Flow Groups at {0} {1}".format(officeID, location)) print(e) print('') - def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): + def compute_Single_Flowgroup(officeID, location, start_date, end_date, flowGroup): try: - gateCalc.computeFlowGroup(officeID, location, startCal.getTime(), endCal.getTime(), "Flow.{0}.{1}".format(location, flowGroup)) + gateCalc.computeFlowGroup(officeID, location, start_date, end_date, "Flow.{0}.{1}".format(location, flowGroup)) except Exception as e: print("Error Computing Flow Group {0} at {1}".format(officeID, location)) print(e) print('') - # #gateCalc.computeFlowGroup("SWF", "ACTT2", startCal.getTime(), endCal.getTime(), "Flow.ACTT2.Pump_Out_Total") + # #gateCalc.computeFlowGroup("SWF", "ACTT2", start_date, end_date, "Flow.ACTT2.Pump_Out_Total") # Description of: LoggingOptions.setDbMessageLevel(int level) # # Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended @@ -65,31 +67,22 @@ def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): # this retrieves a Gate Flow calculation object gateCalc = registry.getCalculation(1.0, "Gate Flow") - # Time zone must be set because the Solaris time zone is UTC - timeZone = TimeZone.getTimeZone("US/Central") + # Time zone must be set explicitly because the JVM's default timezone is + # UTC, not the district's local time. + central = ZoneInfo("America/Chicago") # Defaults to start of the day 5 days ago, and ends at the top of the current hour today - # configure the start calendar - startCal = Calendar.getInstance(timeZone) - startCal.add(Calendar.DAY_OF_MONTH, -5) - #startCal.add(Calendar.HOUR, -7) - startCal.set(Calendar.MINUTE, 0) - startCal.set(Calendar.SECOND, 0) - startCal.set(Calendar.MILLISECOND, 0) - - - # configure the end calendar - endCal = Calendar.getInstance(timeZone) - endCal.set(Calendar.MINUTE, 0) - endCal.set(Calendar.SECOND, 0) - endCal.set(Calendar.MILLISECOND, 0) - #endCal.add(Calendar.MONTH, -3) - - # Calendar can be adjusted using the following functions: - # startCal.set(Calendar.DATE, 1) # Sets the date of the calendar. - # startCal.set(Calendar.HOUR_OF_DAY, 1) # Sets the hour of the day to 0100 (1-24) - # startCal.set(Calendar.YEAR, 2020) # Sets the year - # startCal.set(Calendar.MONTH, 4) # Sets the month (month 4 means May to Java) + end_date_dt = datetime.now(central).replace(minute=0, second=0, microsecond=0) + start_date_dt = end_date_dt - timedelta(days=5) + #start_date_dt = end_date_dt - timedelta(days=5, hours=7) + + start_date = start_date_dt.astimezone(timezone.utc) + end_date = end_date_dt.astimezone(timezone.utc) + + # Dates can be adjusted using normal datetime arithmetic/replace, e.g.: + # start_date_dt = start_date_dt.replace(day=1) # start of month + # start_date_dt = start_date_dt.replace(hour=1) # 0100 local time + # start_date_dt = start_date_dt.replace(year=2020, month=5) # month is 1-indexed here officeID = "SWT" @@ -99,23 +92,23 @@ def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): # projectId # startDate # endDate - # gateCalc.computeFlowGroup("SWF", "LEWT2", startCal.getTime(), endCal.getTime(), "Flow.LEWT2.ConduitGate_Total") + # gateCalc.computeFlowGroup("SWF", "LEWT2", start_date, end_date, "Flow.LEWT2.ConduitGate_Total") # # GROUP 5 PROJECTS (SELF-TIMED TRANSMISSIONS WITHIN 19 TO 21 MINUTES PAST THE TOP OF THE HOUR) # #MCGE - gateCalc.computeFlowGroup("SWT", "MCGE", startCal.getTime(), endCal.getTime(), "Flow.MCGE.Project_Total") - gateCalc.computeFlowGroup("SWT", "MCGE", startCal.getTime(), endCal.getTime(), "Flow.MCGE.Gated_Total") + gateCalc.computeFlowGroup("SWT", "MCGE", start_date, end_date, "Flow.MCGE.Project_Total") + gateCalc.computeFlowGroup("SWT", "MCGE", start_date, end_date, "Flow.MCGE.Gated_Total") #BIGH - gateCalc.computeFlowGroup("SWT", "BIGH", startCal.getTime(), endCal.getTime(), "Flow.BIGH.Project_Total") - gateCalc.computeFlowGroup("SWT", "BIGH", startCal.getTime(), endCal.getTime(), "Flow.BIGH.Gated_Total") + gateCalc.computeFlowGroup("SWT", "BIGH", start_date, end_date, "Flow.BIGH.Project_Total") + gateCalc.computeFlowGroup("SWT", "BIGH", start_date, end_date, "Flow.BIGH.Gated_Total") #KEMP - gateCalc.computeFlowGroup("SWT", "KEMP", startCal.getTime(), endCal.getTime(), "Flow.KEMP.Project_Total") - gateCalc.computeFlowGroup("SWT", "KEMP", startCal.getTime(), endCal.getTime(), "Flow.KEMP.Gated_Total") + gateCalc.computeFlowGroup("SWT", "KEMP", start_date, end_date, "Flow.KEMP.Project_Total") + gateCalc.computeFlowGroup("SWT", "KEMP", start_date, end_date, "Flow.KEMP.Gated_Total") if __name__ == "__main__": diff --git a/district-scripts/SWT/GateFlowGroup6.py b/district-scripts/SWT/GateFlowGroup6.py index 933592d..c735906 100644 --- a/district-scripts/SWT/GateFlowGroup6.py +++ b/district-scripts/SWT/GateFlowGroup6.py @@ -2,30 +2,32 @@ def run_calculations(registry): + from datetime import datetime, timedelta, timezone + from zoneinfo import ZoneInfo + # Java imports must happen after regi_session starts the JVM. - from java.util import Calendar - from java.util import TimeZone from usace.rowcps.headless import LoggingOptions - def compute_All_Flowgroups(officeID, location, startCal, endCal): + + def compute_All_Flowgroups(officeID, location, start_date, end_date): # Takes in locations defined by user in group and computes all flow groups try: - gateCalc.computeAll(officeID, location, startCal.getTime(), endCal.getTime()) + gateCalc.computeAll(officeID, location, start_date, end_date) except Exception as e: print("Error Computing all Flow Groups at {0} {1}".format(officeID, location)) print(e) print('') - def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): + def compute_Single_Flowgroup(officeID, location, start_date, end_date, flowGroup): try: - gateCalc.computeFlowGroup(officeID, location, startCal.getTime(), endCal.getTime(), "Flow.{0}.{1}".format(location, flowGroup)) + gateCalc.computeFlowGroup(officeID, location, start_date, end_date, "Flow.{0}.{1}".format(location, flowGroup)) except Exception as e: print("Error Computing Flow Group {0} at {1}".format(officeID, location)) print(e) print('') - # #gateCalc.computeFlowGroup("SWF", "ACTT2", startCal.getTime(), endCal.getTime(), "Flow.ACTT2.Pump_Out_Total") + # #gateCalc.computeFlowGroup("SWF", "ACTT2", start_date, end_date, "Flow.ACTT2.Pump_Out_Total") # Description of: LoggingOptions.setDbMessageLevel(int level) # # Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended @@ -65,37 +67,24 @@ def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): # this retrieves a Gate Flow calculation object gateCalc = registry.getCalculation(1.0, "Gate Flow") - # Time zone must be set because the Solaris time zone is UTC - timeZone = TimeZone.getTimeZone("US/Central") + # Time zone must be set explicitly because the JVM's default timezone is + # UTC, not the district's local time. + central = ZoneInfo("America/Chicago") # Defaults to start of the day 5 days ago, and ends at the top of the current hour today - # configure the start calendar - startCal = Calendar.getInstance(timeZone) - startCal.add(Calendar.DAY_OF_MONTH, -5) - #startCal.add(Calendar.HOUR, -7) - startCal.set(Calendar.MINUTE, 0) - startCal.set(Calendar.SECOND, 0) - startCal.set(Calendar.MILLISECOND, 0) - - - #startCal.set(Calendar.YEAR, 2025) - #startCal.set(Calendar.MONTH, 0) #e.g. 6 ==July - #startCal.set(Calendar.DAY_OF_MONTH, 14) - + end_date_dt = datetime.now(central).replace(minute=0, second=0, microsecond=0) + start_date_dt = end_date_dt - timedelta(days=5) + #start_date_dt = end_date_dt - timedelta(days=5, hours=7) - # configure the end calendar - endCal = Calendar.getInstance(timeZone) - endCal.set(Calendar.MINUTE, 0) - endCal.set(Calendar.SECOND, 0) - endCal.set(Calendar.MILLISECOND, 0) - #endCal.add(Calendar.MONTH, -3) + #start_date_dt = start_date_dt.replace(year=2025, month=1, day=14) # month is 1-indexed here + start_date = start_date_dt.astimezone(timezone.utc) + end_date = end_date_dt.astimezone(timezone.utc) - # Calendar can be adjusted using the following functions: - # startCal.set(Calendar.DATE, 1) # Sets the date of the calendar. - # startCal.set(Calendar.HOUR_OF_DAY, 1) # Sets the hour of the day to 0100 (1-24) - # startCal.set(Calendar.YEAR, 2020) # Sets the year - # startCal.set(Calendar.MONTH, 4) # Sets the month (month 4 means May to Java) + # Dates can be adjusted using normal datetime arithmetic/replace, e.g.: + # start_date_dt = start_date_dt.replace(day=1) # start of month + # start_date_dt = start_date_dt.replace(hour=1) # 0100 local time + # start_date_dt = start_date_dt.replace(year=2020, month=5) # month is 1-indexed here officeID = "SWT" @@ -105,7 +94,7 @@ def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): # projectId # startDate # endDate - # gateCalc.computeFlowGroup("SWF", "LEWT2", startCal.getTime(), endCal.getTime(), "Flow.LEWT2.ConduitGate_Total") + # gateCalc.computeFlowGroup("SWF", "LEWT2", start_date, end_date, "Flow.LEWT2.ConduitGate_Total") # @@ -113,40 +102,40 @@ def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): # #WDMA - gateCalc.computeFlowGroup("SWT", "WDMA", startCal.getTime(), endCal.getTime(), "Flow.WDMA.Project_Total") - gateCalc.computeFlowGroup("SWT", "WDMA", startCal.getTime(), endCal.getTime(), "Flow.WDMA.Gated_Total") + gateCalc.computeFlowGroup("SWT", "WDMA", start_date, end_date, "Flow.WDMA.Project_Total") + gateCalc.computeFlowGroup("SWT", "WDMA", start_date, end_date, "Flow.WDMA.Gated_Total") #WEBB - gateCalc.computeFlowGroup("SWT", "WEBB", startCal.getTime(), endCal.getTime(), "Flow.WEBB.Project_Total") - gateCalc.computeFlowGroup("SWT", "WEBB", startCal.getTime(), endCal.getTime(), "Flow.WEBB.Turbine_Total") - gateCalc.computeFlowGroup("SWT", "WEBB", startCal.getTime(), endCal.getTime(), "Flow.WEBB.Gated_Total") + gateCalc.computeFlowGroup("SWT", "WEBB", start_date, end_date, "Flow.WEBB.Project_Total") + gateCalc.computeFlowGroup("SWT", "WEBB", start_date, end_date, "Flow.WEBB.Turbine_Total") + gateCalc.computeFlowGroup("SWT", "WEBB", start_date, end_date, "Flow.WEBB.Gated_Total") #WIST - gateCalc.computeFlowGroup("SWT", "WIST", startCal.getTime(), endCal.getTime(), "Flow.WIST.Project_Total") - gateCalc.computeFlowGroup("SWT", "WIST", startCal.getTime(), endCal.getTime(), "Flow.WIST.Gated_Total") + gateCalc.computeFlowGroup("SWT", "WIST", start_date, end_date, "Flow.WIST.Project_Total") + gateCalc.computeFlowGroup("SWT", "WIST", start_date, end_date, "Flow.WIST.Gated_Total") #TENK - gateCalc.computeFlowGroup("SWT", "TENK", startCal.getTime(), endCal.getTime(), "Flow.TENK.Project_Total") - gateCalc.computeFlowGroup("SWT", "TENK", startCal.getTime(), endCal.getTime(), "Flow.TENK.Turbine_Total") - gateCalc.computeFlowGroup("SWT", "TENK", startCal.getTime(), endCal.getTime(), "Flow.TENK.Gated_Total") + gateCalc.computeFlowGroup("SWT", "TENK", start_date, end_date, "Flow.TENK.Project_Total") + gateCalc.computeFlowGroup("SWT", "TENK", start_date, end_date, "Flow.TENK.Turbine_Total") + gateCalc.computeFlowGroup("SWT", "TENK", start_date, end_date, "Flow.TENK.Gated_Total") #FGIB - gateCalc.computeFlowGroup("SWT", "FGIB", startCal.getTime(), endCal.getTime(), "Flow.FGIB.Project_Total") - gateCalc.computeFlowGroup("SWT", "FGIB", startCal.getTime(), endCal.getTime(), "Flow.FGIB.Turbine_Total") - gateCalc.computeFlowGroup("SWT", "FGIB", startCal.getTime(), endCal.getTime(), "Flow.FGIB.Gated_Total") + gateCalc.computeFlowGroup("SWT", "FGIB", start_date, end_date, "Flow.FGIB.Project_Total") + gateCalc.computeFlowGroup("SWT", "FGIB", start_date, end_date, "Flow.FGIB.Turbine_Total") + gateCalc.computeFlowGroup("SWT", "FGIB", start_date, end_date, "Flow.FGIB.Gated_Total") #THUN - gateCalc.computeFlowGroup("SWT", "THUN", startCal.getTime(), endCal.getTime(), "Flow.THUN.Project_Total") - gateCalc.computeFlowGroup("SWT", "THUN", startCal.getTime(), endCal.getTime(), "Flow.THUN.Gated_Total") + gateCalc.computeFlowGroup("SWT", "THUN", start_date, end_date, "Flow.THUN.Project_Total") + gateCalc.computeFlowGroup("SWT", "THUN", start_date, end_date, "Flow.THUN.Gated_Total") #GSAL - gateCalc.computeFlowGroup("SWT", "GSAL", startCal.getTime(), endCal.getTime(), "Flow.GSAL.Project_Total") - gateCalc.computeFlowGroup("SWT", "GSAL", startCal.getTime(), endCal.getTime(), "Flow.GSAL.Gated_Total") + gateCalc.computeFlowGroup("SWT", "GSAL", start_date, end_date, "Flow.GSAL.Project_Total") + gateCalc.computeFlowGroup("SWT", "GSAL", start_date, end_date, "Flow.GSAL.Gated_Total") #PENS - gateCalc.computeFlowGroup("SWT", "PENS", startCal.getTime(), endCal.getTime(), "Flow.PENS.Project_Total") - gateCalc.computeFlowGroup("SWT", "PENS", startCal.getTime(), endCal.getTime(), "Flow.PENS.Turbine_Total") - gateCalc.computeFlowGroup("SWT", "PENS", startCal.getTime(), endCal.getTime(), "Flow.PENS.Gated_Total") + gateCalc.computeFlowGroup("SWT", "PENS", start_date, end_date, "Flow.PENS.Project_Total") + gateCalc.computeFlowGroup("SWT", "PENS", start_date, end_date, "Flow.PENS.Turbine_Total") + gateCalc.computeFlowGroup("SWT", "PENS", start_date, end_date, "Flow.PENS.Gated_Total") diff --git a/district-scripts/SWT/GateFlowGroup7.py b/district-scripts/SWT/GateFlowGroup7.py index 21a0f89..d00ac37 100644 --- a/district-scripts/SWT/GateFlowGroup7.py +++ b/district-scripts/SWT/GateFlowGroup7.py @@ -2,30 +2,32 @@ def run_calculations(registry): + from datetime import datetime, timedelta, timezone + from zoneinfo import ZoneInfo + # Java imports must happen after regi_session starts the JVM. - from java.util import Calendar - from java.util import TimeZone from usace.rowcps.headless import LoggingOptions - def compute_All_Flowgroups(officeID, location, startCal, endCal): + + def compute_All_Flowgroups(officeID, location, start_date, end_date): # Takes in locations defined by user in group and computes all flow groups try: - gateCalc.computeAll(officeID, location, startCal.getTime(), endCal.getTime()) + gateCalc.computeAll(officeID, location, start_date, end_date) except Exception as e: print("Error Computing all Flow Groups at {0} {1}".format(officeID, location)) print(e) print('') - def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): + def compute_Single_Flowgroup(officeID, location, start_date, end_date, flowGroup): try: - gateCalc.computeFlowGroup(officeID, location, startCal.getTime(), endCal.getTime(), "Flow.{0}.{1}".format(location, flowGroup)) + gateCalc.computeFlowGroup(officeID, location, start_date, end_date, "Flow.{0}.{1}".format(location, flowGroup)) except Exception as e: print("Error Computing Flow Group {0} at {1}".format(officeID, location)) print(e) print('') - # #gateCalc.computeFlowGroup("SWF", "ACTT2", startCal.getTime(), endCal.getTime(), "Flow.ACTT2.Pump_Out_Total") + # #gateCalc.computeFlowGroup("SWF", "ACTT2", start_date, end_date, "Flow.ACTT2.Pump_Out_Total") # Description of: LoggingOptions.setDbMessageLevel(int level) # # Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended @@ -65,32 +67,24 @@ def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): # this retrieves a Gate Flow calculation object gateCalc = registry.getCalculation(1.0, "Gate Flow") - # Time zone must be set because the Solaris time zone is UTC - timeZone = TimeZone.getTimeZone("US/Central") + # Time zone must be set explicitly because the JVM's default timezone is + # UTC, not the district's local time. + central = ZoneInfo("America/Chicago") # Defaults to start of the day 5 days ago, and ends at the top of the current hour today - # configure the start calendar - startCal = Calendar.getInstance(timeZone) - startCal.add(Calendar.DAY_OF_MONTH, -5) - #startCal.add(Calendar.HOUR, -7) + end_date_dt = datetime.now(central).replace(minute=0, second=0, microsecond=0) + start_date_dt = end_date_dt - timedelta(days=5) + #start_date_dt = end_date_dt - timedelta(days=5, hours=7) #remove or comment out the next line when done!! it was for a big backload ajm - #startCal.add(Calendar.MONTH, -10) - startCal.set(Calendar.MINUTE, 0) - startCal.set(Calendar.SECOND, 0) - startCal.set(Calendar.MILLISECOND, 0) - + #start_date_dt = start_date_dt - timedelta(days=305) # ~10 months - # configure the end calendar - endCal = Calendar.getInstance(timeZone) - endCal.set(Calendar.MINUTE, 0) - endCal.set(Calendar.SECOND, 0) - endCal.set(Calendar.MILLISECOND, 0) + start_date = start_date_dt.astimezone(timezone.utc) + end_date = end_date_dt.astimezone(timezone.utc) - # Calendar can be adjusted using the following functions: - # startCal.set(Calendar.DATE, 1) # Sets the date of the calendar. - # startCal.set(Calendar.HOUR_OF_DAY, 1) # Sets the hour of the day to 0100 (1-24) - # startCal.set(Calendar.YEAR, 2020) # Sets the year - # startCal.set(Calendar.MONTH, 4) # Sets the month (month 4 means May to Java) + # Dates can be adjusted using normal datetime arithmetic/replace, e.g.: + # start_date_dt = start_date_dt.replace(day=1) # start of month + # start_date_dt = start_date_dt.replace(hour=1) # 0100 local time + # start_date_dt = start_date_dt.replace(year=2020, month=5) # month is 1-indexed here officeID = "SWT" @@ -100,7 +94,7 @@ def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): # projectId # startDate # endDate - # gateCalc.computeFlowGroup("SWF", "LEWT2", startCal.getTime(), endCal.getTime(), "Flow.LEWT2.ConduitGate_Total") + # gateCalc.computeFlowGroup("SWF", "LEWT2", start_date, end_date, "Flow.LEWT2.ConduitGate_Total") # @@ -108,36 +102,36 @@ def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): # #CHOU - gateCalc.computeFlowGroup("SWT", "CHOU", startCal.getTime(), endCal.getTime(), "Flow.CHOU.Project_Total") - gateCalc.computeFlowGroup("SWT", "CHOU", startCal.getTime(), endCal.getTime(), "Flow.CHOU.Gated_Total") + gateCalc.computeFlowGroup("SWT", "CHOU", start_date, end_date, "Flow.CHOU.Project_Total") + gateCalc.computeFlowGroup("SWT", "CHOU", start_date, end_date, "Flow.CHOU.Gated_Total") #NEWT - gateCalc.computeFlowGroup("SWT", "NEWT", startCal.getTime(), endCal.getTime(), "Flow.NEWT.Project_Total") - gateCalc.computeFlowGroup("SWT", "NEWT", startCal.getTime(), endCal.getTime(), "Flow.NEWT.Gated_Total") + gateCalc.computeFlowGroup("SWT", "NEWT", start_date, end_date, "Flow.NEWT.Project_Total") + gateCalc.computeFlowGroup("SWT", "NEWT", start_date, end_date, "Flow.NEWT.Gated_Total") #TOMS - gateCalc.computeFlowGroup("SWT", "TOMS", startCal.getTime(), endCal.getTime(), "Flow.TOMS.Project_Total") - gateCalc.computeFlowGroup("SWT", "TOMS", startCal.getTime(), endCal.getTime(), "Flow.TOMS.Gated_Total") + gateCalc.computeFlowGroup("SWT", "TOMS", start_date, end_date, "Flow.TOMS.Project_Total") + gateCalc.computeFlowGroup("SWT", "TOMS", start_date, end_date, "Flow.TOMS.Gated_Total") #TORO - gateCalc.computeFlowGroup("SWT", "TORO", startCal.getTime(), endCal.getTime(), "Flow.TORO.Project_Total") - gateCalc.computeFlowGroup("SWT", "TORO", startCal.getTime(), endCal.getTime(), "Flow.TORO.Gated_Total") + gateCalc.computeFlowGroup("SWT", "TORO", start_date, end_date, "Flow.TORO.Project_Total") + gateCalc.computeFlowGroup("SWT", "TORO", start_date, end_date, "Flow.TORO.Gated_Total") #ALTU - gateCalc.computeFlowGroup("SWT", "ALTU", startCal.getTime(), endCal.getTime(), "Flow.ALTU.Project_Total") - gateCalc.computeFlowGroup("SWT", "ALTU", startCal.getTime(), endCal.getTime(), "Flow.ALTU.Gated_Total") + gateCalc.computeFlowGroup("SWT", "ALTU", start_date, end_date, "Flow.ALTU.Project_Total") + gateCalc.computeFlowGroup("SWT", "ALTU", start_date, end_date, "Flow.ALTU.Gated_Total") #ELDR - gateCalc.computeFlowGroup("SWT", "ELDR", startCal.getTime(), endCal.getTime(), "Flow.ELDR.Project_Total") - gateCalc.computeFlowGroup("SWT", "ELDR", startCal.getTime(), endCal.getTime(), "Flow.ELDR.Gated_Total") + gateCalc.computeFlowGroup("SWT", "ELDR", start_date, end_date, "Flow.ELDR.Project_Total") + gateCalc.computeFlowGroup("SWT", "ELDR", start_date, end_date, "Flow.ELDR.Gated_Total") #CHEN - gateCalc.computeFlowGroup("SWT", "CHEN", startCal.getTime(), endCal.getTime(), "Flow.CHEN.Project_Total") - gateCalc.computeFlowGroup("SWT", "CHEN", startCal.getTime(), endCal.getTime(), "Flow.CHEN.Gated_Total") + gateCalc.computeFlowGroup("SWT", "CHEN", start_date, end_date, "Flow.CHEN.Project_Total") + gateCalc.computeFlowGroup("SWT", "CHEN", start_date, end_date, "Flow.CHEN.Gated_Total") #JOHN - gateCalc.computeFlowGroup("SWT", "JOHN", startCal.getTime(), endCal.getTime(), "Flow.JOHN.Project_Total") - gateCalc.computeFlowGroup("SWT", "JOHN", startCal.getTime(), endCal.getTime(), "Flow.JOHN.Gated_Total") + gateCalc.computeFlowGroup("SWT", "JOHN", start_date, end_date, "Flow.JOHN.Project_Total") + gateCalc.computeFlowGroup("SWT", "JOHN", start_date, end_date, "Flow.JOHN.Gated_Total") diff --git a/district-scripts/SWT/GateFlowGroup8.py b/district-scripts/SWT/GateFlowGroup8.py index 83c0b4b..6f30f0d 100644 --- a/district-scripts/SWT/GateFlowGroup8.py +++ b/district-scripts/SWT/GateFlowGroup8.py @@ -2,30 +2,32 @@ def run_calculations(registry): + from datetime import datetime, timedelta, timezone + from zoneinfo import ZoneInfo + # Java imports must happen after regi_session starts the JVM. - from java.util import Calendar - from java.util import TimeZone from usace.rowcps.headless import LoggingOptions - def compute_All_Flowgroups(officeID, location, startCal, endCal): + + def compute_All_Flowgroups(officeID, location, start_date, end_date): # Takes in locations defined by user in group and computes all flow groups try: - gateCalc.computeAll(officeID, location, startCal.getTime(), endCal.getTime()) + gateCalc.computeAll(officeID, location, start_date, end_date) except Exception as e: print("Error Computing all Flow Groups at {0} {1}".format(officeID, location)) print(e) print('') - def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): + def compute_Single_Flowgroup(officeID, location, start_date, end_date, flowGroup): try: - gateCalc.computeFlowGroup(officeID, location, startCal.getTime(), endCal.getTime(), "Flow.{0}.{1}".format(location, flowGroup)) + gateCalc.computeFlowGroup(officeID, location, start_date, end_date, "Flow.{0}.{1}".format(location, flowGroup)) except Exception as e: print("Error Computing Flow Group {0} at {1}".format(officeID, location)) print(e) print('') - # #gateCalc.computeFlowGroup("SWF", "ACTT2", startCal.getTime(), endCal.getTime(), "Flow.ACTT2.Pump_Out_Total") + # #gateCalc.computeFlowGroup("SWF", "ACTT2", start_date, end_date, "Flow.ACTT2.Pump_Out_Total") # Description of: LoggingOptions.setDbMessageLevel(int level) # # Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended @@ -65,31 +67,22 @@ def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): # this retrieves a Gate Flow calculation object gateCalc = registry.getCalculation(1.0, "Gate Flow") - # Time zone must be set because the Solaris time zone is UTC - timeZone = TimeZone.getTimeZone("US/Central") + # Time zone must be set explicitly because the JVM's default timezone is + # UTC, not the district's local time. + central = ZoneInfo("America/Chicago") # Defaults to start of the day 5 days ago, and ends at the top of the current hour today - # configure the start calendar - startCal = Calendar.getInstance(timeZone) - startCal.add(Calendar.DAY_OF_MONTH, -5) - #startCal.add(Calendar.HOUR, -7) - startCal.set(Calendar.MINUTE, 0) - startCal.set(Calendar.SECOND, 0) - startCal.set(Calendar.MILLISECOND, 0) - - - # configure the end calendar - endCal = Calendar.getInstance(timeZone) - endCal.set(Calendar.MINUTE, 0) - endCal.set(Calendar.SECOND, 0) - endCal.set(Calendar.MILLISECOND, 0) - #endCal.add(Calendar.MONTH, -3) - - # Calendar can be adjusted using the following functions: - # startCal.set(Calendar.DATE, 1) # Sets the date of the calendar. - # startCal.set(Calendar.HOUR_OF_DAY, 1) # Sets the hour of the day to 0100 (1-24) - # startCal.set(Calendar.YEAR, 2020) # Sets the year - # startCal.set(Calendar.MONTH, 4) # Sets the month (month 4 means May to Java) + end_date_dt = datetime.now(central).replace(minute=0, second=0, microsecond=0) + start_date_dt = end_date_dt - timedelta(days=5) + #start_date_dt = end_date_dt - timedelta(days=5, hours=7) + + start_date = start_date_dt.astimezone(timezone.utc) + end_date = end_date_dt.astimezone(timezone.utc) + + # Dates can be adjusted using normal datetime arithmetic/replace, e.g.: + # start_date_dt = start_date_dt.replace(day=1) # start of month + # start_date_dt = start_date_dt.replace(hour=1) # 0100 local time + # start_date_dt = start_date_dt.replace(year=2020, month=5) # month is 1-indexed here officeID = "SWT" @@ -99,7 +92,7 @@ def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): # projectId # startDate # endDate - # gateCalc.computeFlowGroup("SWF", "LEWT2", startCal.getTime(), endCal.getTime(), "Flow.LEWT2.ConduitGate_Total") + # gateCalc.computeFlowGroup("SWF", "LEWT2", start_date, end_date, "Flow.LEWT2.ConduitGate_Total") # @@ -107,8 +100,8 @@ def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): # #MERE - gateCalc.computeFlowGroup("SWT", "MERE", startCal.getTime(), endCal.getTime(), "Flow.MERE.Project_Total") - gateCalc.computeFlowGroup("SWT", "MERE", startCal.getTime(), endCal.getTime(), "Flow.MERE.Gated_Total") + gateCalc.computeFlowGroup("SWT", "MERE", start_date, end_date, "Flow.MERE.Project_Total") + gateCalc.computeFlowGroup("SWT", "MERE", start_date, end_date, "Flow.MERE.Gated_Total") diff --git a/district-scripts/SWT/GateFlowGroup9.py b/district-scripts/SWT/GateFlowGroup9.py index 44550e5..98a595a 100644 --- a/district-scripts/SWT/GateFlowGroup9.py +++ b/district-scripts/SWT/GateFlowGroup9.py @@ -2,30 +2,32 @@ def run_calculations(registry): + from datetime import datetime, timedelta, timezone + from zoneinfo import ZoneInfo + # Java imports must happen after regi_session starts the JVM. - from java.util import Calendar - from java.util import TimeZone from usace.rowcps.headless import LoggingOptions - def compute_All_Flowgroups(officeID, location, startCal, endCal): + + def compute_All_Flowgroups(officeID, location, start_date, end_date): # Takes in locations defined by user in group and computes all flow groups try: - gateCalc.computeAll(officeID, location, startCal.getTime(), endCal.getTime()) + gateCalc.computeAll(officeID, location, start_date, end_date) except Exception as e: print("Error Computing all Flow Groups at {0} {1}".format(officeID, location)) print(e) print('') - def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): + def compute_Single_Flowgroup(officeID, location, start_date, end_date, flowGroup): try: - gateCalc.computeFlowGroup(officeID, location, startCal.getTime(), endCal.getTime(), "Flow.{0}.{1}".format(location, flowGroup)) + gateCalc.computeFlowGroup(officeID, location, start_date, end_date, "Flow.{0}.{1}".format(location, flowGroup)) except Exception as e: print("Error Computing Flow Group {0} at {1}".format(officeID, location)) print(e) print('') - # #gateCalc.computeFlowGroup("SWF", "ACTT2", startCal.getTime(), endCal.getTime(), "Flow.ACTT2.Pump_Out_Total") + # #gateCalc.computeFlowGroup("SWF", "ACTT2", start_date, end_date, "Flow.ACTT2.Pump_Out_Total") # Description of: LoggingOptions.setDbMessageLevel(int level) # # Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended @@ -65,31 +67,22 @@ def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): # this retrieves a Gate Flow calculation object gateCalc = registry.getCalculation(1.0, "Gate Flow") - # Time zone must be set because the Solaris time zone is UTC - timeZone = TimeZone.getTimeZone("US/Central") + # Time zone must be set explicitly because the JVM's default timezone is + # UTC, not the district's local time. + central = ZoneInfo("America/Chicago") # Defaults to start of the day 5 days ago, and ends at the top of the current hour today - # configure the start calendar - startCal = Calendar.getInstance(timeZone) - startCal.add(Calendar.DAY_OF_MONTH, -5) - #startCal.add(Calendar.HOUR, -7) - startCal.set(Calendar.MINUTE, 0) - startCal.set(Calendar.SECOND, 0) - startCal.set(Calendar.MILLISECOND, 0) - - - # configure the end calendar - endCal = Calendar.getInstance(timeZone) - endCal.set(Calendar.MINUTE, 0) - endCal.set(Calendar.SECOND, 0) - endCal.set(Calendar.MILLISECOND, 0) - #endCal.add(Calendar.MONTH, -3) - - # Calendar can be adjusted using the following functions: - # startCal.set(Calendar.DATE, 1) # Sets the date of the calendar. - # startCal.set(Calendar.HOUR_OF_DAY, 1) # Sets the hour of the day to 0100 (1-24) - # startCal.set(Calendar.YEAR, 2020) # Sets the year - # startCal.set(Calendar.MONTH, 4) # Sets the month (month 4 means May to Java) + end_date_dt = datetime.now(central).replace(minute=0, second=0, microsecond=0) + start_date_dt = end_date_dt - timedelta(days=5) + #start_date_dt = end_date_dt - timedelta(days=5, hours=7) + + start_date = start_date_dt.astimezone(timezone.utc) + end_date = end_date_dt.astimezone(timezone.utc) + + # Dates can be adjusted using normal datetime arithmetic/replace, e.g.: + # start_date_dt = start_date_dt.replace(day=1) # start of month + # start_date_dt = start_date_dt.replace(hour=1) # 0100 local time + # start_date_dt = start_date_dt.replace(year=2020, month=5) # month is 1-indexed here officeID = "SWT" @@ -99,7 +92,7 @@ def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): # projectId # startDate # endDate - # gateCalc.computeFlowGroup("SWF", "LEWT2", startCal.getTime(), endCal.getTime(), "Flow.LEWT2.ConduitGate_Total") + # gateCalc.computeFlowGroup("SWF", "LEWT2", start_date, end_date, "Flow.LEWT2.ConduitGate_Total") # @@ -107,9 +100,9 @@ def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): # #KEYS - gateCalc.computeFlowGroup("SWT", "KEYS", startCal.getTime(), endCal.getTime(), "Flow.KEYS.Project_Total") - gateCalc.computeFlowGroup("SWT", "KEYS", startCal.getTime(), endCal.getTime(), "Flow.KEYS.Turbine_Total") - gateCalc.computeFlowGroup("SWT", "KEYS", startCal.getTime(), endCal.getTime(), "Flow.KEYS.Gated_Total") + gateCalc.computeFlowGroup("SWT", "KEYS", start_date, end_date, "Flow.KEYS.Project_Total") + gateCalc.computeFlowGroup("SWT", "KEYS", start_date, end_date, "Flow.KEYS.Turbine_Total") + gateCalc.computeFlowGroup("SWT", "KEYS", start_date, end_date, "Flow.KEYS.Gated_Total") diff --git a/district-scripts/SWT/GateFlowHUDS-WS.py b/district-scripts/SWT/GateFlowHUDS-WS.py index 4332238..4280dbe 100644 --- a/district-scripts/SWT/GateFlowHUDS-WS.py +++ b/district-scripts/SWT/GateFlowHUDS-WS.py @@ -2,30 +2,32 @@ def run_calculations(registry): + from datetime import datetime, timedelta, timezone + from zoneinfo import ZoneInfo + # Java imports must happen after regi_session starts the JVM. - from java.util import Calendar - from java.util import TimeZone from usace.rowcps.headless import LoggingOptions - def compute_All_Flowgroups(officeID, location, startCal, endCal): + + def compute_All_Flowgroups(officeID, location, start_date, end_date): # Takes in locations defined by user in group and computes all flow groups try: - gateCalc.computeAll(officeID, location, startCal.getTime(), endCal.getTime()) + gateCalc.computeAll(officeID, location, start_date, end_date) except Exception as e: print("Error Computing all Flow Groups at {0} {1}".format(officeID, location)) print(e) print('') - def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): + def compute_Single_Flowgroup(officeID, location, start_date, end_date, flowGroup): try: - gateCalc.computeFlowGroup(officeID, location, startCal.getTime(), endCal.getTime(), "Flow.{0}.{1}".format(location, flowGroup)) + gateCalc.computeFlowGroup(officeID, location, start_date, end_date, "Flow.{0}.{1}".format(location, flowGroup)) except Exception as e: print("Error Computing Flow Group {0} at {1}".format(officeID, location)) print(e) print('') - # #gateCalc.computeFlowGroup("SWF", "ACTT2", startCal.getTime(), endCal.getTime(), "Flow.ACTT2.Pump_Out_Total") + # #gateCalc.computeFlowGroup("SWF", "ACTT2", start_date, end_date, "Flow.ACTT2.Pump_Out_Total") # Description of: LoggingOptions.setDbMessageLevel(int level) # # Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended @@ -65,33 +67,24 @@ def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): # this retrieves a Gate Flow calculation object gateCalc = registry.getCalculation(1.0, "Gate Flow") - # Time zone must be set because the Solaris time zone is UTC - timeZone = TimeZone.getTimeZone("US/Central") + # Time zone must be set explicitly because the JVM's default timezone is + # UTC, not the district's local time. + central = ZoneInfo("America/Chicago") - # Defaults to start of the day 5 days ago, and ends at the top of the current hour today - # configure the start calendar - startCal = Calendar.getInstance(timeZone) - startCal.add(Calendar.DAY_OF_MONTH, -5) - startCal.add(Calendar.HOUR, -7) + # Defaults to start of the day 5 days and 7 hours ago, and ends at the top + # of the current hour today + end_date_dt = datetime.now(central).replace(minute=0, second=0, microsecond=0) + start_date_dt = end_date_dt - timedelta(days=5, hours=7) #remove or comment out the next line when done!! it was for a big backload ajm - #startCal.add(Calendar.MONTH, -5) - startCal.set(Calendar.MINUTE, 0) - startCal.set(Calendar.SECOND, 0) - startCal.set(Calendar.MILLISECOND, 0) - + #start_date_dt = start_date_dt - timedelta(days=152) # ~5 months - # configure the end calendar - endCal = Calendar.getInstance(timeZone) - endCal.set(Calendar.MINUTE, 0) - endCal.set(Calendar.SECOND, 0) - endCal.set(Calendar.MILLISECOND, 0) - #endCal.add(Calendar.MONTH, -3) + start_date = start_date_dt.astimezone(timezone.utc) + end_date = end_date_dt.astimezone(timezone.utc) - # Calendar can be adjusted using the following functions: - # startCal.set(Calendar.DATE, 1) # Sets the date of the calendar. - # startCal.set(Calendar.HOUR_OF_DAY, 1) # Sets the hour of the day to 0100 (1-24) - # startCal.set(Calendar.YEAR, 2020) # Sets the year - # startCal.set(Calendar.MONTH, 4) # Sets the month (month 4 means May to Java) + # Dates can be adjusted using normal datetime arithmetic/replace, e.g.: + # start_date_dt = start_date_dt.replace(day=1) # start of month + # start_date_dt = start_date_dt.replace(hour=1) # 0100 local time + # start_date_dt = start_date_dt.replace(year=2020, month=5) # month is 1-indexed here officeID = "SWT" @@ -101,11 +94,11 @@ def compute_Single_Flowgroup(officeID, location, startCal, endCal, flowGroup): # projectId # startDate # endDate - # gateCalc.computeFlowGroup("SWF", "LEWT2", startCal.getTime(), endCal.getTime(), "Flow.LEWT2.ConduitGate_Total") + # gateCalc.computeFlowGroup("SWF", "LEWT2", start_date, end_date, "Flow.LEWT2.ConduitGate_Total") #HUDS - gateCalc.computeFlowGroup("SWT", "HUDS", startCal.getTime(), endCal.getTime(), "Flow.HUDS.Pump_Out_Total") - gateCalc.computeFlowGroup("SWT", "HUDS", startCal.getTime(), endCal.getTime(), "Flow.HUDS.Pump_In_Total") + gateCalc.computeFlowGroup("SWT", "HUDS", start_date, end_date, "Flow.HUDS.Pump_Out_Total") + gateCalc.computeFlowGroup("SWT", "HUDS", start_date, end_date, "Flow.HUDS.Pump_In_Total") diff --git a/district-scripts/SWT/WaterSupplyFlowGroup.py b/district-scripts/SWT/WaterSupplyFlowGroup.py index 8a7bb02..5fced69 100644 --- a/district-scripts/SWT/WaterSupplyFlowGroup.py +++ b/district-scripts/SWT/WaterSupplyFlowGroup.py @@ -2,10 +2,13 @@ def run_calculations(registry): + from datetime import datetime, timedelta, timezone + from zoneinfo import ZoneInfo + # Java imports must happen after regi_session starts the JVM. - from java.util import Calendar from usace.rowcps.headless import LoggingOptions + # Description of: LoggingOptions.setDbMessageLevel(int level) # # Adds Time Series logging messages in the OracleTimeSeriesDaoImpl. Recommended @@ -45,41 +48,35 @@ def run_calculations(registry): # this retrieves a Gate Flow calculation object gateCalc = registry.getCalculation(1.0, "Gate Flow") - # the gate flow calculations requires a start and end time. - # here we create a java Calendar object that will be used to create the start Date + # Time zone must be set explicitly because the JVM's default timezone is + # UTC, not the district's local time. (The previous Calendar.getInstance() + # calls here had no explicit timezone and silently depended on whatever + # timezone the host happened to be configured with.) # # use the current date minus 5 days. # - startCal = Calendar.getInstance() - #startCal.clear() - #startCal.set(Calendar.YEAR, 2016) - #startCal.set(Calendar.MONTH, 8) - startCal.add(Calendar.DAY_OF_MONTH, -5) - #startCal.set(Calendar.HOUR, 0) - #startCal.add(Calendar.HOUR, -4) - startCal.set(Calendar.MINUTE, 0) - startCal.set(Calendar.SECOND, 0) - startCal.set(Calendar.MILLISECOND, 0) - - print("this is the place to write the startCal!") - print(startCal.getTime().toString()) - - # create a java Calendar object that will be used to create the end Date + central = ZoneInfo("America/Chicago") + end_date_dt = datetime.now(central).replace(minute=0, second=0, microsecond=0) + #end_date_dt = end_date_dt.replace(year=2016, month=9) # month is 1-indexed here + start_date_dt = end_date_dt - timedelta(days=5) + #start_date_dt = start_date_dt.replace(hour=0) + #start_date_dt = start_date_dt - timedelta(hours=4) + + start_date = start_date_dt.astimezone(timezone.utc) + + print("this is the place to write the start_date!") + print(start_date.isoformat()) + # use the current date. # - endCal = Calendar.getInstance() #remove the next line when the headless time options are fixed - #endCal.add(Calendar.DAY_OF_MONTH, 1) - #endCal.set(Calendar.HOUR, 16) - #endCal.set(Calendar.YEAR, 2018) - #endCal.set(Calendar.MONTH, 6) - #endCal.set(Calendar.DAY_OF_MONTH, 6) - endCal.set(Calendar.MINUTE, 0) - endCal.set(Calendar.SECOND, 0) - endCal.set(Calendar.MILLISECOND, 0) - - print("this is the place to write the endCal!") - print(endCal.getTime().toString()) + #end_date_dt = end_date_dt + timedelta(days=1) + #end_date_dt = end_date_dt.replace(hour=16, year=2018, month=7, day=6) + + end_date = end_date_dt.astimezone(timezone.utc) + + print("this is the place to write the end_date!") + print(end_date.isoformat()) # the gateCalc object can perform its calculation for a single flow group # the computeFlowGroup method takes: @@ -95,43 +92,43 @@ def run_calculations(registry): #ARBU - gateCalc.computeFlowGroup("SWT", "ARBU", startCal.getTime(), endCal.getTime(), "Flow.ARBU.Pump_Out_Total") + gateCalc.computeFlowGroup("SWT", "ARBU", start_date, end_date, "Flow.ARBU.Pump_Out_Total") #ARCA - gateCalc.computeFlowGroup("SWT", "ARCA", startCal.getTime(), endCal.getTime(), "Flow.ARCA.Pump_Out_Total") + gateCalc.computeFlowGroup("SWT", "ARCA", start_date, end_date, "Flow.ARCA.Pump_Out_Total") #CHEN - gateCalc.computeFlowGroup("SWT", "CHEN", startCal.getTime(), endCal.getTime(), "Flow.CHEN.Pump_Out_Total") + gateCalc.computeFlowGroup("SWT", "CHEN", start_date, end_date, "Flow.CHEN.Pump_Out_Total") #ELDR - gateCalc.computeFlowGroup("SWT", "ELDR", startCal.getTime(), endCal.getTime(), "Flow.ELDR.Pump_Out_Total") + gateCalc.computeFlowGroup("SWT", "ELDR", start_date, end_date, "Flow.ELDR.Pump_Out_Total") #FCOB - gateCalc.computeFlowGroup("SWT", "FCOB", startCal.getTime(), endCal.getTime(), "Flow.FCOB.Pump_Out_Total") + gateCalc.computeFlowGroup("SWT", "FCOB", start_date, end_date, "Flow.FCOB.Pump_Out_Total") #FOSS - gateCalc.computeFlowGroup("SWT", "FOSS", startCal.getTime(), endCal.getTime(), "Flow.FOSS.Pump_Out_Total") + gateCalc.computeFlowGroup("SWT", "FOSS", start_date, end_date, "Flow.FOSS.Pump_Out_Total") #MCGE - gateCalc.computeFlowGroup("SWT", "MCGE", startCal.getTime(), endCal.getTime(), "Flow.MCGE.Pump_Out_Total") + gateCalc.computeFlowGroup("SWT", "MCGE", start_date, end_date, "Flow.MCGE.Pump_Out_Total") #MERE - gateCalc.computeFlowGroup("SWT", "MERE", startCal.getTime(), endCal.getTime(), "Flow.MERE.Pump_Out_Total") + gateCalc.computeFlowGroup("SWT", "MERE", start_date, end_date, "Flow.MERE.Pump_Out_Total") #OOLO - gateCalc.computeFlowGroup("SWT", "OOLO", startCal.getTime(), endCal.getTime(), "Flow.OOLO.Pump_Out_Total") + gateCalc.computeFlowGroup("SWT", "OOLO", start_date, end_date, "Flow.OOLO.Pump_Out_Total") #PATM - gateCalc.computeFlowGroup("SWT", "PATM", startCal.getTime(), endCal.getTime(), "Flow.PATM.Pump_Out_Total") + gateCalc.computeFlowGroup("SWT", "PATM", start_date, end_date, "Flow.PATM.Pump_Out_Total") #THUN - gateCalc.computeFlowGroup("SWT", "THUN", startCal.getTime(), endCal.getTime(), "Flow.THUN.Pump_Out_Total") + gateCalc.computeFlowGroup("SWT", "THUN", start_date, end_date, "Flow.THUN.Pump_Out_Total") #TOMS - gateCalc.computeFlowGroup("SWT", "TOMS", startCal.getTime(), endCal.getTime(), "Flow.TOMS.Pump_Out_Total") + gateCalc.computeFlowGroup("SWT", "TOMS", start_date, end_date, "Flow.TOMS.Pump_Out_Total") #WAUR - gateCalc.computeFlowGroup("SWT", "WAUR", startCal.getTime(), endCal.getTime(), "Flow.WAUR.Pump_Out_Total") + gateCalc.computeFlowGroup("SWT", "WAUR", start_date, end_date, "Flow.WAUR.Pump_Out_Total") diff --git a/docs/JYTHON_TO_JPYPE_MIGRATION.md b/docs/JYTHON_TO_JPYPE_MIGRATION.md index a291407..d7a36d7 100644 --- a/docs/JYTHON_TO_JPYPE_MIGRATION.md +++ b/docs/JYTHON_TO_JPYPE_MIGRATION.md @@ -48,14 +48,15 @@ from regi_python import regi_session, run_headless def run_calculations(registry): - from java.util import Calendar - from java.util import TimeZone + from datetime import datetime, timezone + from zoneinfo import ZoneInfo gateCalc = registry.getCalculation(1.0, "Gate Flow") - timeZone = TimeZone.getTimeZone("US/Central") - startCal = Calendar.getInstance(timeZone) - endCal = Calendar.getInstance(timeZone) - gateCalc.computeFlowGroup("SWT", "FOSS", startCal.getTime(), endCal.getTime(), "Flow.FOSS.Project_Total") + + central = ZoneInfo("America/Chicago") + start_date = datetime(2015, 5, 1, tzinfo=central).astimezone(timezone.utc) + end_date = datetime(2015, 7, 1, tzinfo=central).astimezone(timezone.utc) + gateCalc.computeFlowGroup("SWT", "FOSS", start_date, end_date, "Flow.FOSS.Project_Total") if __name__ == "__main__": @@ -63,6 +64,10 @@ if __name__ == "__main__": run_headless(run_calculations) ``` +Note that this example no longer imports anything from `java.util` at all. Date/time +values are built entirely in Python and only cross into Java as plain `datetime` +objects — see [Date and Time Handling](#date-and-time-handling) below. + ## Translation Rules ### 1. Move Java imports inside the callback @@ -115,6 +120,102 @@ if __name__ == "__main__": run_headless(run_calculations) ``` +### 7. Replace `java.util.Calendar`/`TimeZone` with `datetime`/`zoneinfo` + +Old scripts built `java.util.Date` objects with `Calendar.getInstance(TimeZone.getTimeZone(...))`. +New scripts should build ordinary Python `datetime` objects with `zoneinfo.ZoneInfo` instead, +and pass them straight into the Java call. See +[Date and Time Handling](#date-and-time-handling) for the full pattern and the one +timezone rule you must not skip. + +## Date and Time Handling + +The Scriptable calculation APIs (`ScriptableInflow`, `ScriptableGateSettings`, +`ScriptableGateFlowCalc`) accept `java.time.Instant` parameters for start/end dates. +(The old `java.util.Date`/`long` overloads still exist but are `@Deprecated` — +prefer `Instant`.) JPype automatically converts a plain Python `datetime.datetime` +into a Java `Instant` when the target parameter is declared as `Instant`, so **you +do not need to construct any Java object yourself**. Build the date in Python and +pass it directly: + +```python +from datetime import datetime, timezone +from zoneinfo import ZoneInfo + +central = ZoneInfo("America/Chicago") +start_date = datetime(2018, 8, 1, tzinfo=central).astimezone(timezone.utc) +``` + +### The one rule: always convert to UTC before calling into Java + +JPype's automatic `datetime -> Instant` conversion does **not** look at the +`tzinfo` on the value you pass — it takes whatever wall-clock fields the datetime +has and treats them as if they were already UTC. If you hand it a +timezone-aware-but-not-UTC datetime directly, you will get the wrong instant with +no error or warning: + +```python +central = ZoneInfo("America/Chicago") +midnight_central = datetime(2015, 5, 1, tzinfo=central) # 2015-05-01 00:00 CDT == 2015-05-01 05:00 UTC + +gateCalc.computeAll("SWF", "LEWT2", midnight_central, end_date) # WRONG: silently treated as 00:00 UTC, 5 hours off +``` + +Always call `.astimezone(timezone.utc)` on the value before it crosses into a +Java call, as shown in every example in this document. Once a datetime's wall +clock actually represents UTC, JPype's conversion is exact and this is the only +step required — no epoch-millis math, no manual `Instant` construction. + +This is also why the timezone must always be given explicitly with +`zoneinfo.ZoneInfo("America/Chicago")` (or whatever the district's local zone +is) rather than left off. The JVM's own default timezone is UTC, not the +district's local time — a naive `datetime.now()` or a `datetime` built without +`tzinfo` has no way to know it should mean "Central time," and some +scripts that called `Calendar.getInstance()` with no `TimeZone` argument were +silently relying on whatever timezone the host machine happened to have +configured. Always pass `tzinfo=` explicitly when constructing the date. + +### Building relative dates ("N days ago", "top of the hour", etc.) + +Most district scripts compute a date relative to "now" rather than a fixed date. +Use `datetime.now(tz)` plus `timedelta` arithmetic, then `.replace(...)` to zero +out whichever fields need truncating — this mirrors what `Calendar.add()` / +`Calendar.set()` used to do, and is safe across DST transitions the same way: + +```python +from datetime import datetime, timedelta, timezone +from zoneinfo import ZoneInfo + +central = ZoneInfo("America/Chicago") + +# "5 days ago at midnight" through "tomorrow at midnight" +today_midnight = datetime.now(central).replace(hour=0, minute=0, second=0, microsecond=0) +start_date = (today_midnight - timedelta(days=5)).astimezone(timezone.utc) +end_date = (today_midnight + timedelta(days=1)).astimezone(timezone.utc) + +# "5 days ago at the top of the current hour" through "the top of the current hour" +end_date_dt = datetime.now(central).replace(minute=0, second=0, microsecond=0) +start_date_dt = end_date_dt - timedelta(days=5) +start_date = start_date_dt.astimezone(timezone.utc) +end_date = end_date_dt.astimezone(timezone.utc) +``` + +A couple of translation notes when porting the old `Calendar` field calls: + +| Old `Calendar` code | `datetime` equivalent | +| --- | --- | +| `cal.add(Calendar.DAY_OF_MONTH, -5)` | `dt - timedelta(days=5)` | +| `cal.set(Calendar.HOUR_OF_DAY, 0)` + `MINUTE`/`SECOND`/`MILLISECOND` to `0` | `dt.replace(hour=0, minute=0, second=0, microsecond=0)` | +| `cal.set(Calendar.MONTH, 4)` | `dt.replace(month=5)` — **`Calendar.MONTH` is 0-indexed** (4 == May); `datetime.month` is 1-indexed, so add 1 when porting a literal month value | +| `cal.set(Calendar.HOUR, 0)` | Avoid porting this one directly — `Calendar.HOUR` is the 12-hour field and doesn't reliably mean midnight (it depends on the AM/PM already set on the calendar). Use `hour=0` on the `datetime`, which unambiguously means midnight. | + +### Using the `long` epoch-millis overloads + +`ScriptableGateFlowCalc.computeAll`/`computeFlowGroup` also has `long` (epoch +milliseconds) overloads. These remain valid but are deprecated in favor of +`Instant`; if you do need a raw millisecond value, get it from an +already-UTC-normalized datetime: `int(start_date.timestamp() * 1000)`. + ## Project-Specific Examples The current district scripts show the same migration shape across several script families: diff --git a/regi-headless/src/main/java/usace/rowcps/headless/calculator/flowgroup/ScriptableGateFlowCalc.java b/regi-headless/src/main/java/usace/rowcps/headless/calculator/flowgroup/ScriptableGateFlowCalc.java index 7d3d0a9..a8e53bf 100644 --- a/regi-headless/src/main/java/usace/rowcps/headless/calculator/flowgroup/ScriptableGateFlowCalc.java +++ b/regi-headless/src/main/java/usace/rowcps/headless/calculator/flowgroup/ScriptableGateFlowCalc.java @@ -1,5 +1,6 @@ package usace.rowcps.headless.calculator.flowgroup; +import java.time.Instant; import java.util.Date; /** @@ -9,16 +10,55 @@ public interface ScriptableGateFlowCalc { + /** + * @deprecated Use {@link #computeAll(String, String, Instant, Instant)} instead. java.util.Date + * requires callers to build a java.util.Calendar with an explicit TimeZone to avoid relying on + * the JVM's default timezone; Instant is an unambiguous point in time. + */ + @Deprecated void computeAll(String officeId, String locationId, Date start, Date end); + /** + * @deprecated Use {@link #computeAll(String, String, Instant, Instant)} instead. A bare epoch-millis + * long has no explicit unit/type safety in scripts; Instant is self-documenting. + */ + @Deprecated void computeAll(String officeId, String locationId, long startTime, long endTime); + void computeAll(String officeId, String locationId, Instant start, Instant end); + /** + * @deprecated Use {@link #computeAll(String, String[], Instant, Instant)} instead. + */ + @Deprecated void computeAll(String officeId, String[] locationIds, Date start, Date end); + /** + * @deprecated Use {@link #computeAll(String, String[], Instant, Instant)} instead. + */ + @Deprecated void computeAll(String officeId, String[] locationIds, long startTime, long endTime); + void computeAll(String officeId, String[] locationIds, Instant start, Instant end); + /** + * @deprecated Use {@link #computeFlowGroup(String, String, Instant, Instant, String)} instead. + */ + @Deprecated void computeFlowGroup(String officeId, String locationId, Date start, Date end, String groupId); + /** + * @deprecated Use {@link #computeFlowGroup(String, String, Instant, Instant, String)} instead. + */ + @Deprecated void computeFlowGroup(String officeId, String locationId, long startTime, long endTime, String groupId); + void computeFlowGroup(String officeId, String locationId, Instant start, Instant end, String groupId); + /** + * @deprecated Use {@link #computeFlowGroup(String, String[], Instant, Instant, String)} instead. + */ + @Deprecated void computeFlowGroup(String officeId, String[] locationIds, Date start, Date end, String groupId); + /** + * @deprecated Use {@link #computeFlowGroup(String, String[], Instant, Instant, String)} instead. + */ + @Deprecated void computeFlowGroup(String officeId, String[] locationIds, long startTime, long endTime, String groupId); + void computeFlowGroup(String officeId, String[] locationIds, Instant start, Instant end, String groupId); } diff --git a/regi-headless/src/main/java/usace/rowcps/headless/calculator/flowgroup/ScriptableGateFlowImpl.java b/regi-headless/src/main/java/usace/rowcps/headless/calculator/flowgroup/ScriptableGateFlowImpl.java index f50932f..a5001f2 100644 --- a/regi-headless/src/main/java/usace/rowcps/headless/calculator/flowgroup/ScriptableGateFlowImpl.java +++ b/regi-headless/src/main/java/usace/rowcps/headless/calculator/flowgroup/ScriptableGateFlowImpl.java @@ -5,6 +5,7 @@ import hec.data.project.IProject; import hec.db.DbConnectionException; import hec.db.DbIoException; +import java.time.Instant; import java.util.Calendar; import java.util.Date; import java.util.Map; @@ -44,6 +45,13 @@ public void computeAll(String officeId, String locationId, Date start, Date end) } + @Override + public void computeAll(String officeId, String locationId, Instant start, Instant end) { + + computeAll(officeId, locationId, start.toEpochMilli(), end.toEpochMilli()); + + } + @Override public void computeAll(String officeId, String locationId, long startTime, long endTime) { @@ -88,6 +96,13 @@ public void computeAll(String officeId, String[] locationIds, Date start, Date e } } + @Override + public void computeAll(String officeId, String[] locationIds, Instant start, Instant end) { + for (String locationId : locationIds) { + computeAll(officeId, locationId, start, end); + } + } + @Override public void computeAll(String officeId, String[] locationIds, long startTime, long endTime) { for (String locationId : locationIds) { @@ -102,6 +117,11 @@ public void computeFlowGroup(String officeId, String locationId, Date start, Dat computeFlowGroup(officeId, locationId, startTime, endTime, groupId); } + @Override + public void computeFlowGroup(String officeId, String locationId, Instant start, Instant end, String groupId) { + computeFlowGroup(officeId, locationId, start.toEpochMilli(), end.toEpochMilli(), groupId); + } + @Override public void computeFlowGroup(String officeId, String locationId, long startTime, long endTime, String groupId) { @@ -150,6 +170,15 @@ public void computeFlowGroup(String officeId, String[] locationIds, Date start, } } + @Override + public void computeFlowGroup(String officeId, String[] locationIds, Instant start, Instant end, String groupId) { + long startTime = start.toEpochMilli(); + long endTime = end.toEpochMilli(); + for (String locationId : locationIds) { + computeFlowGroup(officeId, locationId, startTime, endTime, groupId); + } + } + @Override public void computeFlowGroup(String officeId, String[] locationIds, long startTime, long endTime, String groupId) { for (String locationId : locationIds) { diff --git a/regi-headless/src/main/java/usace/rowcps/headless/calculator/gatesettings/ScriptableGateSettings.java b/regi-headless/src/main/java/usace/rowcps/headless/calculator/gatesettings/ScriptableGateSettings.java index d8ec218..dab3685 100644 --- a/regi-headless/src/main/java/usace/rowcps/headless/calculator/gatesettings/ScriptableGateSettings.java +++ b/regi-headless/src/main/java/usace/rowcps/headless/calculator/gatesettings/ScriptableGateSettings.java @@ -1,5 +1,6 @@ package usace.rowcps.headless.calculator.gatesettings; +import java.time.Instant; import java.util.Date; /** @@ -8,8 +9,33 @@ */ interface ScriptableGateSettings { + /** + * @deprecated Use {@link #createGateSettings(String, String, Instant, Instant)} instead. java.util.Date + * requires callers to build a java.util.Calendar with an explicit TimeZone to avoid relying on the JVM's + * default timezone; Instant is an unambiguous point in time. + */ + @Deprecated void createGateSettings(String officeId, String locationStr, Date startDate, Date end) throws Exception; + void createGateSettings(String officeId, String locationStr, Instant startDate, Instant end) throws Exception; + + /** + * @deprecated Use {@link #createGateSettingsGroup(String, String, Instant, Instant, String)} instead. + */ + @Deprecated void createGateSettingsGroup(String officeId, String locationStr, Date startDate, Date end, String groupId) throws Exception; + void createGateSettingsGroup(String officeId, String locationStr, Instant startDate, Instant end, String groupId) throws Exception; + + /** + * @deprecated Use {@link #createGateSettingsOutlet(String, String, Instant, Instant, String)} instead. + */ + @Deprecated void createGateSettingsOutlet(String officeId, String locationStr, Date startDate, Date end, String outletId) throws Exception; + void createGateSettingsOutlet(String officeId, String locationStr, Instant startDate, Instant end, String outletId) throws Exception; + + /** + * @deprecated Use {@link #createGateSettingsOutletFromTs(String, String, Instant, Instant, String, String)} instead. + */ + @Deprecated void createGateSettingsOutletFromTs(String officeId, String locationStr, Date startDate, Date end, String outletId, String tsId) throws Exception; + void createGateSettingsOutletFromTs(String officeId, String locationStr, Instant startDate, Instant end, String outletId, String tsId) throws Exception; } diff --git a/regi-headless/src/main/java/usace/rowcps/headless/calculator/gatesettings/ScriptableGateSettingsImpl.java b/regi-headless/src/main/java/usace/rowcps/headless/calculator/gatesettings/ScriptableGateSettingsImpl.java index 3c2bffd..f5b7863 100644 --- a/regi-headless/src/main/java/usace/rowcps/headless/calculator/gatesettings/ScriptableGateSettingsImpl.java +++ b/regi-headless/src/main/java/usace/rowcps/headless/calculator/gatesettings/ScriptableGateSettingsImpl.java @@ -37,6 +37,7 @@ import java.text.MessageFormat; import java.text.NumberFormat; import java.text.SimpleDateFormat; +import java.time.Instant; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -109,6 +110,12 @@ public ScriptableGateSettingsImpl(RegiDomain regiDomain, ManagerId managerId) { super(regiDomain, managerId); } + @Override + public void createGateSettings(String officeId, String locationStr, Instant startDate, Instant end) throws Exception + { + createGateSettings(officeId, locationStr, Date.from(startDate), Date.from(end)); + } + @Override public void createGateSettings(String officeId, String locationStr, Date startDate, Date end) throws Exception { @@ -141,6 +148,12 @@ public void createGateSettings(String officeId, String locationStr, Date startDa gc.saveData(options); } + @Override + public void createGateSettingsOutlet(String officeId, String locationStr, Instant startDate, Instant end, String outletId) throws Exception + { + createGateSettingsOutlet(officeId, locationStr, Date.from(startDate), Date.from(end), outletId); + } + @Override public void createGateSettingsOutlet(String officeId, String locationStr, Date startDate, Date end, String outletId) throws Exception { @@ -185,6 +198,13 @@ public void createGateSettingsOutlet(String officeId, String locationStr, Date s gc.saveData(options); } + @Override + public void createGateSettingsOutletFromTs(String officeId, String locationStr, Instant startDate, Instant end, String outletId, String tsId) + throws Exception + { + createGateSettingsOutletFromTs(officeId, locationStr, Date.from(startDate), Date.from(end), outletId, tsId); + } + @Override public void createGateSettingsOutletFromTs(String officeId, String locationStr, Date startDate, Date end, String outletId, String tsId) throws Exception @@ -223,6 +243,12 @@ public IControlledOutlet getIControlledOutlet(GateCache gc, String outletId) { return retval; } + @Override + public void createGateSettingsGroup(String officeId, String locationStr, Instant startDate, Instant end, String groupId) throws Exception + { + createGateSettingsGroup(officeId, locationStr, Date.from(startDate), Date.from(end), groupId); + } + @Override public void createGateSettingsGroup(String officeId, String locationStr, Date startDate, Date end, String groupId) throws Exception { diff --git a/regi-headless/src/main/java/usace/rowcps/headless/calculator/inflow/ScriptableInflow.java b/regi-headless/src/main/java/usace/rowcps/headless/calculator/inflow/ScriptableInflow.java index d85f0b9..7c28488 100644 --- a/regi-headless/src/main/java/usace/rowcps/headless/calculator/inflow/ScriptableInflow.java +++ b/regi-headless/src/main/java/usace/rowcps/headless/calculator/inflow/ScriptableInflow.java @@ -1,5 +1,6 @@ package usace.rowcps.headless.calculator.inflow; +import java.time.Instant; import java.util.Date; /** @@ -9,19 +10,63 @@ public interface ScriptableInflow { + /** + * @deprecated Use {@link #autoAdjust(String, String, Instant)} instead. java.util.Date + * requires callers to build a java.util.Calendar with an explicit TimeZone to avoid + * relying on the JVM's default timezone; Instant is an unambiguous point in time. + */ + @Deprecated void autoAdjust(String officeId, String locationStr, Date startDate); + void autoAdjust(String officeId, String locationStr, Instant startDate); + + /** + * @deprecated Use {@link #autoAdjust(String, String, Instant, boolean, boolean)} instead. + */ + @Deprecated void autoAdjust(String officeId, String locationStr, Date startDate, boolean useLimits, boolean freezeRain); + void autoAdjust(String officeId, String locationStr, Instant startDate, boolean useLimits, boolean freezeRain); + + /** + * @deprecated Use {@link #cloneInflows(String, String, Instant)} instead. + */ + @Deprecated void cloneInflows(String officeId, String locationStr, Date startDate); + void cloneInflows(String officeId, String locationStr, Instant startDate); + + /** + * @deprecated Use {@link #zeroNegatives(String, String, Instant)} instead. + */ + @Deprecated void zeroNegatives(String officeId, String locationStr, Date startDate); + void zeroNegatives(String officeId, String locationStr, Instant startDate); + + /** + * @deprecated Use {@link #balanceAll(String, String, Instant)} instead. + */ + @Deprecated void balanceAll(String officeId, String locationStr, Date startDate); + void balanceAll(String officeId, String locationStr, Instant startDate); + + /** + * @deprecated Use {@link #computeInflow(String, String, Instant, Instant)} instead. + */ + @Deprecated void computeInflow(String officeId, String locationStr, Date startDate, Date endDate); + void computeInflow(String officeId, String locationStr, Instant startDate, Instant endDate); + + /** + * @deprecated Use {@link #computeEvapAsFlow(String, String, Instant, Instant)} instead. + */ + @Deprecated void computeEvapAsFlow(String officeId, String locationStr, Date startDate, Date endDate); + void computeEvapAsFlow(String officeId, String locationStr, Instant startDate, Instant endDate); + void setComputationStorageOptions(InflowComputationStorageOption option, InflowComputationStorageOption... options); } diff --git a/regi-headless/src/main/java/usace/rowcps/headless/calculator/inflow/ScriptableInflowImpl.java b/regi-headless/src/main/java/usace/rowcps/headless/calculator/inflow/ScriptableInflowImpl.java index b680a5c..bd10556 100644 --- a/regi-headless/src/main/java/usace/rowcps/headless/calculator/inflow/ScriptableInflowImpl.java +++ b/regi-headless/src/main/java/usace/rowcps/headless/calculator/inflow/ScriptableInflowImpl.java @@ -6,6 +6,7 @@ import hec.db.DbConnectionException; import hec.db.DbException; import hec.db.DbIoException; +import java.time.Instant; import java.util.Calendar; import java.util.Date; import java.util.HashMap; @@ -63,6 +64,18 @@ public void autoAdjust(String officeId, String locationStr, Date startDate) autoAdjust(officeId, locationStr, startDate, false, false); } + @Override + public void autoAdjust(String officeId, String locationStr, Instant startDate) + { + autoAdjust(officeId, locationStr, Date.from(startDate), false, false); + } + + @Override + public void autoAdjust(String officeId, String locationStr, Instant startDate, boolean useLimits, boolean freezeRain) + { + autoAdjust(officeId, locationStr, Date.from(startDate), useLimits, freezeRain); + } + @Override public void autoAdjust(String officeId, String locationStr, Date startDate, boolean useLimits, boolean freezeRain) { @@ -111,6 +124,12 @@ public void autoAdjust(String officeId, String locationStr, Date startDate, bool } } + @Override + public void cloneInflows(String officeId, String locationStr, Instant startDate) + { + cloneInflows(officeId, locationStr, Date.from(startDate)); + } + @Override public void cloneInflows(String officeId, String locationStr, Date startDate) { @@ -150,6 +169,12 @@ public void cloneInflows(String officeId, String locationStr, Date startDate) } } + @Override + public void zeroNegatives(String officeId, String locationStr, Instant startDate) + { + zeroNegatives(officeId, locationStr, Date.from(startDate)); + } + @Override public void zeroNegatives(String officeId, String locationStr, Date startDate) { @@ -188,6 +213,12 @@ public void zeroNegatives(String officeId, String locationStr, Date startDate) } } + @Override + public void balanceAll(String officeId, String locationStr, Instant startDate) + { + balanceAll(officeId, locationStr, Date.from(startDate)); + } + @Override public void balanceAll(String officeId, String locationStr, Date startDate) { @@ -323,6 +354,12 @@ private InflowAdjustedTypeModel getOrCreateStatusMap(LocationTemplate template) return retval; } + @Override + public void computeEvapAsFlow(String officeId, String locationStr, Instant startDate, Instant endDate) + { + computeEvapAsFlow(officeId, locationStr, Date.from(startDate), Date.from(endDate)); + } + @Override public void computeEvapAsFlow(String officeId, String locationStr, Date startDate, Date endDate) { @@ -355,6 +392,12 @@ public void computeEvapAsFlow(String officeId, String locationStr, Date startDat } } + @Override + public void computeInflow(String officeId, String locationStr, Instant startDate, Instant endDate) + { + computeInflow(officeId, locationStr, Date.from(startDate), Date.from(endDate)); + } + @Override public void computeInflow(String officeId, String locationStr, Date startDate, Date endDate) { diff --git a/regi-headless/src/test/python/test_datetime_instant_conversion.py b/regi-headless/src/test/python/test_datetime_instant_conversion.py new file mode 100644 index 0000000..73829f5 --- /dev/null +++ b/regi-headless/src/test/python/test_datetime_instant_conversion.py @@ -0,0 +1,90 @@ +""" +Verifies JPype's automatic conversion of a plain Python `datetime.datetime` +into a `java.time.Instant`, and locks in the exact timezone behavior documented +in docs/JYTHON_TO_JPYPE_MIGRATION.md ("Date and Time Handling"). + +These tests start a real JVM through jpype instead of faking `java.time`, +because the point is to verify jpype's own conversion behavior rather than +our code. They only touch `java.time.Instant`, which ships in every JDK/JRE, +so no project jars or Gradle build are required -- just a JVM that jpype can +locate. If none is available, the module is skipped rather than failed. +""" + +from datetime import datetime, timezone + +import pytest + +jpype = pytest.importorskip("jpype") +pytest.importorskip("jpype.imports") # registers the `from java.x import Y` import hook + + +def _ensure_jvm_started(): + if jpype.isJVMStarted(): + return + try: + jpype.startJVM(jpype.getDefaultJVMPath()) + except Exception as exc: # pragma: no cover - environment dependent + pytest.skip(f"No usable JVM available for jpype: {exc}") + + +@pytest.fixture(scope="module", autouse=True) +def _jvm(): + _ensure_jvm_started() + yield + # Deliberately not shut down: a JVM cannot be restarted once stopped in + # the same process, and other test modules in this pytest run may still + # need one (real or mocked). + + +@pytest.fixture(scope="module") +def Instant(): + from java.time import Instant as JInstant + + return JInstant + + +def test_utc_aware_datetime_converts_to_the_exact_instant(Instant): + """ + A datetime whose wall-clock fields already represent UTC crosses into an + `Instant`-typed parameter exactly. + + `compareTo`'s formal parameter type is declared as exactly `Instant`, + which is what makes jpype's datetime -> Instant converter fire. Methods + declared to accept `Object` (like `equals`) do NOT trigger it. + """ + utc_dt = datetime(2018, 8, 1, 12, 30, 0, tzinfo=timezone.utc) + expected = Instant.parse("2018-08-01T12:30:00Z") + + assert expected.compareTo(utc_dt) == 0 + + +def test_non_utc_aware_datetime_is_silently_misread_as_utc(Instant): + """ + Regression guard for the one rule called out in the migration doc: jpype's + converter does not consult `tzinfo` -- it takes whatever wall-clock fields + the datetime has and stamps them as UTC. A Central-time datetime that is + NOT first normalized with `.astimezone(timezone.utc)` silently produces + the wrong instant, five hours off, with no error or warning. + """ + from zoneinfo import ZoneInfo + + central = ZoneInfo("America/Chicago") + midnight_central = datetime(2015, 5, 1, 0, 0, 0, tzinfo=central) # really 05:00 UTC + + what_jpype_actually_produces = Instant.parse("2015-05-01T00:00:00Z") + what_it_should_have_meant = Instant.parse("2015-05-01T05:00:00Z") + + assert what_jpype_actually_produces.compareTo(midnight_central) == 0 + assert what_it_should_have_meant.compareTo(midnight_central) != 0 + + +def test_astimezone_utc_before_passing_is_the_correct_pattern(Instant): + """The documented fix: always call `.astimezone(timezone.utc)` first.""" + from zoneinfo import ZoneInfo + + central = ZoneInfo("America/Chicago") + midnight_central = datetime(2015, 5, 1, 0, 0, 0, tzinfo=central) + normalized = midnight_central.astimezone(timezone.utc) + + correct_instant = Instant.parse("2015-05-01T05:00:00Z") + assert correct_instant.compareTo(normalized) == 0 diff --git a/regi-headless/src/test/resources/usace/rowcps/headless/examples/GateFlowCalc.py b/regi-headless/src/test/resources/usace/rowcps/headless/examples/GateFlowCalc.py index 8bcbab8..c7c3205 100644 --- a/regi-headless/src/test/resources/usace/rowcps/headless/examples/GateFlowCalc.py +++ b/regi-headless/src/test/resources/usace/rowcps/headless/examples/GateFlowCalc.py @@ -5,9 +5,12 @@ def calculate_gate_flow(registry): + from datetime import datetime, timezone + from zoneinfo import ZoneInfo + # Java imports must happen after regi_session starts the JVM. from java.lang import System - from java.util import Calendar, TimeZone + print("Now executing GateFlowCalc.py") print("os.arch:", System.getProperty("os.arch")) @@ -23,23 +26,19 @@ def calculate_gate_flow(registry): project_id = "LEWT2" flow_group_id = "Flow.LEWT2.ConduitGate_Total" - # Time zone must be set because the Solaris time zone is UTC - time_zone = TimeZone.getTimeZone("US/Central") - start_cal = Calendar.getInstance(time_zone) - start_cal.clear() - start_cal.set(Calendar.YEAR, 2015) - start_cal.set(Calendar.MONTH, 1) - - end_cal = Calendar.getInstance(time_zone) - end_cal.clear() - end_cal.set(Calendar.YEAR, 2013) - end_cal.set(Calendar.MONTH, 1) + # Time zone must be set explicitly because the JVM's default timezone is + # UTC, not the district's local time. + central = ZoneInfo("America/Chicago") + # Java's Calendar.MONTH was 0-indexed (1 == February); datetime.month is + # 1-indexed, so we use 2 here for the same dates. + start_date = (datetime(2015, 2, 1, tzinfo=central)).astimezone(timezone.utc) + end_date = (datetime(2013, 2, 1, tzinfo=central)).astimezone(timezone.utc) gate_calc.computeFlowGroup( office_id, project_id, - start_cal.getTimeInMillis(), - end_cal.getTimeInMillis(), + start_date, + end_date, flow_group_id, ) diff --git a/regi-headless/src/test/resources/usace/rowcps/headless/examples/GateFlowCalc2.py b/regi-headless/src/test/resources/usace/rowcps/headless/examples/GateFlowCalc2.py index 1eca4b1..14fc1ed 100644 --- a/regi-headless/src/test/resources/usace/rowcps/headless/examples/GateFlowCalc2.py +++ b/regi-headless/src/test/resources/usace/rowcps/headless/examples/GateFlowCalc2.py @@ -2,27 +2,24 @@ def calculate_gate_flow(registry): - # Java imports must happen after regi_session starts the JVM. - from java.util import Calendar, TimeZone + from datetime import datetime, timezone + from zoneinfo import ZoneInfo + names = registry.getNames(1.0) print("names", names) gate_calc = registry.getCalculation(1.0, "Gate Flow") - # Time zone must be set because the Solaris time zone is UTC - time_zone = TimeZone.getTimeZone("US/Central") - start_cal = Calendar.getInstance(time_zone) - start_cal.clear() - start_cal.set(Calendar.YEAR, 2015) - start_cal.set(Calendar.MONTH, 4) - - end_cal = Calendar.getInstance(time_zone) - end_cal.clear() - end_cal.set(Calendar.YEAR, 2015) - end_cal.set(Calendar.MONTH, 6) + # Time zone must be set explicitly because the JVM's default timezone is + # UTC, not the district's local time. + central = ZoneInfo("America/Chicago") + # Java's Calendar.MONTH was 0-indexed (4 == May, 6 == July); datetime.month + # is 1-indexed, so we use 5 and 7 here for the same dates. + start_date = (datetime(2015, 5, 1, tzinfo=central)).astimezone(timezone.utc) + end_date = (datetime(2015, 7, 1, tzinfo=central)).astimezone(timezone.utc) - gate_calc.computeAll("SWF", "LEWT2", start_cal.getTimeInMillis(), end_cal.getTimeInMillis()) + gate_calc.computeAll("SWF", "LEWT2", start_date, end_date) if __name__ == "__main__": diff --git a/regi-headless/src/test/resources/usace/rowcps/headless/examples/GateSettings.py b/regi-headless/src/test/resources/usace/rowcps/headless/examples/GateSettings.py index b1d4121..c3a0995 100644 --- a/regi-headless/src/test/resources/usace/rowcps/headless/examples/GateSettings.py +++ b/regi-headless/src/test/resources/usace/rowcps/headless/examples/GateSettings.py @@ -2,43 +2,38 @@ def calculate_gate_settings(registry): - # Java imports must happen after regi_session starts the JVM. - from java.util import Calendar, TimeZone + from datetime import datetime, timezone + from zoneinfo import ZoneInfo + # this gets a scriptable Gate Settings object gate_settings = registry.getCalculation(1.0, "Gate Settings") - # Time zone must be set because the Solaris time zone is UTC - time_zone = TimeZone.getTimeZone("US/Central") - # configure the start calendar - start_cal = Calendar.getInstance(time_zone) - start_cal.clear() - start_cal.set(Calendar.YEAR, 2015) - start_cal.set(Calendar.MONTH, 4) - - # configure the end calendar - end_cal = Calendar.getInstance(time_zone) - end_cal.clear() - end_cal.set(Calendar.YEAR, 2015) - end_cal.set(Calendar.MONTH, 6) + # Time zone must be set explicitly because the JVM's default timezone is + # UTC, not the district's local time. + central = ZoneInfo("America/Chicago") + # Java's Calendar.MONTH was 0-indexed (4 == May, 6 == July); datetime.month + # is 1-indexed, so we use 5 and 7 here for the same dates. + start_date = (datetime(2015, 5, 1, tzinfo=central)).astimezone(timezone.utc) + end_date = (datetime(2015, 7, 1, tzinfo=central)).astimezone(timezone.utc) # gate_settings contains four callable methods - # void createGateSettings(String officeId, String locationStr, Date startDate, Date end) throws Exception; - # void createGateSettingsGroup(String officeId, String locationStr, Date startDate, Date end, String groupId) throws Exception; - # void createGateSettingsOutlet(String officeId, String locationStr, Date startDate, Date end, String outletId) throws Exception; - # void createGateSettingsOutletFromTs(String officeId, String locationStr, Date startDate, Date end, String outletId, String tsId) throws Exception; + # void createGateSettings(String officeId, String locationStr, Instant startDate, Instant end) throws Exception; + # void createGateSettingsGroup(String officeId, String locationStr, Instant startDate, Instant end, String groupId) throws Exception; + # void createGateSettingsOutlet(String officeId, String locationStr, Instant startDate, Instant end, String outletId) throws Exception; + # void createGateSettingsOutletFromTs(String officeId, String locationStr, Instant startDate, Instant end, String outletId, String tsId) throws Exception; # This is an example of a call that would create gate settings at TainterGate 1 at WTYT2 from the specified input time series. - gate_settings.createGateSettingsOutletFromTs("SWF", "WTYT2", start_cal.getTime(), end_cal.getTime(), "TG1", "WTYT2-TG1.Opening-Spillway_Gate.Const.0.0.MANUAL") + gate_settings.createGateSettingsOutletFromTs("SWF", "WTYT2", start_date, end_date, "TG1", "WTYT2-TG1.Opening-Spillway_Gate.Const.0.0.MANUAL") # This is an example of a call that would create gate settings at TainterGate 1 at WTYT2 from the regi association configured input time series. - gate_settings.createGateSettingsOutlet("SWF", "WTYT2", start_cal.getTime(), end_cal.getTime(), "TG1") + gate_settings.createGateSettingsOutlet("SWF", "WTYT2", start_date, end_date, "TG1") # This is an example of a call that would create gate settings at all outlets at WTYT2 which are in the TainterGateWTY group from the association configured time series. - gate_settings.createGateSettingsGroup("SWF", "WTYT2", start_cal.getTime(), end_cal.getTime(), "WTYT2-TainterGateWTY") + gate_settings.createGateSettingsGroup("SWF", "WTYT2", start_date, end_date, "WTYT2-TainterGateWTY") # This is an example of a call that would create gate settings for every outlet in a rating group at WTYT2. - gate_settings.createGateSettings("SWF", "WTYT2", start_cal.getTime(), end_cal.getTime()) + gate_settings.createGateSettings("SWF", "WTYT2", start_date, end_date) if __name__ == "__main__": diff --git a/regi-headless/src/test/resources/usace/rowcps/headless/examples/InflowCalc.py b/regi-headless/src/test/resources/usace/rowcps/headless/examples/InflowCalc.py index 8e4df61..6909d44 100644 --- a/regi-headless/src/test/resources/usace/rowcps/headless/examples/InflowCalc.py +++ b/regi-headless/src/test/resources/usace/rowcps/headless/examples/InflowCalc.py @@ -2,19 +2,19 @@ def calculate_inflow(registry): - # Java imports must happen after regi_session starts the JVM. - from java.util import Calendar, TimeZone + from datetime import datetime, timezone + from zoneinfo import ZoneInfo + # this gets a scriptable Pool Percent object inflow_calc = registry.getCalculation(1.0, "Inflow") - # Time zone must be set because the Solaris time zone is UTC - time_zone = TimeZone.getTimeZone("US/Central") - # configure the start calendar - start_cal = Calendar.getInstance(time_zone) - start_cal.clear() - start_cal.set(Calendar.YEAR, 2015) - start_cal.set(Calendar.MONTH, 4) + # Time zone must be set explicitly because the JVM's default timezone is + # UTC, not the district's local time. + central = ZoneInfo("America/Chicago") + # Java's Calendar.MONTH was 0-indexed (4 == May); datetime.month is + # 1-indexed, so we use 5 here for the same date. + start_date = (datetime(2015, 5, 1, tzinfo=central)).astimezone(timezone.utc) # inflow_calc contains 4 callable methods: # autoAdjust @@ -32,7 +32,7 @@ def calculate_inflow(registry): # freezeRain # This autoBalances ALAT2 - inflow_calc.autoAdjust("SWF", "ALAT2", start_cal.getTime(), False, False) + inflow_calc.autoAdjust("SWF", "ALAT2", start_date, False, False) if __name__ == "__main__": diff --git a/regi-headless/src/test/resources/usace/rowcps/headless/examples/InflowCalcAutoAdjust.py b/regi-headless/src/test/resources/usace/rowcps/headless/examples/InflowCalcAutoAdjust.py index 5825fa1..61ee5ef 100644 --- a/regi-headless/src/test/resources/usace/rowcps/headless/examples/InflowCalcAutoAdjust.py +++ b/regi-headless/src/test/resources/usace/rowcps/headless/examples/InflowCalcAutoAdjust.py @@ -2,17 +2,19 @@ def calculate_inflow(registry): - # Java imports must happen after regi_session starts the JVM. - from java.util import Calendar, TimeZone + from datetime import datetime, timezone + from zoneinfo import ZoneInfo + # this gets a ScriptableInflow instance. inflow_calc = registry.getCalculation(1.0, "Inflow") - # configure the start calendar - start_cal = Calendar.getInstance(TimeZone.getTimeZone("US/Central")) - start_cal.clear() - start_cal.set(Calendar.YEAR, 2018) - start_cal.set(Calendar.MONTH, 6) + # Time zone must be set explicitly because the JVM's default timezone is + # UTC, not the district's local time. + central = ZoneInfo("America/Chicago") + # Java's Calendar.MONTH was 0-indexed (6 == July); datetime.month is + # 1-indexed, so we use 7 here for the same date. + start_date = (datetime(2018, 7, 1, tzinfo=central)).astimezone(timezone.utc) # inflow_calc contains 4 callable methods: # autoAdjust @@ -30,7 +32,7 @@ def calculate_inflow(registry): # freezeRain # This autoBalances ALAT2 - inflow_calc.autoAdjust("SWF", "ALAT2", start_cal.getTime(), False, False) + inflow_calc.autoAdjust("SWF", "ALAT2", start_date, False, False) if __name__ == "__main__": diff --git a/regi-headless/src/test/resources/usace/rowcps/headless/examples/InflowCalcBalanceAll.py b/regi-headless/src/test/resources/usace/rowcps/headless/examples/InflowCalcBalanceAll.py index a9cb225..a9197cd 100644 --- a/regi-headless/src/test/resources/usace/rowcps/headless/examples/InflowCalcBalanceAll.py +++ b/regi-headless/src/test/resources/usace/rowcps/headless/examples/InflowCalcBalanceAll.py @@ -2,17 +2,19 @@ def calculate_inflow(registry): - # Java imports must happen after regi_session starts the JVM. - from java.util import Calendar, TimeZone + from datetime import datetime, timezone + from zoneinfo import ZoneInfo + # this gets a ScriptableInflow instance. inflow_calc = registry.getCalculation(1.0, "Inflow") - # configure the start calendar - start_cal = Calendar.getInstance(TimeZone.getTimeZone("US/Central")) - start_cal.clear() - start_cal.set(Calendar.YEAR, 2018) - start_cal.set(Calendar.MONTH, 7) + # Time zone must be set explicitly because the JVM's default timezone is + # UTC, not the district's local time. + central = ZoneInfo("America/Chicago") + # Java's Calendar.MONTH was 0-indexed (7 == August); datetime.month is + # 1-indexed, so we use 8 here for the same date. + start_date = (datetime(2018, 8, 1, tzinfo=central)).astimezone(timezone.utc) # inflow_calc contains 4 callable methods: # autoAdjust @@ -30,7 +32,7 @@ def calculate_inflow(registry): # freezeRain # This autoBalances ALAT2 - inflow_calc.balanceAll("SWF", "ALAT2", start_cal.getTime()) + inflow_calc.balanceAll("SWF", "ALAT2", start_date) if __name__ == "__main__": diff --git a/regi-headless/src/test/resources/usace/rowcps/headless/examples/InflowCalcClone.py b/regi-headless/src/test/resources/usace/rowcps/headless/examples/InflowCalcClone.py index d3590d5..32791aa 100644 --- a/regi-headless/src/test/resources/usace/rowcps/headless/examples/InflowCalcClone.py +++ b/regi-headless/src/test/resources/usace/rowcps/headless/examples/InflowCalcClone.py @@ -2,17 +2,19 @@ def calculate_inflow(registry): - # Java imports must happen after regi_session starts the JVM. - from java.util import Calendar, TimeZone + from datetime import datetime, timezone + from zoneinfo import ZoneInfo + # this gets a ScriptableInflow instance. inflow_calc = registry.getCalculation(1.0, "Inflow") - # configure the start calendar - start_cal = Calendar.getInstance(TimeZone.getTimeZone("US/Central")) - start_cal.clear() - start_cal.set(Calendar.YEAR, 2018) - start_cal.set(Calendar.MONTH, 7) + # Time zone must be set explicitly because the JVM's default timezone is + # UTC, not the district's local time. + central = ZoneInfo("America/Chicago") + # Java's Calendar.MONTH was 0-indexed (7 == August); datetime.month is + # 1-indexed, so we use 8 here for the same date. + start_date = (datetime(2018, 8, 1, tzinfo=central)).astimezone(timezone.utc) # inflow_calc contains 4 callable methods: # autoAdjust @@ -30,7 +32,7 @@ def calculate_inflow(registry): # freezeRain # This autoBalances ALAT2 - inflow_calc.cloneInflows("SWF", "ALAT2", start_cal.getTime()) + inflow_calc.cloneInflows("SWF", "ALAT2", start_date) if __name__ == "__main__": diff --git a/regi-headless/src/test/resources/usace/rowcps/headless/examples/InflowCalcComputeEvapAsFlow.py b/regi-headless/src/test/resources/usace/rowcps/headless/examples/InflowCalcComputeEvapAsFlow.py index 8f5bce3..e32c8e5 100644 --- a/regi-headless/src/test/resources/usace/rowcps/headless/examples/InflowCalcComputeEvapAsFlow.py +++ b/regi-headless/src/test/resources/usace/rowcps/headless/examples/InflowCalcComputeEvapAsFlow.py @@ -2,26 +2,23 @@ def calculate_inflow(registry): - # Java imports must happen after regi_session starts the JVM. - from java.util import Calendar, TimeZone + from datetime import datetime, timezone + from zoneinfo import ZoneInfo + # this gets a ScriptableInflow instance. inflow_calc = registry.getCalculation(1.0, "Inflow") - # configure the start calendar - start_cal = Calendar.getInstance(TimeZone.getTimeZone("US/Central")) - start_cal.clear() - start_cal.set(Calendar.YEAR, 2018) - start_cal.set(Calendar.MONTH, 4) - - end_cal = Calendar.getInstance(TimeZone.getTimeZone("US/Central")) - end_cal.clear() - end_cal.set(Calendar.YEAR, 2018) - end_cal.set(Calendar.MONTH, 4) - end_cal.set(Calendar.DAY_OF_MONTH, 4) + # Time zone must be set explicitly because the JVM's default timezone is + # UTC, not the district's local time. + central = ZoneInfo("America/Chicago") + # Java's Calendar.MONTH was 0-indexed (4 == May); datetime.month is + # 1-indexed, so we use 5 here for the same date. + start_date = (datetime(2018, 5, 1, tzinfo=central)).astimezone(timezone.utc) + end_date = (datetime(2018, 5, 4, tzinfo=central)).astimezone(timezone.utc) # This computes and saves evap as flow for EUFA in May 2018 - inflow_calc.computeEvapAsFlow("SWT", "EUFA", start_cal.getTime(), end_cal.getTime()) + inflow_calc.computeEvapAsFlow("SWT", "EUFA", start_date, end_date) if __name__ == "__main__": diff --git a/regi-headless/src/test/resources/usace/rowcps/headless/examples/InflowCalcComputedInflow.py b/regi-headless/src/test/resources/usace/rowcps/headless/examples/InflowCalcComputedInflow.py index 591325f..a977571 100644 --- a/regi-headless/src/test/resources/usace/rowcps/headless/examples/InflowCalcComputedInflow.py +++ b/regi-headless/src/test/resources/usace/rowcps/headless/examples/InflowCalcComputedInflow.py @@ -2,26 +2,23 @@ def calculate_inflow(registry): - # Java imports must happen after regi_session starts the JVM. - from java.util import Calendar, TimeZone + from datetime import datetime, timezone + from zoneinfo import ZoneInfo + # this gets a ScriptableInflow instance. inflow_calc = registry.getCalculation(1.0, "Inflow") - # configure the start calendar - start_cal = Calendar.getInstance(TimeZone.getTimeZone("US/Central")) - start_cal.clear() - start_cal.set(Calendar.YEAR, 2018) - start_cal.set(Calendar.MONTH, 4) - - end_cal = Calendar.getInstance(TimeZone.getTimeZone("US/Central")) - end_cal.clear() - end_cal.set(Calendar.YEAR, 2018) - end_cal.set(Calendar.MONTH, 4) - end_cal.set(Calendar.DAY_OF_MONTH, 4) + # Time zone must be set explicitly because the JVM's default timezone is + # UTC, not the district's local time. + central = ZoneInfo("America/Chicago") + # Java's Calendar.MONTH was 0-indexed (4 == May); datetime.month is + # 1-indexed, so we use 5 here for the same date. + start_date = (datetime(2018, 5, 1, tzinfo=central)).astimezone(timezone.utc) + end_date = (datetime(2018, 5, 4, tzinfo=central)).astimezone(timezone.utc) # This computes and saves inflow for EUFA in May 2018 given the computation options set above - inflow_calc.computeInflow("SWT", "EUFA", start_cal.getTime(), end_cal.getTime()) + inflow_calc.computeInflow("SWT", "EUFA", start_date, end_date) if __name__ == "__main__": diff --git a/regi-headless/src/test/resources/usace/rowcps/headless/examples/InflowCalcZeroNegative.py b/regi-headless/src/test/resources/usace/rowcps/headless/examples/InflowCalcZeroNegative.py index b0e85ad..4f2e8d9 100644 --- a/regi-headless/src/test/resources/usace/rowcps/headless/examples/InflowCalcZeroNegative.py +++ b/regi-headless/src/test/resources/usace/rowcps/headless/examples/InflowCalcZeroNegative.py @@ -2,17 +2,19 @@ def calculate_inflow(registry): - # Java imports must happen after regi_session starts the JVM. - from java.util import Calendar, TimeZone + from datetime import datetime, timezone + from zoneinfo import ZoneInfo + # this gets a ScriptableInflow instance. inflow_calc = registry.getCalculation(1.0, "Inflow") - # configure the start calendar - start_cal = Calendar.getInstance(TimeZone.getTimeZone("US/Central")) - start_cal.clear() - start_cal.set(Calendar.YEAR, 2018) - start_cal.set(Calendar.MONTH, 7) + # Time zone must be set explicitly because the JVM's default timezone is + # UTC, not the district's local time. + central = ZoneInfo("America/Chicago") + # Java's Calendar.MONTH was 0-indexed (7 == August); datetime.month is + # 1-indexed, so we use 8 here for the same date. + start_date = (datetime(2018, 8, 1, tzinfo=central)).astimezone(timezone.utc) # inflow_calc contains 4 callable methods: # autoAdjust @@ -30,7 +32,7 @@ def calculate_inflow(registry): # freezeRain # This autoBalances ALAT2 - inflow_calc.zeroNegatives("SWF", "ALAT2", start_cal.getTime()) + inflow_calc.zeroNegatives("SWF", "ALAT2", start_date) if __name__ == "__main__":