#! /usr/bin/env python

from eon_date import *
import sys
import os

def parse_input_times( is_date, marker, arg=None):
	'''
	#+
	# NAME:
	#	parse_input_times
	# PURPOSE:
	#	Interpret input from command line
	# CALLING SEQUENCE:
	#	tt  = parse_input_times( is_date, marker, arg )
	# INPUTS:
	#	is_date     True : 'arg' is a date
	#	            False: 'arg' is a delta time
	#	marker		identifies the type of information
	#	            that 'arg' represents
	#
	#	            marker = 're=<regex string>'
	#				Then 'arg' is the string to be processed
	#				with the regex.
	#
	#	            marker = '<time format string>'
	#	            (the format could be unspecified, i.e. None)
	#	            Then arg is the string time to be
	#	            interpreted with this format (it it's None
	#	            we're going to guess)
	#
	#	arg			one of the input args from the command
	#	            line
	# OUTPUTS:
	#	tt			dictionary with a lot of fields needed
	#				by the eon_date or eon_delta __init__ method.
	#	            The following relevant combinations can occur.
	#
	#	For times specified as a string in some format:
	#
	#	tt['special'] = ''
	#	tt['ctime'  ] = arg             '2009-10-10 20:00:00'
	#	tt['regex'  ] = None
	#	tt['format' ] = time format     'YYYY-MM-DD hh:mm:ss'
	#
	#	For times specified as a regex:
	#	re=^daily\.l\d\.t\d\.c\d{6}\.(\d{4})(\d{2})(\d{2})\..+\.warts(\.gz)?$
	#	daily.l7.t3.c001991.20120518.her-gr.warts.gz
	#
	#	tt['special'] = ''
	#	tt['ctime'  ] = arg
	#	tt['regex'  ] = marker[3:]
	#	tt['format' ] = None
	#
	#	For times specified by a list of separate components:
	#	"year=2000 doy=10 hour=5 ...."
	#
	#	tt['special'] = 'time'
	#	tt['ctime'  ] = ''
	#	tt['format' ] = None
	#	tt['regex'  ] = None
	#	tt['year'   ] = value or None
	#	tt['doy'    ] = value or None (always None for delta time)
	#	tt['month'  ] = value or None (always None for delta time)
	#	tt['day'    ] = value of None
	#	tt['hour'	] = value or None
	#	tt['minute' ] = value or None
	#	tt['second' ] = value or None
	#	tt['chipsec'] = value or None
	#	tt;'timezone']= value or None (always None for delta time)
	#
	#	For times presented as a single number:
	#
	#	tt['special'] = marker          'posix'
	#	tt['ctime'  ] = ''
	#	tt['format' ] = None
	#	tt['regex'  ] = None
	#	tt[marker   ] = arg             '123456789.00'
	#-
	'''

	# Date: possible single-number date representations

	epoch_options = [
		'posix','njd','mjd','jd','bepoch','jepoch',
	]

	# Date: list of possible components in date

	date_options = [
		'year','doy','month','day','hour','minute','second','chipsec','timezone'
	]

	# Delta time: possible single-number delta representations

	duration_options = [
		'year','day','hour','minute','second','chipsec'
	]

	# Delta time: list of possible components in delta time

	delta_options = [
		'year','day','hour','minute','second','chipsec'
	]

	# Set up return value by setting all possible options to None.
	# The return value collects the information needed for the
	# __init__ methods of eon_date or eon_delta

	tt = dict(ctime = None, format = None, regex = None)

	if is_date:
		for key in epoch_options	: tt[key] = None
		for key in date_options		: tt[key] = None
	else:
		for key in duration_options	: tt[key] = None
		for key in delta_options	: tt[key] = None

	# If there is no time (component) specified, then
	# return a dict filled with None for all options.

	if arg == None:
		return tt

	# Check whether 'marker' refers to a 'special option':
	# - marker = 'time' indicates that one or more time
	#	components are specified in 'arg'.
	# - marker could be one of the single-number time specs
	#
	# If no special option is detected than the intput time
	# must be a string time.

	special_option = ''

	if marker == 'time':			# Check for 'time'
		special_option = 'time'

	else:							# Check for single-number times
		all_options = epoch_options if is_date else duration_options
		opt = [ opt for opt in all_options if opt == marker or opt+'s' == marker ]
		if len(opt) > 0: special_option = opt[0]

	if special_option == '':		# 'arg' is a time string

		tt['special'] = ''			# Not a special option
		tt['ctime'  ] = arg

		if marker != None and len(marker) > 3 and marker[0:3] == 're=':

			if os.path.isfile(marker[3:]):
				import yaml
				yaml_file  = open( marker[3:] )
				tregex = yaml.load(yaml_file)
				yaml_file.close()
				if not tregex.has_key('file') or not tregex['file'].has_key('tregex'):
					raise EonError("__main__, no 'tregex' in YAML file, '%s'"%marker[3:])
				tregex = tregex['file']['tregex']
			else:
				tregex = marker[3:]

			tt['regex' ] = tregex
			tt['format'] = None

		else:

			tt['regex'  ] = None

			if is_date:
				tt['format'] =	\
					None											if tt['ctime'] == ''	else	\
					None											if marker ==  None		else	\
					'YYYY-MM-DD hh:mm:ss.'+'d'*options.exponent		if '-ymd'	in marker	else	\
					'YYYY_MM_DD_hhmmss'   +'d'*options.exponent		if '_ymd'	in marker	else	\
					'YYYYMMDD-hhmmss'	  +'d'*options.exponent		if  'ymd'	in marker	else	\
					'YYYY-DOY hh:mm:ss.'  +'d'*options.exponent		if '-ydoy'	in marker	else	\
					'YYYY_DOY_hhmmss'     +'d'*options.exponent		if '_ydoy'	in marker	else	\
					'YYYYDOY-hhmmss'	  +'d'*options.exponent		if  'ydoy'	in marker	else	\
					'YYYY-MM-DDThh:mm:ss' +'d'*options.exponent		if 'iso'	in marker	else	\
					marker
			else:
				tt['format'] =	\
					None											if tt['ctime'] == ''	else	\
					None											if marker ==  None		else	\
					marker

	elif special_option == 'time':

		# 'date' option
		# Should be input as -i date year=<year> doy=<doy> etc.

		tt['special'] = 'time'
		tt['ctime'  ] = ''

		tt['format' ] = None
		tt['regex'  ] = None

		# Input: -i time "year=2000 doy=10 hour=5 ...."

		# Concatenate all fields separated by "=":
		# year=2000=doy=10=hour=5=.....

		specs = arg.split()
		spec  = specs[0]
		for i in range(1,len(specs)):
			if spec[-1] != '=' and specs[i][0] != '=':
				spec += '='
			spec += specs[i]

		# Split at '='. Even entries in the resulting list are
		# keys; odd entries are values.

		if is_date:
			all_options = date_options[:]
		else:
			all_options = delta_options[:]
			for key in delta_options:
				all_options.append(key+'s')

		specs = spec.split('=')
		for i in range(len(specs)):
			if i%2 == 0:
				key = specs[i]
				if key not in all_options:
					raise EonError("__main__, invalid time specification, '%s'"%key)
				if not is_date and key[-1] == 's':
					key = key[0:-1]
			else:
				if is_date and key == 'month':
					(dummy,specs[i],dummy) = convert_month(0, specs[i])
					specs[i] = str(specs[i])
				spec = specs[i]

				# The timezone needs to stay in string form.
				# All other keys are converted to numerical values.

				tt[key] = spec if key == 'timezone' else float(spec) if '.' in spec else long(spec)

	else:

		tt['special'] = special_option
		tt['ctime'  ] = ''

		tt['format' ] = None
		tt['regex'  ] = None

		# Check for one of the single-number options (like posix time) provided as -i posix <number>
		# Note that it is stored as a string

		tt[special_option] = arg

	return tt

