printDate

Repository for user functions
Post Reply
User avatar
joleenf
Posts: 1123
Joined: Mon Jan 19, 2009 7:16 pm

printDate

Post by joleenf »

This function can be used to
1.) Obtain a java date object given an input date string
2.) Obtain a date string in a specified format given an input date string.
3.) Add days, years or months to an input time string.
4.) Replace the dateList code posted to the forum in 2011. The dateList code had a bug that occasionally would return the wrong month. This printDate code fixes that bug and uses the java date utilities for date conversion rather than the convoluted string parsing performed in dateList.
5.) This code is not built to address HH:mm:ss time conversions, nor will it perform time zone conversions. However, there is code included which lists available time zones or checks for validity. (listTimeZones(regex=None) and testTimeZone(tz=None) respectively).
6.) Documentation can also be obtained in the jython shell using:
progHelp(printDate)
progHelp(listTimeZones)
progHelp(testTimeZone)


Please follow documentation below to use the code. Please note, a simple test is included, after placing this code in the jython library, it may be tested by typing

Code: Select all

testPrintDate()


in the jython shell.

By default, the code prints the converted date to the jython shell with the format that was traditional in McIDAS-X. Using the outputFormat parameter, the printed date can be customized. If this function is being run within a loop, it may be desirable to use the printResult=False parameter to conserve memory

In addition, the printDate function can be called without saving the returned date object or date string:

example:

Code: Select all

printDate(‘2014141’, inputFormat=’yyyyDDD’)


Usage:
myJavaDate, myDateString = printDate(userDateString,inputFormat='yyyy-MM-dd', yearInc=0, monthInc=0,dayInc=0,outFormat=None, printResult=True)

Print user output date format in form "yyyyDDD = yyyy MMM dd = yyyy/MM/dd" if none is given, otherwise print the date using the given outFormat.

Return a java date object and a date string. Print date to jython shell if printResult=True (default)

Input:
userDateString - date string input by user
inputFormat - the format pattern of the input date string, following the simpleDateFormat Date and Time Pattern conventions (default=’yyyy-MM-dd’)
http://docs.oracle.com/javase/7/docs/ap ... ormat.html

yearInc - number of years to increment or decrement input date (Default=0)
monthInc - number of months to increment or decrement input date (Default=0)
dayInc - number of days to increment or decrement input date (Default=0)
outFormat - the format of the output date, if none is given, the default is the traditional McIDAS-X dateList format.
yyyyDDD = yyyy MMM dd = yyyy/MM/dd

printResult= Boolean which determines if code is printed to jython shell. It is recommended to set printResult to False when running this code in a loop. (default=True)

Code: Select all

#====================================================================================
from java.util import Locale

