NCL Home > Documentation > Functions > Date routines

ut_inv_calendar

Converts a UT-referenced date to a mixed Julian/Gregorian date (deprecated; use cd_inv_calendar).

Prototype

	function ut_inv_calendar (
		year       : numeric,  ; numeric allowed in NCL 6.4.0 and later
		month      : numeric,  
		day        : numeric,  
		hour       : numeric,  
		minute     : numeric,  
		second     : numeric,  
		units      : string,   
		option [1] : integer   
	)

	return_val [dimsizes(year)] :  int, long, float, double (pre V6.4.0 --> double only)

Arguments

year

An array or scalar representing years.

month

An array or scalar representing months. Must be same size as year.

day

An array or scalar representing days. Must be same size as year.

hour

An array or scalar representing hours. Must be same size as year.

minute

An array or scalar representing minutes. Must be same size as year.

second

An array or scalar representing seconds. Must be same size as year.

units

A string representing a formatted time unit specification. Valid strings include:

seconds
minutes
hours
days
months
years

The following units qualifiers may also be used:

since
after
from
ref

Examples:

time@units = "days after 0049-09-01 00:00:00"
time@units = "hours ref 1-1-1 00:00:0.0"
time@units = "months from 1-1-1"

option

The actual value of this variable currently has no effect, but it can optionally contain a "calendar" or "return_type" attribute. See description below.

Return value

An array of the same size as year with a default return type of double.

As of NCL V6.4.0, you can specify other return types of "float", "long", or "integer" via the special "return_type" attribute attached to option. See the description below for details.

The return variable will have a "units" attribute that contains the temporal units.

Description

Unidata no longers supports the internal code that ut_inv_calendar is based on. We therefore strongly recommend that you use the cd_inv_calendar function instead. Important note: ut_inv_calendar and cd_inv_calendar treat "year 0" differently. See the caveats below.

Converts a UT-referenced date to a mixed Julian/Gregorian date. As of version 5.1.0, if the option variable contains a "calendar" attribute with one of the following values:

  • "360", "360_day"
  • "365", "365_day"
  • "noleap"
then this calendar will be used.

Thanks to David W. Pierce, the developer of ncview, for providing these calendar additions.

Important notes

  • Known bug in NCL V6.4.0 and earlier: Many users have reported a "60 second" bug in several of NCL's date conversion routines, in which you get a value of "n minutes, 60 seconds" instead of "n+1 minutes, 0 seconds". See the 6.4.0 release notes for details. If you encounter this bug, please email the ncl-talk group with the details. Meanwhile, you can try the temporary ut_inv_calendar_fix function to see if it fixes the problem.

  • ut_calendar is based on an external software package called UDUNITS-2, which has phased out the support for these types of calendaring routines. Caution should be used when using this routine with special calendars like the above, or negative values.

  • If you use the special "return_type" attribute to specify a return type of something other than double, then be aware that the values could be truncated if they are too large to fit in a float, long, or integer type.

  • This function was updated in NCL V6.4.0 to allow any numeric type to be used for the first six input arguments.

    Internally, the first five arguments have to be coerced to integers. If you pass in floating point or long values that cannot be coerced to integers, then they will be truncated. As an example, if you enter a float value of "1995.8" for year, this will get truncated to an integer equal to "1995". NO WARNING WILL BE ISSUED IF THIS OCCURS.

  • As of NCL version 5.2.0, this code is being linked against UDUNITS-2, which has a dependency on some xml files that come installed with NCL. There's a bug in 5.2.0 that if you are setting the environment variable UDUNITS_PATH, you may see the error message:
    
      warning:ut_inv_calendar: Invalid specification string. Missing values will
      be returned.
    
    There are two possible work-arounds:

    1. Set the UDUNITS2_XML_PATH environment variable:

         setenv UDUNITS2_XML_PATH $NCARG_ROOT/lib/ncarg/udunits/udunits2.xml
      or
         export UDUNITS2_XML_PATH=$NCARG_ROOT/lib/ncarg/udunits/udunits2.xml
      

    2. Unset the UDUNITS_PATH environment variable before you run NCL.

  • In V5.1.0/5.1.1 there's a bug if you use one of the above calendars. You will get an error:

      Error, udu_lib_version not set to value value: -1
    

    A work-around is to call ut_calendar first with dummy data, which internally forces "udu_lib_version" to be correctly initialized. You can use these three lines:

      dum_time       = 17522904
      dum_time@units = "hours since 1-1-1 00:00:0.0"
      dum_date       = ut_calendar(dum_time, 0)
    