if __name__ == '__main__':
	"""
	#+
	# NAME:
	#	eon
	# PURPOSE:
	#	Converts dates or time periods (delta times) between various formats.
	#	Adds and subtracts dates and delta times.
	# CALLING SEQUENCE:
	#	eon.py -i IN_DATE <DATE> [ ] -o <OUT_DATE>
	# INPUTS:
	#
	#	-i <IN_DATE> t1 [t2 t3 ..]
	#	--in-date=<IN_DATE>  t1 [t2 t3 ..]
	#		is used to indicate that input times are calendar dates
	#
	#		IN_DATE is a string specifying the format describing the input
	#		dates t1, t2, etc.
	#
	#		The following strings are used to specify dates as single numbers (integer or float)
	#			posix		posix time (secs since 1970/01/01 00:00:00 UTC
	#			jd			Julian day (days since -4713/11/24 12:00:00 UTC
	#			njd			'new' Julian day (days since 2000/01/01 12:00:00 UTC)
	#			mjd			modified Julian day (days since 1858/11/16 12:00:00 UTC)
	#			jepoch		Julian epoch
	#			bepoch		Besselian epoch
	#
	#		The second option is to set IN_DATE to a string explicitly specifying the
	#		format needed to interpret the input times t1, t2, etc.. The format must be
	#		constructed from the components
	#			YYYY		year
	#			DOY			day of year
	#			MM		 	month
	#			DD			day of month
	#			hh			hours
	#			mm			minutes
	#			ss			seconds
	#			TZ			timezone
	#
	#		A number of special values for IN_DATE can be used to specify a couple
	#		of commonly used formats:
	#
	#			ymd			same as format YYYYMMDD-hhmmss
	#			-ymd		same as format YYYY-MM-DD hh:mm:ss
	#			_ymd		same as format YYYY_MM_DD_hhmmss
	#			ydoy		same as format YYYYDOY-hhmmss
	#			-ydoy		same as format YYYY-DOY hh:mm:ss
	#			_ydoy		same as format YYYY_DOY_hhmmss
	#			iso8601		same as format YYYY-DD-MMThh:mm:ss
	#
	#		The third options is to set IN_DATE to 'time'; this must be followed by a single (quoted)
	#		string containing the following components for describing a date:
	#			'year=<year> doy=<doy> hour=<hour> minute=<minute> second=<second> timezone=<timezone>'
	#			'year=<year> month=<month> day=<day> hour=<hour> minute=<minute> second=<second> timezone=<timezone>'
	#
	#		Missing leading components are filled in from the current time; missing trailing
	#		components are set to zero.
	#
	#		Multiple input dates can be specified in a single call. If one of the input
	#		dates is set to '-', then input is read from standard input.
	#
	#	-I <IN_DELTA> dt1 [dt2 dt3 ..]
	#	--in-delta=<IN_DELTA> dt1 [dt2 dt3 ..]
	#		is used to indicate that input times are time periods.
	#
	#		IN_DELTA is a string specifying the format describing the input
	#		delta times dt1, dt2, etc.
	#
	#		The following strings are used to specify delta times as single numbers (integer or float)
	#		(the trailing 's' is optional):
	#			year[s]		number of Julian years (=365.25 days)
	#			day[s]		number of days
	#			hour[s]		number of hours
	#			minute[s]	mumber of minutes
	#			second[s]	number of seconds
	#
	#		The second option is to set IN_DELTA to a string explicitly specifying the
	#		format needed to interpret the input delta times dt1, dt2, etc.
	#		The format must be constructed from the components
	#			YYYY		Julian years
	#			DD			days
	#			hh			hours
	#			mm			minutes
	#			ss			seconds
	#
	#		The third options is to set IN_DELTA to 'time'; this must be followed by a single (quoted)
	#		string containing the following components for describing a delta time:
	#			'year=<year> day=<day> hour=<hour> minute=<minute> second=<second>
	#
	#		Multiple input delta times can be specified in a single call. If one of the input
	#		delta times is set to '-', then input is read from standard input.
	#
	#	-A dt1
	#	--plus-delta dt1
	#		is used to add a delta time to an input date or delta time
	#
	#	-s
	#	--minus-date
	#		is used to subtract a date from an input date
	#
	#	-S
	#	--minus-delta
	#		is used to subtract a delta time to an input date or delta time
	#
	# RESTRICTIONS:
	#	--in-date and --in-delta are mutually exclusive
	#	--minus-date is incompatible with --in-delta
	# TODO:
	#	eon.py -p 1029340800.000058055 -s posix 1029369599.999996230
	#	gives -01:16:00:00.000061825
	#	should be -00:08:00.00 ??
	#
	#	Keywords -f --date-format, and -F --delta-format to specify format string
	#
	#	Find a way to deal with delta times that are not really a uniquely
	#	defined time period: year, month
	# EXAMPLES:
	# PROCEDURE:
	#	http://en.wikipedia.org/wiki/ISO_8601#Calendar_dates
	# MODIFICATION HISTORY:
	#	NOV-2011, Paul Hick (UCSD/CASS; pphick@uscd.edu), V1.01
	#		Original version, translated from IDL functions
	#	DEC-2011, Paul Hick (UCSD/CAIDA; pphick@caida.org), V1.02
	#		Started to add shortcut options (-p)
	#	JAN-2012, Paul Hick (UCSD/CAIDA; pphick@caida.org), V1.03
	#		Added shortcut option -P
	#	MAY-2012, Paul Hick (UCSD/CAIDA; pphick@caida.org), V1.04
	#	    Added support for timezones
	#-
	"""

	from optparse import OptionParser

	usage = "\n for date conversion:\n"	+ \
			"  %prog -i IN_DATE <DATE> -o <OUT_DATE>\n"	+ \
			"    IN_DATE is format build from YYYY, MM, DD, hh, mm, ss[.ddd...], timezone (followed by matching date)\n"	+ \
			"            or  'ymd'   same as format YYYYMMDD-hhmmss\n"		+ \
			"            or '-ymd'   same as format YYYY-MM-DD hh:mm:ss\n"	+ \
			"            or '_ymd'   same as format YYYY_MM_DD_hhmmss\n"	+ \
			"            or  'ydoy'  same as format YYYYDOY-hhmmss\n"		+ \
			"            or '-ydoy'  same as format YYYY-DOY hh:mm:ss\n"	+ \
			"            or '_ydoy'  same as format YYYY_DOY_hhmmss\n"		+ \
			"            pr 'iso8601'same as format YYYY-DD-MMThh:mm:ss\n"	+ \
			"            or 'time'   followed by one or more of "			+ \
							"'year=<year> doy=<doy> month=<month> day=<day> hour=<hour> minute=<minute> second=<second> timezone=<timezone>'\n" + \
			"            or 'posix'  followed by posix time (secs since 1970/01/01 00:00:00 UTC\n"		+ \
			"            or 'jd'     followed by Julian day (days since -4713/11/24 12:00:00 UTC\n"		+ \
			"            or 'njd'    followed by 'new' Julian day (days since 2000/01/01 12:00:00 UTC)\n"+ \
			"            or 'mjd'    followed modified Julian day (days since 1858/11/16 12:00:00 UTC)\n"+ \
			"            or 'jepoch' followed by Julian epoch\n"			+ \
			"            or 'bepoch' followed by Besselian epoch\n"			+ \
			"\n for delta (time period) conversion:\n"						+ \
			'  %prog -I IN_DELTA <DELTA> -output <OUT_DELTA>\n'				+ \
			"    IN_DELTA is format build from YYYY, DD, hh, mm, ss[.ddd...] followed by matching delta time\n"	+ \
			"            or 'time '     followed by one or more of 'year=<year> day=<day> hour=<hour> minute=<minute> second=<second>'\n" + \
			"            or 'year[s]'   followed by nr of Julian years\n"	+ \
			"            or 'day[s]'    followed by nr of days\n"			+ \
			"            or 'hour[s]'   followed by nr of hours\n"			+ \
			"            or 'minute[s]' followed by nr of minutes\n"		+ \
			"            or 'second[s]' followed by nr of seconds\n"		+ \
			"\n for date subtraction:\n"									+ \
			'  %prog -i IN_DATE <DATE> -s MINUS_DATE <DATE> -output <OUT_DELTA>\n'	+ \
			"    MINUS_DATE has same options as IN_DATE\n"					+ \
			"            (can only be combined with --in-date)\n"			+ \
			"\n for delta (time period) subtraction:\n"						+ \
			'  %prog -i IN_DATE  <DATE>  -S MINUS_DELTA <DELTA> -output <OUT_DATE>\n'	+ \
			'  %prog -i IN_DELTA <DELTA> -S MINUS_DELTA <DELTA> -output <OUT_DELTA>\n'+ \
			"    MINUS_DELTA has same options as IN_DELTA\n"					+ \
			"\n for delta (time period) addition:\n"						+ \
			'  %prog -i IN_DATE  <DATE>  -A PLUS_DELTA <DELTA> -output <OUT_DATE>\n'	+ \
			'  %prog -i IN_DELTA <DELTA> -A PLUS_DELTA <DELTA> -output <OUT_DELTA>\n'	+ \
			"    PLUS_DELTA has same options as IN_DELTA\n"					+ \
			"\n --output options for date:\n"								+ \
			"    OUT_DATE is format build from YYYY, MM, MON, Month, DD, hh, mm, ss[.ddd...], timezone, DOW, dayofweek\n"	+ \
			"            or  'ymd'   same as format YYYYMMDD-hhmmss\n"		+ \
			"            or '-ymd'   same as format YYYY-MM-DD hh:mm:ss\n"	+ \
			"            or '_ymd'   same as format YYYY_MM_DD_hhmmss\n"	+ \
			"            or  'ydoy'  same as format YYYYDOY-hhmmss\n"		+ \
			"            or '-ydoy'  same as format YYYY-DOY hh:mm:ss\n"	+ \
			"            or '_ydoy'  same as format YYYY_DOY_hhmmss\n"		+ \
			"            or 'iso8601'same as format YYYY-DD-MMThh:mm:ss\n"	+ \
			"            or 'posix'  gives posix time (secs since 1970/01/01 00:00:00 UTC\n"		+ \
			"            or 'jd'     gives Julian day (days since -4713/11/24 12:00:00 UTC\n"		+ \
			"            or 'njd'    gives 'new' Julian day (days since 2000/01/01 12:00:00 UTC)\n"	+ \
			"            or 'mjd'    gives modified Julian day (days since 1858/11/16 12:00:00 UTC)\n"+ \
			"            or 'jepoch' gives Julian epoch\n"					+ \
			"            or 'bepoch' gives Besselian epoch\n"				+ \
			"            or 'dow     gives day of week (number and name)"	+ \
			"\n --round  options for delta (time period):\n"				+ \
			"\n --bot    options for delta (time period):\n"				+ \
			"\n --eot    options for delta (time period):\n"				+ \
			"\n --output options for delta (time period):\n"				+ \
			"    OUT_DELTA is format build from YYYY, DD, hh, mm, ss[.ddd...]\n"	+ \
			"            or 'years'   followed by nr of Julian years\n"		+ \
			"            or 'days'    followed by nr of days\n"				+ \
			"            or 'hours'   followed by nr of hours\n"			+ \
			"            or 'minutes' followed by nr of minutes\n"			+ \
			"            or 'seconds' followed by nr of seconds\n"

	version = '1.04'

	parser = OptionParser(usage=usage,version=version)

	#parser.add_option('-v', '--verbose'	,
	#	action		= 'store_true'	,
	#	default		= False			,
	#	help		= 'verbose (default: False)'
	#)
	parser.add_option('-n', '--now'	,
		dest		= 'now'			,
		action		= 'store_true'	,
		default		= False			,
		help		= 'fill missing leading fields in input dates from current time'	,
	)
	parser.add_option('-e', '--exponent'	,
		dest		= 'exponent',
		action		= 'store'	,
		type		= 'int'		,
		default		= g_EXPONENT,
		help		= 'sets time precision to 10^(-exponent) (default: %s)'%g_EXPONENT	,
	)
	parser.add_option('-i', '--in-date'		,
		dest		= 'in_date'	,
		action		= 'store'	,
		type		= 'string'	,
		help		= 'format spec for input date (default: none)'	,
	)
	parser.add_option('-I', '--in-delta'	,
		dest		= 'in_delta',
		action		= 'store'	,
		type		= 'string'	,
		help		= 'format spec for input time period (default: none)'	,
	)
	parser.add_option('-A',	'--plus-delta'	,
		dest		= 'plus_delta'	,
		action		= 'store'		,
		type		= 'string'		,
		help		= 'time period to add to input date or time period'	,
	)
	parser.add_option('-s', '--minus-date'	,
		dest		= 'sub_date',
		action		= 'store'	,
		type		= 'string'	,
		help		= 'date to subtract from input date'	,
	)
	parser.add_option('-S', '--minus-delta'	,
		dest		= 'minus_delta'	,
		action		= 'store'		,
		type		= 'string'		,
		help		= 'time period to subtract from input date or time period'	,
	)
	parser.add_option('-R', '--round',
		dest		= 'round_delta'	,
		action		= 'store'		,
		type		= 'string'		,
		help		= 'time period used for rounding'	,
	)
	parser.add_option('-B', '--bot'	,
		dest		= 'bot_delta'	,
		action		= 'store'		,
		type		= 'string'		,
		help		= 'time period used for rounding down'	,
	)
	parser.add_option('-E', '--eot'	,
		dest		= 'eot_delta'	,
		action		= 'store'		,
		type		= 'string'		,
		help		= 'time period used for rounding up'	,
	)
	parser.add_option('-o', '--output'	,
		dest		= 'output'			,
		action		= 'store'			,
		type		= 'string'			,
		help		= 'format spec for output time (default: none)'	,
	)
	parser.add_option('-j', '--julian'	,
		dest		= 'julian_input'	,
		action		= 'store_true'		,
		default		= False				,
		help		= 'treat input as Julian date'	,
	)
	parser.add_option('-J', '--Julian'	,
		dest		= 'julian_output'	,
		action		= 'store_true'		,
		default		= False				,
		help		= 'present output as Julian date'	,
	)
	parser.add_option('-p', '--posix'	,
		dest		= 'in_date_posix'	,
		action		= 'store_true'		,
		default		= False				,
		help		= 'shortcut for --in-date=posix'	,
	)
	parser.add_option('-P', '--Posix'	,
		dest		= 'out_date_posix'	,
		action		= 'store_true'		,
		default		= False				,
		help		= 'shortcut for --output=posix'	,
	)
	parser.add_option('-Z', '--timezone',
		dest		= 'timezone_output'	,
		action		= 'store'			,
		type		= 'string'			,
		help		= 'timezone for output (default: UTC)'	,
	)
	parser.add_option('', '--deadline'	,
		dest		= 'deadline'		,
		action		= 'store'			,
		type		= 'string'			,
		help		= 'deadline specification'	,
	)

	#parser.add_option('', '--strict-test'	,
	#	dest		= 'test'				,
	#	action		= 'store'				,
	#	type		= 'string'				,
	#	default		= ''					,
	#	help		= 'strict test of input times'	,
	#)
	#parser.add_option('', '--start-time'	,
	#	dest		= 'start_time'			,
	#	action		= 'store'				,
	#	type		= 'string'				,
	#	help		= 'start time'			,
	#)
	#parser.add_option('', '--stop-time'		,
	#	dest		= 'stop_time'			,
	#	action		= 'store'				,
	#	type		= 'string'				,
	#	help		= 'stop time'			,
	#)

	# This separates the times from the keywords where they were
	# specified. Still needs work.

	options, args = parser.parse_args()

	# Standard input on cmd line: read stdin stream
	# and insert into args

	if '-' in args:
		n = args.index('-')
		args[n:n+1] = [ x.split('\n')[0] for x in sys.stdin.readlines() ]

	# Check for incompatible options

	if options.in_date and options.in_delta:
		parser.error('--in-date and --in-delta are incompatible')
	#if options.in_date and options.minus_delta:
	#	parser.error('--in-date and --minus-delta are incompatible')
	if options.exponent < 0:
		parser.error('--exponent <exponent> must be positive definite')

	# Process shortcut options

	if options.in_date_posix:
		options.in_date = 'posix'
		options.in_date_posix = None

	if options.out_date_posix:
		options.output = 'posix'
		options.out_date_posix = None

	# The first time argument is interpreted as a date, unless it is explicitly
	# identified as a delta time.
	# A special case occurs when options.in_date and options.in_delta are both
	# None. This happens when a time is specified without any --in-date or
	# --in-delta options.
	# This is interpreted as a date in an unspecified format.

	main_is_date = options.in_delta == None

	# ti collects all the times specified.
	# ti['main'] has args[0] in it. If none of the delta-time
	# related options are used, it contains all times in args.

	ti = dict(	main 		= [] ,
				sub_date 	= [] ,
				minus_delta	= [] ,
				plus_delta	= [] ,
				round_delta = [] ,
				bot_delta	= [] ,
				eot_delta	= [] ,
		)

	opt = options.in_date if main_is_date else options.in_delta

		#if main_is_date and opt == 'now':
		#	from time import asctime, gmtime
		#	opt = 'DOW MON DD hh:mm:ss YYYY'
		#	args.insert(0, asctime( gmtime() ))

	if main_is_date and (opt == 'now' or options.now):		# This picks up '-i now'

		options.now = True
		opt = None
		tp  = parse_input_times( main_is_date, opt )
		tp['date'] = main_is_date	# True
		ti['main'].append( tp )		# Blank time

		args.insert(0,'')			# Dummy

	else:

		# If opt=None, then main_is_date=True
		# This happens when a date is specified as time without
		# --in-date or --in-delta, i.e. a date in an unspecified format.

		if len(args) == 0:
			parser.error('no time arguments available')

		tp = parse_input_times( main_is_date, opt, args[0] )
		tp['date'] = main_is_date
		ti['main'].append( tp )

	narg = len(args)

	if options.sub_date != None and narg > 1:
		tp = parse_input_times( True, options.sub_date, args[1] )
		tp['date'] = True
		ti['sub_date'].append( tp )

		if options.minus_delta != None and narg > 2:
			tp = parse_input_times( False, options.minus_delta, args[2] )
			tp['date'] = False
			ti['minus_delta'].append( tp )

			if options.plus_delta != None and narg > 3:
				tp = parse_input_times( False, options.plus_delta, args[3] )
				tp['date'] = False
				ti['plus_delta'].append( tp )

		elif options.plus_delta != None and narg > 2:
			tp = parse_input_times( False, options.plus_delta, args[2] )
			tp['date'] = False
			ti['plus_delta'].append( tp )

	elif options.minus_delta != None and narg > 1:
		tp = parse_input_times( False, options.minus_delta, args[1] )
		tp['date'] = False
		ti['minus_delta'].append( tp )

		if options.plus_delta != None and narg > 2:
			tp = parse_input_times( False, options.plus_delta, args[1] )
			tp['date'] = False
			ti['plus_delta'].append( tp )

	elif options.plus_delta != None and narg > 1:

		tp = parse_input_times( False, options.plus_delta, args[1] )
		tp['date'] = False
		ti['plus_delta'].append( tp )

	elif options.round_delta != None and narg > 1:

		tp = parse_input_times( False, options.round_delta, args[1] )
		tp['date'] = False
		ti['round_delta'].append( tp )

		options.round_delta = None

	elif options.bot_delta != None and narg > 1:

		tp = parse_input_times( False, options.bot_delta, args[1] )
		tp['date'] = False
		ti['bot_delta'].append( tp )

		options.bot_delta = None

	elif options.eot_delta != None and narg > 1:

		tp = parse_input_times( False, options.eot_delta, args[1] )
		tp['date'] = False
		ti['eot_delta'].append( tp )

		options.eot_delta = None

	else:
		for arg in args[1:]:
			opt = options.in_date if main_is_date else options.in_delta
			tp  = parse_input_times( main_is_date, opt, arg )
			tp['date'] = main_is_date
			ti['main'].append( tp )

	for key in ti:
		for n in range(len(ti[key])):
			t = ti[key][n]
			ti[key][n] =	\
				eon_date(
					ctime	= t['ctime'		] ,
					format	= t['format'	] ,
					regex	= t['regex'		] ,

					year	= t['year'		] ,
					doy		= t['doy'		] ,
					month	= t['month'		] ,
					day		= t['day'		] ,
					hour	= t['hour'		] ,
					minute	= t['minute'	] ,
					second	= t['second'	] ,
					chipsec	= t['chipsec'	] ,
					timezone= t['timezone'	] ,

					jd		= t['jd'		] ,
					mjd		= t['mjd'		] ,
					njd		= t['njd'		] ,
					bepoch	= t['bepoch'	] ,
					jepoch	= t['jepoch'	] ,
					posix	= t['posix'		] ,

					julian	= options.julian_input,
					now		= options.now	  ,

					exponent= options.exponent,
				)	\
					\
				if t['date'] else	\
				 	\
				eon_delta(
					ctime	= t['ctime'		] ,
					format	= t['format'	] ,
					regex	= t['regex'		] ,

					year	= t['year'		] ,
					day		= t['day'		] ,
					hour	= t['hour'		] ,
					minute	= t['minute'	] ,
					second	= t['second'	] ,
					chipsec	= t['chipsec'	] ,

					exponent= options.exponent,
				)

	# Do subtractions and additions

	if len(ti['sub_date']) > 0:
		for n in range(len(ti['main'])):
			ti['main'][n] -= ti['sub_date'][0]

	if len(ti['minus_delta']) > 0:
		for n in range(len(ti['main'])):
			ti['main'][n] -= ti['minus_delta'][0]

	if len(ti['plus_delta']) > 0:
		for n in range(len(ti['main'])):
			ti['main'][n] += ti['plus_delta'][0]

	if len(ti['round_delta']) > 0:
		for n in range(len(ti['main'])):
			ti['main'][n] = ti['main'][n].round(ti['round_delta'][0])

	if len(ti['bot_delta']) > 0:
		for n in range(len(ti['main'])):
			ti['main'][n] = ti['main'][n].bot(ti['bot_delta'][0])

	if len(ti['eot_delta']) > 0:
		for n in range(len(ti['main'])):
			ti['main'][n] = ti['main'][n].eot(ti['eot_delta'][0])





	if options.bot_delta != None:
		for n in range(len(ti['main'])):
			ti['main'][n] = ti['main'][n].bop(options.bot_delta)
	elif options.eot_delta != None:
		for n in range(len(ti['main'])):
			ti['main'][n] = ti['main'][n].eop(options.eot_delta)
	elif options.deadline != None:
		for n in range(len(ti['main'])):
			ti['main'][n] = ti['main'][n].set_deadline(options.deadline)



	# Output options

	decimal_part =	'' 							if options.exponent == 0				else	\
					    'd'*options.exponent	if options.output in ['_ymd','_ydoy']	else	\
					'.'+'d'*options.exponent

	for tt in ti['main']:

		if isinstance(tt,eon_date):

			# 'posix' will get posix time as a real number,
			# which is not good for printing (precision only a few digits)
			# Taking it off the list results in options.output = 'posix' to
			# be processed as a format, which allows better control over
			# precision in the resulting string.

			#time_options = ['posix','njd','mjd','jd',
			time_options = ['njd','mjd','jd',
				'bepoch','jepoch',
				'year','doy','month','imonth','cmonth','day',
				'julian_year','julian_month','julian_day',
				'hour','minute','second','chipsec',
				'dow']

			if options.output in time_options:

				attr 	= options.output
				format	= None

			else:

				# If the decimal part (.ddd...) is not specified, append
				# a decimal with options.exponent digits

				attr    = None
				format	=	\
					'YYYY-MM-DD hh:mm:ss'+decimal_part	if options.output == None		else \
					'YYYY_MM_DD_hhmmss'  +decimal_part	if '_ymd'	in options.output	else \
					'YYYY-MM-DD hh:mm:ss'+decimal_part	if '-ymd'	in options.output	else \
					'YYYYMMDD-hhmmss'    +decimal_part	if  'ymd'	in options.output	else \
					'YYYY_DOY_hhmmss'    +decimal_part	if '_ydoy'	in options.output	else \
					'YYYY-DOY hh:mm:ss'  +decimal_part	if '-ydoy'	in options.output	else \
					'YYYYDOY-hhmmss'     +decimal_part	if  'ydoy'	in options.output	else \
					'YYYY-MM-DDThh:mm:ss'+decimal_part	if 'iso'	in options.output	else \
					options.output		 +decimal_part	if 'posix'	== options.output	else \
					options.output

			print tt.get(
				format			= format					,
				attr			= attr						,
				julian			= options.julian_output		,
				timezone		= options.timezone_output	,
			  )

		else:

			if options.output in tt.all_attr():

				format	= None
				attr	= options.output

			else:

				format =	\
					'DDD:hh:mm:ss'+decimal_part if options.output == None else	\
					options.output
				attr = None

			print tt.get(
				format	= format	,
				attr	= attr		,
			  )

	sys.exit(0)