def setParseDate(userDate,timeZoneObject,userDateFormat='yyyy-MM-dd'):

   """
      year, month, day = setParseDate(userDate,timeZoneObject,userDateFormat='yyyy-MM-dd')
     
      year, month, day = setParseDate('2012/02/22',timeZoneObject,userDateFormat='yyyy/MM/dd')
      year, month, day = setParseDate('2012-02-22',timeZoneObject)
     
      input:
         userDate - string, java.util.Date, or visad.Date object which follows
            the formatting conventions of SimpleDateFormat: 
            http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html#rfc822timezone
         
         timeZoneObject - a java.util.SimpleTimeZone object which defines the time zone and time zone offset
     
         userDateFormat - the format of the input userDate using the SimpleDateFormat formatting convention
            default = 'yyyy-MM-dd'
      Output:
         year - integer
         month - integer
         day - integer
     
      setParseDate accepts a userDate as a string, java.util.Date object, or visad.DateTime object.  Returns
      the year, month, day of that date as integers. 
   """

   if isinstance(userDate, java.util.Date):
      userJavaDate = userDate
   elif isinstance(userDate, DateTime):
      userJavaDate = convertDateTimeToJavaUtilDate(userDate)
   elif isinstance(userDate, str):
      # set the time to current system time if the user does not specify a time:
      if ('HH' not in userDateFormat) and ('mm' not in userDateFormat) and ('ss' not in userDateFormat):
         newCal=Calendar.getInstance(TimeZone.getTimeZone("UTC"))
         systemDate=newCal.getTime()
         systemDateFormat=SimpleDateFormat('HH:mm:ss z')
         systemTime, nowZone=systemDateFormat.format(systemDate).split()
         formatObject = SimpleDateFormat(userDateFormat+' HH:mm:ss z')
         formatObject.setTimeZone(TimeZone.getTimeZone(nowZone))
         userJavaDate = formatObject.parse(userDate + " " + systemTime + " " + nowZone)
      else:   
         # Convert the user's string date to a java.util Date, using declared format.
         formatObject = SimpleDateFormat(userDateFormat)
         formatObject.setTimeZone(timeZoneObject)
         userJavaDate = formatObject.parse(userDate)

   else:
     myException = 'TypeError: The userDate is the type: "' +str(type(userDate))+ '." Must be java.Util.Date, visad.DateTime, or string'
     raise(myException)

   # Set time zone and place user's date in predictable format, so that it can
   # be parsed to a year, month, day, hour minute, second

   predictableFormat = SimpleDateFormat('yyyy MM dd HH mm ss')
   predictableFormat.setTimeZone(timeZoneObject)
   predictableDateStyle = predictableFormat.format(userJavaDate)
   
   year, month, day, hour, minute, second = map(lambda x: int(x), predictableDateStyle.split())
   
   return year, month, day, hour, minute, second
   
#-------------------------------------------------------------------------------------------------   
   
def addToDate(year, month, day, hour, minute, second, yearInc, monthInc, dayInc,\
    timeZoneObject, localeSet=Locale.ENGLISH):
   """
      myCalendar=addToDate(2012,2,22,0,0,5,timeZoneObject)
         returns a calendar with the date 2012-2-27
      Input:
         year - year as integer  (yyyy)
         month - month as integer  (MM)
         day - day as integer (DD)
         
         yearInc - number of years to increment or decrement input year
         monthInc - number of months to increment or decrement input month
         dayInc -number of days to increment or decrement input day
         
         timeZoneObject - java.util.SimpleTimeZone object which sets the timezone and offset
         
         localeSet - set the locale being used. (default = Locale.ENGLISH)
         
      Output:
         java.util.Calendar - a Gregorian Calendar object which is set to the input date plus the incremented
            (decremented) years, months, days if set.
   """

   myCalendar = Calendar.getInstance(timeZoneObject, localeSet)
   
   # subtract one from the month integer because the gregorian calendar is 0 based.
   myCalendar.set(year, month-1, day, hour, minute, second)
   
   if (dayInc != 0):
      myCalendar.add(Calendar.DAY_OF_MONTH,dayInc)
   if (monthInc !=0):
      myCalendar.add(Calendar.MONTH, monthInc)
   if (yearInc !=0):
      myCalendar.add(Calendar.YEAR, yearInc)   
     
   return myCalendar
#-------------------------------------------------------------------------------------------------   
def fromCalendarReturnFormattedDateString(calendarObject, timeZoneObject, format='yyyy-MM-DD'):
   """
      fromCalendarReturnFormattedDateString(calendarObject, timeZoneObject, format'yyyy-MM-DD')
     
      Input:
          calendarObject - a initialized gregorian calendar (java.util.Calendar) set to a date
          timeZoneObject - a timeZoneObject to set the reference time zone and offset
          format - the date format for the output string
      Output:
          theUnicodeDateString - a unicode date string corresponding to the input
            gregorian date in the format specified by the format string.
         
   """
   
   newFormat = SimpleDateFormat(format)
   newFormat.setTimeZone(timeZoneObject)
   theUnicodeDateString = newFormat.format(calendarObject.getTime())
   
   return theUnicodeDateString