To quote the UDUNITS-2 man page:

The udunits(3) package uses a mixed Gregorian/Julian calendar system. Dates prior to 1582-10-15 are assumed to use the Julian calendar, which was introduced by Julius Caesar in 46 BCE and is based on a year that is exactly 365.25 days long. Dates on and after 1582-10-15 are assumed to use the Gregorian calendar, which was introduced on that date and is based on a year that is exactly 365.2425 days long. (A year is actually approximately 365.242198781 days long.) Seemingly strange behavior of the udunits(3) package can result if a user-given time interval includes the changeover date. For example, ut_calendar and ut_inv_calendar can be used to show that 1582-10-15 *preceded* 1582-10-14 by 9 days.

The following excerpt from the UDUNITS-2 documentation explains the time@units encoding by example:

    The specification:

        seconds since 1992-10-8 15:15:42.5 -6:00

    indicates seconds  since October 8th, 1992 at 3 hours, 15 minutes and
    42.5 seconds in the afternoon in the time zone which is six hours to
    the west of Coordinated Universal Time (i.e.  Mountain Daylight Time).
    The time zone specification can also be written without a colon using
    one or two-digits.

Caveats

  • Year 0 and year 1 are treated the same, which is unlike the functions cd_calendar and cd_inv_calendar functions.

  • If you use the special "return_type" attribute to specify a return type of something other than double, then be aware that the values could be truncated if they are too large to fit in a float, long, or integer type.

See Also

cd_calendar, cd_inv_calendar, ut_calendar, cd_convert, cd_string, calendar_decode2, time_axis_labels

Examples

Example 1

To see how the inverse function ut_inv_calendar works, simply take the output from ut_calendar and plug it back into ut_inv_calendar:

  date = ut_inv_calendar(year,month,day,hour,minute,second,time@units, 0)

The arrays date and time should be identical.

Example 2: this example illustrates the use of the "return_type" attribute added in NCL V6.4.0, and serves as a precautionary tale of when it is not a good idea to use it.

  year   = 1999
  month  = 12
  day    = 31
  hour   = 0
  minute = 0
  second = 0
  units  = "hours since 1-1-1 00:00:0.0"

  opt = 0
  ut_dbl1 = ut_inv_calendar(year,month,day,hour,minute,second,units,opt)

  opt@return_type = "float"
  ut_flt1 = ut_inv_calendar(year,month,day,hour,minute,second,units,opt)

  print(ut_dbl1)
  print(ut_flt1)
  print("ut_dbl1-ut_flt1 = " + (ut_dbl1-ut_flt1))

ut_dbl1 and ut_flt1 should be identical, except one will be a float and one will be a double:

    Variable: ut_dbl1
    Type: double
    Total Size: 8 bytes
                1 values
    Number of Dimensions: 1
    Dimensions and sizes:[1]
    Coordinates: 
    Number Of Attributes: 2
    calendar : standard
    units : hours since 1-1-1 00:00:0.0
    17522880
    
    
    Variable: ut_flt1
    Type: float
    Total Size: 4 bytes
                1 values
    Number of Dimensions: 1
    Dimensions and sizes:[1]
    Coordinates: 
    Number Of Attributes: 2
    calendar : standard
    units : hours since 1-1-1 00:00:0.0
    1.752288e+07
    ut_dbl1-ut_flt1 = 0

Note what happens, however, if you simply change the value of hour:

;---Change the hour value and note what happens to ut_flt2
  hour  = 23

  opt2 = 0
  ut_dbl2 = ut_inv_calendar(year,month,day,hour,minute,second,units,opt2)

  opt2@return_type = "float"
  ut_flt2 = ut_inv_calendar(year,month,day,hour,minute,second,units,opt2)

  print(ut_dbl2)
  print(ut_flt2)
  print("ut_dbl2-ut_flt2 = " + (ut_dbl2-ut_flt2))

Note the two values are NOT equal and their differences are not zero:

    Variable: ut_dbl2
    Type: double
    Total Size: 8 bytes
                1 values
    Number of Dimensions: 1
    Dimensions and sizes:[1]
    Coordinates: 
    Number Of Attributes: 2
    calendar : standard
    units : hours since 1-1-1 00:00:0.0
    17522903
    
    
    Variable: ut_flt2
    Type: float
    Total Size: 4 bytes
                1 values
    Number of Dimensions: 1
    Dimensions and sizes:[1]
    Coordinates: 
    Number Of Attributes: 2
    calendar : standard
    units : hours since 1-1-1 00:00:0.0
    1.75229e+07
    ut_dbl2-ut_flt2 = -1