760 lines
30 KiB
Python
760 lines
30 KiB
Python
##
|
|
# This software was developed and / or modified by Raytheon Company,
|
|
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
|
#
|
|
# U.S. EXPORT CONTROLLED TECHNICAL DATA
|
|
# This software product contains export-restricted data whose
|
|
# export/transfer/disclosure is restricted by U.S. law. Dissemination
|
|
# to non-U.S. persons whether in the United States or abroad requires
|
|
# an export license or other authorization.
|
|
#
|
|
# Contractor Name: Raytheon Company
|
|
# Contractor Address: 6825 Pine Street, Suite 340
|
|
# Mail Stop B8
|
|
# Omaha, NE 68106
|
|
# 402.291.0100
|
|
#
|
|
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
|
# further licensing information.
|
|
##
|
|
# ----------------------------------------------------------------------------
|
|
# This software is in the public domain, furnished "as is", without technical
|
|
# support, and with no warranty, express or implied, as to its usefulness for
|
|
# any purpose.
|
|
#
|
|
# TimeDescriptor.py
|
|
# Methods for producing time descriptors.
|
|
#
|
|
# Author: hansen
|
|
# ----------------------------------------------------------------------------
|
|
#
|
|
# SOFTWARE HISTORY
|
|
#
|
|
# Date Ticket# Engineer Description
|
|
# ------------- -------- --------- --------------------------------------------
|
|
#
|
|
# Feb 28, 2018 7116 randerso Fixed casing in getWeekday_descriptor when
|
|
# combined time period includes a holiday.
|
|
##
|
|
|
|
##
|
|
# This is a base file that is not intended to be overridden.
|
|
##
|
|
|
|
import types
|
|
import time
|
|
import TimeRangeUtils
|
|
import Interfaces
|
|
import Holidays
|
|
import AbsTime
|
|
import TimeRange
|
|
|
|
class TimeDescriptor(TimeRangeUtils.TimeRangeUtils, Interfaces.Interfaces):
|
|
def __init__(self):
|
|
Interfaces.Interfaces.__init__(self)
|
|
TimeRangeUtils.TimeRangeUtils.__init__(self)
|
|
|
|
## def getHolidayLabel(self, tr):
|
|
## return "holiday"
|
|
|
|
def getCurrentTime(self, argDict=None, format="%I%M %p %Z %a %b %d %Y",
|
|
shiftToLocal=1, upperCase=0, stripLeading=1):
|
|
# Return a text string of the current time in the given format
|
|
if argDict is not None and "creationTime" in argDict:
|
|
ctime = argDict['creationTime']
|
|
else:
|
|
ctime = time.time()
|
|
if shiftToLocal == 1:
|
|
curTime = time.localtime(ctime)
|
|
else:
|
|
curTime = time.gmtime(ctime)
|
|
localTime = time.localtime(ctime)
|
|
zoneName = time.strftime("%Z", localTime)
|
|
timeStr = time.strftime(format, curTime)
|
|
if shiftToLocal == 0:
|
|
timeStr = timeStr.replace(zoneName, "GMT")
|
|
if stripLeading == 1 and (timeStr[0] == "0" or timeStr[0] == " "):
|
|
timeStr = timeStr[1:]
|
|
if argDict is None:
|
|
language = "english"
|
|
else:
|
|
language = argDict["language"]
|
|
timeStr = self.translateExpr(timeStr, language)
|
|
if upperCase == 1:
|
|
timeStr = timeStr.upper()
|
|
timeStr = timeStr.replace(" ", " ")
|
|
return timeStr
|
|
|
|
def getIssueTime(self, argDict, upperCase=0):
|
|
# Return the issue time formatted and translated
|
|
# issueRange is set up as the first time range of the
|
|
# product.
|
|
timeRange = argDict["issueRange"]
|
|
timeStr = timeRange.startTime().string()
|
|
timeStr = self.translateExpr(timeStr, argDict["language"])
|
|
if upperCase == 1:
|
|
timeStr = timeStr.upper()
|
|
return timeStr
|
|
|
|
def getWeekday(self, timeRange, holidays=0, shiftToLocal=0,
|
|
labelType="Worded", today=0, tomorrow=0, holidayModule="Holidays",
|
|
nextDay24HourLabel=0, splitDay24HourLabel=0):
|
|
# Check for long time ranges
|
|
if timeRange.duration() > 24 * 3600:
|
|
# If splitDay24HourLabel is not set, we need to make the
|
|
# timeRanges 24 hours long so that getWeekday_descriptor
|
|
# will honor the splitDay24HourLabel setting and leave
|
|
# weekdays as simply the weekday name e.g.
|
|
# Saturday instead of Saturday and Saturday night
|
|
if splitDay24HourLabel:
|
|
# Make 12-hour start and end timeRanges
|
|
durHours1 = 12
|
|
durHours2 = 0
|
|
else:
|
|
# Make 24-hour start and end timeRanges
|
|
durHours1 = 24
|
|
durHours2 = 12
|
|
startTR = TimeRange.TimeRange(timeRange.startTime(),
|
|
timeRange.startTime() + (durHours1 * 3600))
|
|
endTR = TimeRange.TimeRange(timeRange.endTime() - (12 * 3600),
|
|
timeRange.endTime() + (durHours2 * 3600))
|
|
startDay = self.getWeekday_descriptor(startTR, holidays, shiftToLocal,
|
|
"Combo", today, tomorrow, holidayModule, nextDay24HourLabel)
|
|
endDay = self.getWeekday_descriptor(endTR, holidays, shiftToLocal,
|
|
"Capital", today, tomorrow, holidayModule, nextDay24HourLabel)
|
|
s = startDay + " through " + endDay
|
|
return s.upper()
|
|
else: # do the normal thing
|
|
return self.getWeekday_descriptor(timeRange, holidays, shiftToLocal,
|
|
labelType, today, tomorrow, holidayModule,
|
|
nextDay24HourLabel, splitDay24HourLabel)
|
|
|
|
def getWeekday_descriptor(self, timeRange, holidays=0, shiftToLocal=0,
|
|
labelType="Worded", today=0, tomorrow=0,
|
|
holidayModule="Holidays", nextDay24HourLabel=0,
|
|
splitDay24HourLabel=0):
|
|
# Return a weekday text string
|
|
# Arguments:
|
|
# timeRange
|
|
# holidays : if 1, the holiday file will be consulted
|
|
# shiftToLocal : if 1, will shift the given time range to local time
|
|
# labelType : See Labels dictionary below for types
|
|
# today : if 1, Today, Tonight,
|
|
# will be returned instead of corresponding weekday name
|
|
# tomorrow: if 1, Tomorrow, Tomorrow Night
|
|
# will be returned instead of corresponding weekday name
|
|
# holidayModule: file containing holiday dates
|
|
# nextDay24HourLabel: if 1, a 24-hour time period starting
|
|
# after 1600, will be labeled as the next day.
|
|
# This is to accommodate 24 extended periods that go from
|
|
# 6pm-6pm.
|
|
# splitDay24HourLabel: if 0, a 24-hour period will be labeled with
|
|
# simply the weekday name (e.g. Saturday)
|
|
# instead of including the day and night periods
|
|
# (e.g. Saturday and Saturday night)
|
|
#
|
|
# If the time range is for today AND is less than 12 hours,
|
|
# we must accurately describe the period.
|
|
# At some point, this may need to be coordinated with TextRules
|
|
# timePeriod descriptors.
|
|
|
|
currentLocalTime, shift = self.determineTimeShift()
|
|
if shiftToLocal == 1:
|
|
timeRange = TimeRange.TimeRange(timeRange.startTime() + shift,
|
|
timeRange.endTime() + shift)
|
|
labels = self.Labels()[labelType]
|
|
pre = labels["PrePunctuation"]
|
|
post = labels["PostPunctuation"]
|
|
todayFlag = currentLocalTime.day == timeRange.startTime().day
|
|
try:
|
|
if self._productIssuance == "Next Day":
|
|
todayFlag = currentLocalTime.day + 1 == timeRange.startTime().day
|
|
except:
|
|
pass
|
|
startHour = timeRange.startTime().hour
|
|
dayNight = self.getPeriod(timeRange)
|
|
durationHours = timeRange.duration() // 3600
|
|
if nextDay24HourLabel:
|
|
nextDay24Hour = durationHours >= 24 and timeRange.startTime().hour > 16
|
|
else:
|
|
nextDay24Hour = 0
|
|
splitDay24Hour = splitDay24HourLabel and durationHours == 24
|
|
# Do not say "Night" if:
|
|
# startHour is between midnight self.DAY (e.g. 6 am)
|
|
nightTimeFlag = durationHours <= 12 and dayNight == self.NIGHTTIME() \
|
|
and startHour > self.DAY()
|
|
|
|
# Check for holiday
|
|
if not splitDay24Hour and not todayFlag and holidays == 1 and \
|
|
(dayNight == self.DAYTIME() or dayNight == self.DAYNIGHT()):
|
|
|
|
if nextDay24Hour == 1:
|
|
label = Holidays.getHolidayLabel(timeRange.endTime())
|
|
else:
|
|
label = Holidays.getHolidayLabel(timeRange.startTime())
|
|
|
|
if label != "":
|
|
if labelType == "CapitalWithPeriod":
|
|
label = label.upper()
|
|
|
|
return pre + label + post
|
|
|
|
# Check for today or tonight
|
|
if today == 1:
|
|
if todayFlag:
|
|
if dayNight == self.DAYNIGHT():
|
|
# Key off of end time
|
|
keyRange = TimeRange.TimeRange(
|
|
timeRange.endTime() - 3600, timeRange.endTime())
|
|
dayNight = self.getPeriod(keyRange)
|
|
#if durationHours == 1:
|
|
# label = labels["Now"]
|
|
if durationHours < 12 and durationHours > 1:
|
|
if dayNight == self.DAYTIME():
|
|
label = labels["Rest of Today"]
|
|
else:
|
|
label = labels["Rest of Tonight"]
|
|
elif dayNight == self.NIGHTTIME():
|
|
label = labels["Tonight"]
|
|
else:
|
|
label = labels["Today"]
|
|
return pre + label + post
|
|
|
|
# Check for tomorrow or tomorrow night
|
|
if tomorrow == 1:
|
|
startTime = timeRange.startTime() - 24 * 3600
|
|
if startTime.day == currentLocalTime.day:
|
|
if durationHours == 1:
|
|
label = timeRange.startTime().string() + ": "
|
|
elif nightTimeFlag:
|
|
label = labels["Tomorrow"] + " " + labels["Night"]
|
|
else:
|
|
label = labels["Tomorrow"]
|
|
try:
|
|
if self._productIssuance == "Next Day":
|
|
label = "Tonight"
|
|
except:
|
|
pass
|
|
return pre + label + post
|
|
|
|
# Week day
|
|
weekdayName = labels["Weekday"][timeRange.startTime().weekday()]
|
|
if durationHours == 1:
|
|
label = self.timeDisplay(timeRange, "Zulu", "", "", "%I %p")
|
|
if label[0] == "0":
|
|
label = label[1:]
|
|
label = label + " " + weekdayName
|
|
# Check for Night and Evening
|
|
elif nightTimeFlag:
|
|
if durationHours <= 6:
|
|
label = weekdayName + " " + labels["Evening"]
|
|
else:
|
|
label = weekdayName + " " + labels["Night"]
|
|
elif nextDay24Hour == 1:
|
|
# If we have a 24 hour time period starting late in the day,
|
|
# use the next day as the label.
|
|
label = labels["Weekday"][timeRange.endTime().weekday()]
|
|
elif splitDay24Hour:
|
|
# See if we are starting with a night or day period
|
|
weekNight = weekdayName + " " + labels["Night"]
|
|
upper = weekdayName[-1].isupper()
|
|
connector = " and "
|
|
|
|
if startHour < self.NIGHT():
|
|
# Monday and Monday Night OR
|
|
# Labor Day and Monday Night
|
|
weekDayHoliday = self.getHolidayLabel(timeRange.startTime(), holidays)
|
|
if weekDayHoliday != "":
|
|
weekdayName = weekDayHoliday
|
|
label = weekdayName + connector + weekNight
|
|
else:
|
|
# Sunday Night and Monday OR
|
|
# Sunday Night and Labor Day
|
|
nextWeekdayName = self.getHolidayLabel(timeRange.endTime(), holidays)
|
|
if nextWeekdayName == "":
|
|
nextWeekdayName = labels["Weekday"][timeRange.endTime().weekday()]
|
|
label = weekNight + connector + nextWeekdayName
|
|
|
|
if upper:
|
|
label = label.upper()
|
|
else:
|
|
label = weekdayName
|
|
# Check for Evening
|
|
|
|
return pre + label + post
|
|
|
|
def getHolidayLabel(self, absTime, holidays):
|
|
if holidays:
|
|
return Holidays.getHolidayLabel(absTime)
|
|
else:
|
|
return ""
|
|
|
|
def getPeriodLabel(self, range, currentLocalTime, shift, labelType,
|
|
holidays=0):
|
|
# Do a worded label, e.g. Now, Today, Tonight, Tuesday... etc.
|
|
# Compare range (in GMT time) to current local time
|
|
|
|
label = self.getWeekday(range, holidays, 1, labelType)
|
|
return label
|
|
|
|
def getLocalWeekday(self, timeRange):
|
|
return self.getWeekday(timeRange, holidays=1, shiftToLocal=1,
|
|
labelType="SimpleWorded", today=1, tomorrow=0)
|
|
|
|
def getLocalWeekdayName(self, timeRange):
|
|
return self.getWeekday(timeRange, holidays=1, shiftToLocal=1,
|
|
labelType="SimpleWorded")
|
|
|
|
def Labels(self):
|
|
return {
|
|
"SimpleWorded": {
|
|
"PrePunctuation": "",
|
|
"PostPunctuation": "",
|
|
"Weekday" : {
|
|
6 : "Sunday",
|
|
0 : "Monday",
|
|
1 : "Tuesday",
|
|
2 : "Wednesday",
|
|
3 : "Thursday",
|
|
4 : "Friday",
|
|
5 : "Saturday"
|
|
},
|
|
"Now": "now",
|
|
"Today":"today",
|
|
"Tonight": "tonight",
|
|
"Rest of Today":"the rest of today",
|
|
"Rest of Tonight": "the rest of tonight",
|
|
"Night": "night",
|
|
"Evening": "evening",
|
|
"Afternoon": "this afternoon",
|
|
},
|
|
"Worded": {
|
|
"PrePunctuation": "",
|
|
"PostPunctuation": ": ",
|
|
"Weekday" : {
|
|
6 : "Sunday",
|
|
0 : "Monday",
|
|
1 : "Tuesday",
|
|
2 : "Wednesday",
|
|
3 : "Thursday",
|
|
4 : "Friday",
|
|
5 : "Saturday"
|
|
},
|
|
"Now": "Now",
|
|
"Today":"Today",
|
|
"Tonight": "Tonight",
|
|
"Rest of Today":"Rest of Today",
|
|
"Rest of Tonight": "Rest of Tonight",
|
|
"Night": "Night",
|
|
"Evening": "Evening",
|
|
"Afternoon": "This Afternoon",
|
|
},
|
|
"Capital": {
|
|
"PrePunctuation": "",
|
|
"PostPunctuation": "...",
|
|
"Weekday" : {
|
|
6 : "Sunday",
|
|
0 : "Monday",
|
|
1 : "Tuesday",
|
|
2 : "Wednesday",
|
|
3 : "Thursday",
|
|
4 : "Friday",
|
|
5 : "Saturday"
|
|
},
|
|
"Now": "Now",
|
|
"Today":"Today",
|
|
"Tonight": "Tonight",
|
|
"Rest of Today":"Rest of Today",
|
|
"Rest of Tonight": "Rest of Tonight",
|
|
"Night": "Night",
|
|
"Evening": "Evening",
|
|
"Afternoon": "This Afternoon",
|
|
},
|
|
"CapitalWithPeriod": {
|
|
"PrePunctuation": ".",
|
|
"PostPunctuation": "...",
|
|
"Weekday" : {
|
|
6 : "SUNDAY",
|
|
0 : "MONDAY",
|
|
1 : "TUESDAY",
|
|
2 : "WEDNESDAY",
|
|
3 : "THURSDAY",
|
|
4 : "FRIDAY",
|
|
5 : "SATURDAY"
|
|
},
|
|
"Now": "NOW",
|
|
"Today":"TODAY",
|
|
"Tonight": "TONIGHT",
|
|
"Rest of Today":"REST OF TODAY",
|
|
"Rest of Tonight": "REST OF TONIGHT",
|
|
"Night": "NIGHT",
|
|
"Evening": "EVENING",
|
|
"Afternoon": "THIS AFTERNOON",
|
|
},
|
|
"Abbreviated": {
|
|
"PrePunctuation": "",
|
|
"PostPunctuation": "",
|
|
"Weekday" : {
|
|
6 : "Sun",
|
|
0 : "Mon",
|
|
1 : "Tue",
|
|
2 : "Wed",
|
|
3 : "Thu",
|
|
4 : "Fri",
|
|
5 : "Sat"
|
|
},
|
|
"Now": "now",
|
|
"Today":"today",
|
|
"Tonight": "tonight",
|
|
"Rest of Today":"rest of today",
|
|
"Rest of Tonight": "rest of tonight",
|
|
"Night": "night",
|
|
"Evening": "evening",
|
|
"Afternoon": "this afternoon",
|
|
},
|
|
"CapsAbbreviated": {
|
|
"PrePunctuation": "",
|
|
"PostPunctuation": "",
|
|
"Weekday" : {
|
|
6 : "Sun",
|
|
0 : "Mon",
|
|
1 : "Tue",
|
|
2 : "Wed",
|
|
3 : "Thu",
|
|
4 : "Fri",
|
|
5 : "Sat"
|
|
},
|
|
"Now": "Now",
|
|
"Today":"Today",
|
|
"Tonight": "Tonight",
|
|
"Rest of Today":"Rest of today",
|
|
"Rest of Tonight": "Rest of tonight",
|
|
"Night": "Night",
|
|
"Evening": "Evening",
|
|
"Afternoon": "This afternoon",
|
|
},
|
|
"Combo": {
|
|
"PrePunctuation": ".",
|
|
"PostPunctuation": "",
|
|
"Weekday" : {
|
|
6 : "Sunday",
|
|
0 : "Monday",
|
|
1 : "Tuesday",
|
|
2 : "Wednesday",
|
|
3 : "Thursday",
|
|
4 : "Friday",
|
|
5 : "Saturday"
|
|
},
|
|
"Now": "Now",
|
|
"Today":"Today",
|
|
"Tonight": "Tonight",
|
|
"Rest of Today":"Rest of Today",
|
|
"Rest of Tonight": "Rest of Tonight",
|
|
"Night": "Night",
|
|
"Evening": "Evening",
|
|
"Afternoon": "This Afternoon",
|
|
}
|
|
}
|
|
|
|
def timePeriod_descriptor_list(self, tree, node):
|
|
# Contains definition for localtime start/end times and phrase
|
|
# Tuples, 0=startHrLT, 1=endHrLT, 2=phrase
|
|
day = self.DAY()
|
|
return [
|
|
(day, (day + 3) % 24, "early in the morning"), # 6a-9a
|
|
(day, (day + 6) % 24, "in the morning"), # 6a-noon
|
|
(day, (day + 9) % 24, "until late afternoon"), # 6a-3p
|
|
(day, (day + 12) % 24, ""), # 6a-6p
|
|
(day, (day + 15) % 24, "until early evening"), # 6a-9p
|
|
(day, (day + 18) % 24, "through the evening"), # 6a-midnite
|
|
|
|
((day + 2) % 24, (day + 3) % 24, "early in the morning"), # 8a-9a
|
|
|
|
((day + 3) % 24, (day + 6) % 24, "late in the morning"), # 9a-noon
|
|
((day + 3) % 24, (day + 9) % 24, "in the late morning and early afternoon"), # 9a-3p
|
|
((day + 3) % 24, (day + 12) % 24, "in the late morning and afternoon"), # 9a-6p
|
|
((day + 3) % 24, (day + 15) % 24, "until early evening"), # 9a-9p
|
|
((day + 3) % 24, (day + 18) % 24, "through the evening"), # 9a-midnite
|
|
|
|
((day + 5) % 24, (day + 6) % 24, "late in the morning"), # 11a-noon
|
|
|
|
((day + 6) % 24, (day + 9) % 24, "early in the afternoon"), # noon-3p
|
|
((day + 6) % 24, (day + 12) % 24, "in the afternoon"), # noon-6p
|
|
((day + 6) % 24, (day + 15) % 24, "in the afternoon and evening"),# noon-9p
|
|
((day + 6) % 24, (day + 18) % 24, "in the afternoon and evening"),# noon-midnite
|
|
|
|
((day + 8) % 24, (day + 9) % 24, "early in the afternoon"), # 2pm-3pm
|
|
|
|
((day + 9) % 24, (day + 12) % 24, self.lateDay_descriptor), # 3p-6p
|
|
((day + 9) % 24, (day + 15) % 24, "early in the evening"), # 3p-9p
|
|
((day + 9) % 24, (day + 18) % 24, "in the evening"), # 3p-midnite
|
|
((day + 9) % 24, (day + 21) % 24, "until early morning"), # 3p-3a
|
|
((day + 9) % 24, day, ""), # 3p-6a
|
|
|
|
((day + 11) % 24, (day + 12) % 24, self.lateDay_descriptor), # 5p-6p
|
|
|
|
((day + 12) % 24, (day + 15) % 24, "early in the evening"), # 6p-9p
|
|
((day + 12) % 24, (day + 18) % 24, "in the evening"), # 6p-midnite
|
|
((day + 12) % 24, (day + 21) % 24, "until early morning"), # 6p-3a
|
|
((day + 12) % 24, day, ""), # 6p-6a
|
|
|
|
((day + 14) % 24, (day + 15) % 24, "early in the evening"), # 8p-9p
|
|
|
|
((day + 15) % 24, (day + 18) % 24, "late in the evening"), # 9p-midnite
|
|
((day + 15) % 24, (day + 21) % 24, "in the late evening and early morning"),# 9p-3a
|
|
((day + 15) % 24, day, "in the late evening and overnight"), # 9p-6a
|
|
|
|
((day + 17) % 24, (day + 18) % 24, "late in the evening"), # 11p-midnight
|
|
|
|
((day + 18) % 24, (day + 21) % 24, "after midnight"), # midnite-3a
|
|
((day + 18) % 24, day, "after midnight"), # midnite-6a
|
|
((day + 18) % 24, (day + 6) % 24, ""), # midnite-noon
|
|
|
|
((day + 20) % 24, (day + 21) % 24, "after midnight"), # 2a-3a
|
|
|
|
((day + 21) % 24, day, self.lateNight_descriptor), # 3a-6a
|
|
((day + 21) % 24, (day + 3) % 24, "early in the morning"), # 3a-9a
|
|
((day + 21) % 24, (day + 6) % 24, "early in the morning"), # 3a-noon
|
|
((day + 21) % 24, (day + 9) % 24, "until afternoon"), # 3a-3p
|
|
((day + 21) % 24, (day + 12) % 24, ""), # 3a-6p
|
|
|
|
((day + 23) % 24, (day) % 24, self.lateNight_descriptor), # 5a-6a
|
|
|
|
]
|
|
|
|
def lateDay_descriptor(self, tree, node, timeRange):
|
|
return "late in the afternoon"
|
|
|
|
def lateNight_descriptor(self, tree, node, timeRange):
|
|
return "early in the morning"
|
|
|
|
def include_timePeriod_descriptor_flag(
|
|
self, tree, node, statsByRange, index, element):
|
|
# For "range" phrases, tells whether or not to include the time_descriptor
|
|
# i.e "North winds 10-15 knots becoming 20-30 knots in the afternoon."
|
|
# "index" tells which sub-phrase of the phrase we're qualifying, and the default
|
|
# is to qualify every other sub-phrase.
|
|
#
|
|
# Default only applies to Wind and reports "every other" sub-phrase
|
|
if element != "Wind":
|
|
return 1
|
|
flag = 0
|
|
odd = len(statsByRange) % 2
|
|
# If there is an odd number of sub-phrases,
|
|
# report on 1st sub-phrase and then every other one
|
|
if odd == 1:
|
|
if index % 2 == 0:
|
|
flag = 1
|
|
# If there is an even number of sub-phrases,
|
|
# report on 2nd sub-phrase and then every other one
|
|
elif index % 2 == 1:
|
|
flag = 1
|
|
return flag
|
|
|
|
# Time period Table Access
|
|
def timePeriod_descriptor(self, tree, node, timeRange):
|
|
# Returns a descriptor phrase for the time range.
|
|
# Assumes the timeRange is in GMT and converts it to Local time.
|
|
|
|
# more than 12 hours, return empty string
|
|
if timeRange.duration() > 12 * 3600:
|
|
return ""
|
|
if timeRange == node.getTimeRange():
|
|
return ""
|
|
|
|
# determine the local time
|
|
localTime, shift = self.determineTimeShift()
|
|
periodStart = timeRange.startTime() + shift
|
|
periodEnd = timeRange.endTime() + shift
|
|
startHour = periodStart.hour
|
|
endHour = periodEnd.hour
|
|
|
|
# get the table
|
|
table = self.timePeriod_descriptor_list(tree, node)
|
|
|
|
# look for the best match entry, start with the startTime match
|
|
bestIndexes = []
|
|
bestTime = 9999
|
|
for i in range(len(table)):
|
|
diff = self.hourDiff(startHour, table[i][0])
|
|
if diff < bestTime:
|
|
bestTime = diff
|
|
for i in range(len(table)):
|
|
diff = self.hourDiff(startHour, table[i][0])
|
|
if diff == bestTime:
|
|
bestIndexes.append(table[i])
|
|
|
|
# if nothing found, return "" string
|
|
if len(bestIndexes) == 0:
|
|
return ""
|
|
|
|
# now find the best match for the ending time, from the ones earlier
|
|
bestTime = 9999
|
|
returnValue = ''
|
|
for i in range(len(bestIndexes)):
|
|
diff = self.hourDiff(endHour, bestIndexes[i][1])
|
|
if diff < bestTime:
|
|
returnValue = bestIndexes[i][2]
|
|
bestTime = diff
|
|
|
|
if type(returnValue) is types.MethodType:
|
|
return returnValue(tree, node, timeRange)
|
|
else:
|
|
return returnValue
|
|
|
|
def hourDiff(self, h1, h2):
|
|
# returns the number of hours difference
|
|
h = abs(h1 - h2)
|
|
if h > 12:
|
|
h = 24 - h
|
|
return h
|
|
|
|
def dayDict(self):
|
|
return {0:"SUN", 1:"MON", 2:"TUE", 3:"WED", 4:"THU", 5:"FRI", 6:"SAT"}
|
|
def monthDict(self):
|
|
return {1:"JAN", 2:"FEB", 3:"MAR", 4:"APR", 5:"MAY", 6:"JUN",
|
|
7:"JUL", 8:"AUG", 9:"SEP", 10:"OCT", 11:"NOV", 12:"DEC"}
|
|
def monthDict1(self):
|
|
return {1:"Jan", 2:"Feb", 3:"Mar", 4:"Apr", 5:"May", 6:"Jun", 7:"Jul",
|
|
8:"Aug", 9:"Sep", 10:"Oct", 11:"Nov", 12:"Dec"}
|
|
|
|
#********************
|
|
# Methods for formatting TimeRange labels
|
|
|
|
def timeRangeLabel(self, timeRange):
|
|
# Return the label for the given time range
|
|
start = timeRange.startTime()
|
|
end = timeRange.endTime()
|
|
return start.string() + " - " + end.string()
|
|
|
|
def hourAmPm(self, hour):
|
|
# Given a military time hour, return
|
|
# Non-military time plus AM or PM
|
|
if hour == 0:
|
|
hour = 12
|
|
ampm = " AM"
|
|
elif hour == 12:
|
|
ampm = " PM"
|
|
elif hour < 12:
|
|
ampm = " AM"
|
|
else:
|
|
hour = hour - 12
|
|
ampm = " PM"
|
|
return hour, ampm
|
|
|
|
def periodLabel(self, timeRange):
|
|
# Return the label for the given time range
|
|
start = timeRange.startTime()
|
|
hourStr = repr(start.hour) + "Z/" + repr(start.day)
|
|
return hourStr
|
|
|
|
def localTimeRangeLabel(self, timeRange):
|
|
# Return the label for the given time range
|
|
localTime, shift = self.determineTimeShift()
|
|
localStart = timeRange.startTime() + shift
|
|
localEnd = timeRange.endTime() + shift
|
|
localRange = TimeRange.TimeRange(localStart, localEnd)
|
|
|
|
# Determine name of time zone (e.g. MST, MDT...)
|
|
localTime = time.localtime(time.time())
|
|
zoneName = time.strftime("%Z", localTime)
|
|
|
|
# Create label
|
|
localStr = self.timeRangeLabel(localRange)
|
|
localStr = localStr.replace("GMT", zoneName)
|
|
return localStr
|
|
|
|
def localOneHourTRLabel(self, timeRange):
|
|
# Return label in form: Month Day, Year hour - hour
|
|
# E.g. Sept 30, 2000 1 AM - 2 AM
|
|
localTime, shift = self.determineTimeShift()
|
|
start = timeRange.startTime() + shift
|
|
localTime = time.localtime(time.time())
|
|
zoneName = time.strftime("%Z", localTime)
|
|
monthDict = self.monthDict()
|
|
s = monthDict[start.month] + " " + repr(start.day) + ", " + repr(start.year)
|
|
hour1, ampm1 = self.hourAmPm(start.hour)
|
|
hour2, ampm2 = self.hourAmPm(start.hour + 1)
|
|
return s + " " + repr(hour1) + ampm1 + " " + zoneName + " - " + \
|
|
repr(hour2) + ampm2 + " " + zoneName
|
|
|
|
def localTRLabel(self, timeRange):
|
|
# Return label in form
|
|
# E.g. Sept 30, 1 AM MST TO Oct 1, 2 AM MST
|
|
localTime, shift = self.determineTimeShift()
|
|
start = timeRange.startTime() + shift
|
|
end = timeRange.endTime() + shift
|
|
localTime = time.localtime(time.time())
|
|
zoneName = time.strftime("%Z", localTime)
|
|
hour1, ampm1 = self.hourAmPm(start.hour)
|
|
hour2, ampm2 = self.hourAmPm(end.hour)
|
|
monthDict1 = self.monthDict1()
|
|
str1 = repr(hour1) + ampm1 + " " + zoneName + " " + monthDict1[start.month] + " " + repr(start.day)
|
|
str2 = repr(hour2) + ampm2 + " " + zoneName + " " + monthDict1[end.month] + " " + repr(end.day)
|
|
return str1 + " TO " + str2
|
|
|
|
def localPeriodLabel(self, timeRange):
|
|
# Return the label for the given time range
|
|
|
|
# Adjust time from GMT to local
|
|
localTime, shift = self.determineTimeShift()
|
|
start = timeRange.startTime() + shift
|
|
|
|
# Determine name of time zone (e.g. MST, MDT...)
|
|
localTime = time.localtime(time.time())
|
|
zoneName = time.strftime("%Z", localTime)
|
|
|
|
# Create label
|
|
hourStr = repr(start.hour) + " " + zoneName + "/" + repr(start.day)
|
|
return hourStr
|
|
|
|
def localTimeLabel(self, timeRange):
|
|
# Return a label of length 6 the form: hour AM/PM
|
|
# E.g. 5 PM
|
|
return self.localHourLabel(timeRange.startTime(), 6)
|
|
|
|
def localRangeLabel(self, timeRange):
|
|
# Return label of range: 5AM-6PM
|
|
label1 = self.localHourLabel(timeRange.startTime(), 4)
|
|
label2 = self.localHourLabel(timeRange.endTime(), 4)
|
|
s = label1 + "-" + label2
|
|
return s.replace(" ", "")
|
|
|
|
def localHourLabel(self, absTime, length=6):
|
|
# Convert from gmt to local time
|
|
localTime, shift = self.determineTimeShift()
|
|
start = absTime + shift
|
|
hour = start.hour
|
|
hour, ampm = self.hourAmPm(hour)
|
|
label = repr(hour) + ampm
|
|
return label.rjust(length)
|
|
|
|
def strToGMT(self, timeStr):
|
|
# Convert a time str in the form of local time
|
|
# hours and minutes to a GMT AbsTime for the current day.
|
|
# The time string must be 6 or 7 characters long
|
|
# E.g. "1030 AM"
|
|
# "800 PM"
|
|
|
|
# Get the hour and minutes
|
|
length = len(timeStr)
|
|
amPm = timeStr[length - 2:length]
|
|
minutes = timeStr[length - 5:length - 3]
|
|
minutes = int(minutes)
|
|
if length > 6:
|
|
hour = timeStr[0:2]
|
|
else:
|
|
hour = timeStr[0]
|
|
hour = int(hour)
|
|
if hour == 12:
|
|
if amPm == "AM":
|
|
hour = 0
|
|
else:
|
|
if amPm == "PM":
|
|
hour = hour + 12
|
|
# Make a local AbsTime
|
|
curLocalTime, shift = self.determineTimeShift()
|
|
newTime = AbsTime.absTimeYMD(curLocalTime.year, curLocalTime.month,
|
|
curLocalTime.day, hour, minutes)
|
|
# Convert to GMT
|
|
return newTime - shift
|