#-------------------------------------------------------------------------------------------------     
def printDate(userDateString,inputFormat='yyyy-MM-dd', yearInc=0, monthInc=0, dayInc=0, outFormat=None,printResult=True):

   """
      Usage:
      myJavaDate, myDateString = printDate(userDateString,inputFormat='yyyy-MM-dd', yearInc=0, monthInc=0,dayInc=0,outFormat=None, printResult=True) 

      Print user output date format in form "yyyyDDD = yyyy MMM dd = yyyy/MM/dd" if none is given, otherwise print the date using the given outFormat.

      Return a java date object and a date string.  Print date to jython shell if printResult=True (default)
     
      Input:
         userDateString - date string input by user
         inputFormat - the format pattern of the input date string, following the simpleDateFormat Date and Time Pattern conventions (default=’yyyy-MM-dd’)
         http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html

         yearInc - number of years to increment or decrement input date  (Default=0)
         monthInc - number of months to increment or decrement input date (Default=0)
         dayInc - number of days to increment or decrement input date (Default=0)
         outFormat - the format of the output date, if none is given, the default is the traditional McIDAS-X dateList format.
         yyyyDDD = yyyy MMM dd = yyyy/MM/dd

         printResult=Boolean which determines if code is printed to jython shell.  It is recommended to set printResult to False when running this code in a loop.  (default=True)
   """
   timeZone="UTC"
   # check for timeZone validity first
   testTimeZone(timeZone) 
   timeZoneObject = TimeZone.getTimeZone(timeZone)

   if isinstance(userDateString, int):
      userDateString=str(userDateString)
   
   # parse the user date and return the year month day as integers to set the java Calendar.
   year, month, day, hour, minute, second = setParseDate(userDateString,timeZoneObject, userDateFormat=inputFormat)

   # increment date and get a java.util Calendar object
   returnedCalendar = addToDate(year, month, day, hour, minute, second, yearInc, monthInc, dayInc, timeZoneObject)
       
   # use outFormat for date
   if isinstance(outFormat,str):
       outDateString = fromCalendarReturnFormattedDateString(returnedCalendar, timeZoneObject, format=outFormat)
       if (printResult):
          print outDateString
   else:
       textDate = fromCalendarReturnFormattedDateString(returnedCalendar, timeZoneObject, format='yyyy MMM dd')
       julianDate = fromCalendarReturnFormattedDateString(returnedCalendar, timeZoneObject, format='yyyyDDD')
       slashDate = fromCalendarReturnFormattedDateString(returnedCalendar, timeZoneObject, format='yyyy/MM/dd')
       outDateString=slashDate
       # remove 2014/11/14 #outDateString = fromCalendarReturnFormattedDateString(returnedCalendar, timeZoneObject, format='yyyy/MM/dd HH:mm:ss')
       
       McXStyleDateListPrint =  julianDate + ' = ' + textDate + ' = ' + slashDate
       if (printResult):
          print McXStyleDateListPrint

   javaDate=returnedCalendar.getTime()
       
   return javaDate, outDateString
#-------------------------------------------------------------------------------------------------     
def listTimeZones(regex=None):
   """
      listTimeZones() - lists all available time zone names for use with the java.util.TimeZone class
      listTimeZones(regex='P*') - uses regular expressions to match a pattern for a time zone name.
   """
   import re 
   timeZoneList = TimeZone.getAvailableIDs()
   
   if isinstance(regex, str):
         index = [i for i, x in enumerate(timeZoneList) if re.search(regex, x)]
       
         if len(index) == 0:
            print "There are no matches for "+regex+ " regular expression or string"
         elif len(index) == 1:
            print "There is one match for " + regex
            print timeZoneList[index[0]]
         else:
            print "There are " + str(len(index)) + " matches."
            for x in index:
               print timeZoneList[x]
   else:
      for id in timeZoneList:
         print id
#-------------------------------------------------------------------------------------------------     
def testTimeZone(tz=None):
   """
      testTimeZones(tz='CST') - uses exact expression to determine validity of time zone specification.
      Raises a lookup error if there is not match in the timezone list.
   """
   import re 

   if unicode(tz) in TimeZone.getAvailableIDs():
      pass
   else:
      raise LookupError(tz+" not found.  Use listTimeZones() to list available IDs.")

#-------------------------------------------------------------------------------------------------   
def pd(date,inputFormat='yyyyDDD'):
   """
   
   Usage: 
       pd(date,inputFormat='yyyyDDD')
       dateObject=pd(date,inputFormat='yyyyDDD')

       date - Input string containing a date
       inputFormat - format of input string.
       
   Examples:
      pd('2014295')
      dateObject=pd('2014/10/22', inputFormat='yyyy/MM/dd')

   pd: short for "printDate" does not provide an option to format output.
   It is a quick tool to print the date as a yyyyDDD, yyyy MMM dd and yyyy-MM-dd.
   and return a java date corresponding to the input.
   Use printDate function to obtain more control of output format.
   """

   if isinstance(date,int):
      date=str(date)
   theDateObject, theDateString=printDate(date, inputFormat=inputFormat)

   return theDateObject, theDateString
   
#-------------------------------------------------------------------------------------------------   
def testPrintDate():
   print ' Test 1:  Command Entered:  t1,t1s=printDate("2012-02-12")'
   print ' Test 1:  input date is 2012-02-12, output should be "yyyyDDD = yyyy MMM dd = yyyy/MM/dd"'
   t1,t1s=printDate("2012-02-12")
   
   print '\nTest 2: Command Entered:  t2,t2s=printDate("2012-02-29")'
   print 'Test 2:  Test LEAP YEAR:  input date is 2012-02-29, date should print in default format'
   t2,t2s=printDate("2012-02-29")
   
   print '\nTest 3:  Command Entered:  t3,t3s=printDate("2013-02-29")'
   print 'Test 3:  Test NOT leap year:  input date is 2013-02-29, date should return 2013-03-01 default format'
   t3,t3s=printDate('2013-02-29')
   
   print '\nTest 4:  Command Entered:  t4, t4s=printDate("2013-02-29", outFormat="yyyyDDD")'
   print 'Test 4:  Test NOT leap year and format conversion:  input date is 2013-02-29, date should return 2013060'
   t4, t4s=printDate('2013-02-29', outFormat='yyyyDDD')
   

   print '\n Test 5: Command Entered:  t6,t6s=printDate("2013/12/31", inputFormat="yyyy/MM/dd", yearInc=1)'
   print 'Test 5:  test year addition.  Should return 2014/12/31'
   t5,t5s=printDate('2013/12/31', inputFormat='yyyy/MM/dd', yearInc=1)

   print '\nTest 6:  Command Entered:  t6half,t6halfs=printDate(t6, inputFormat="yyyy/MM/dd", dayInc=1, outFormat="yyyy-MM-dd")'
   print 'Test 6:  add a day to result of t5, Should return 2015-01-01 if t5 is 2014/12/31'
   t6,t6=printDate(t5, inputFormat='yyyy/MM/dd', dayInc=1, outFormat='yyyy-MM-dd')

   print '\n Test 7: Command Entered:  t8,t8s=printDate(today(), inputFormat="yyyyDDD", outFormat="yyyy/MM/dd")'
   print 'Test 7:  input date is today().  Print date'
   t7,t7s=printDate(today(), inputFormat='yyyyDDD', outFormat='yyyy/MM/dd')

#=================================================================================
def progHelp(programName):
   print programName.__doc__
#=================================================================================


printDate.py
(12.77 KiB) Downloaded 761 times

printDate.jar
(3.47 KiB) Downloaded 776 times
User avatar
joleenf
Posts: 1123
Joined: Mon Jan 19, 2009 7:16 pm

Re: printDate

Post by joleenf »

Always learning...

A colleague pointed out that the code could much simpler using python's datetime module...

In this case, the formatting is defined using
https://docs.python.org/2/library/datet ... e-behavior

Code: Select all

def changeDateFormat(inputDate,informat='%Y%j', outFormat='%Y-%b-%d',addDays=0):
    from datetime import datetime, timedelta

    today_parsed = datetime.strptime(inputDate, informat)

    newDate_parsed = today_parsed + timedelta(days=addDays)

    newDate = newDate_parsed.strftime(outFormat)
   
    return newDate


Thanks Mike!
Joleen
Post Reply