001/* Modify date by adding or subtracting a value to one of the date fields. 002 003 @Copyright (c) 2008-2016 The Regents of the University of California. 004 All rights reserved. 005 006 Permission is hereby granted, without written agreement and without 007 license or royalty fees, to use, copy, modify, and distribute this 008 software and its documentation for any purpose, provided that the 009 above copyright notice and the following two paragraphs appear in all 010 copies of this software. 011 012 IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 013 FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 014 ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 015 THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 016 SUCH DAMAGE. 017 018 THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 019 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 020 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 021 PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 022 CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 023 ENHANCEMENTS, OR MODIFICATIONS. 024 025 PT_COPYRIGHT_VERSION_2 026 COPYRIGHTENDKEY 027 028 */ 029package ptolemy.actor.lib; 030 031import java.util.Calendar; 032 033import ptolemy.actor.TypedAtomicActor; 034import ptolemy.actor.TypedIOPort; 035import ptolemy.data.DateToken; 036import ptolemy.data.IntToken; 037import ptolemy.data.StringToken; 038import ptolemy.data.expr.Parameter; 039import ptolemy.data.expr.StringParameter; 040import ptolemy.data.type.BaseType; 041import ptolemy.kernel.CompositeEntity; 042import ptolemy.kernel.util.IllegalActionException; 043import ptolemy.kernel.util.NameDuplicationException; 044 045/////////////////////////////////////////////////////////////////// 046//// DateElements 047 048/** 049 Modify date by adding or subtracting a value to one of the date fields. 050 051 @author Patricia Derler 052 @version $Id$ 053 @since Ptolemy II 10.0 054 @Pt.ProposedRating Red (pd) 055 @Pt.AcceptedRating Red (pd) 056 */ 057public class ModifyDate extends TypedAtomicActor { 058 /** Construct an actor with the given container and name. 059 * @param container The container. 060 * @param name The name of this actor. 061 * @exception IllegalActionException If the actor cannot be contained 062 * by the proposed container. 063 * @exception NameDuplicationException If the container already has an 064 * actor with this name. 065 */ 066 public ModifyDate(CompositeEntity container, String name) 067 throws NameDuplicationException, IllegalActionException { 068 super(container, name); 069 070 input = new TypedIOPort(this, "input", true, false); 071 input.setTypeEquals(BaseType.DATE); 072 073 operation = new StringParameter(this, "operation"); 074 operation.addChoice("+"); 075 operation.addChoice("-"); 076 operation.setToken(new StringToken("+")); 077 078 value = new TypedIOPort(this, "value", true, false); 079 value.setTypeEquals(BaseType.INT); 080 081 unit = new StringParameter(this, "unit"); 082 unit.addChoice("Year"); 083 unit.addChoice("Month"); 084 unit.addChoice("Day"); 085 unit.addChoice("Hour"); 086 unit.addChoice("Minute"); 087 unit.addChoice("Second"); 088 unit.addChoice("Millisecond"); 089 unit.addChoice("Microsecond"); 090 unit.addChoice("Nanosecond"); 091 unit.setToken(new StringToken("Second")); 092 093 output = new TypedIOPort(this, "output", false, true); 094 output.setTypeEquals(BaseType.DATE); 095 } 096 097 /** Input for date tokens. 098 */ 099 public TypedIOPort input; 100 101 /** Parameter for operation. The operation is a choice of the string 102 * values "+" and "-" and defaults to "+". 103 */ 104 public Parameter operation; 105 106 /** Input for value in a given unit to be added or subtracted from date 107 * token received by input. 108 */ 109 public TypedIOPort value; 110 111 /** Unit of value to be added or subtracted. This can be either part of 112 * the date, i.e. year, month, day, ... and it defaults to second. 113 */ 114 public Parameter unit; 115 116 /** Output for the new date token. 117 */ 118 public TypedIOPort output; 119 120 /////////////////////////////////////////////////////////////////// 121 //// public methods //// 122 123 /** Compute the absolute value of the input. If there is no input, then 124 * produce no output. 125 * @exception IllegalActionException If there is no director. 126 */ 127 @Override 128 public void fire() throws IllegalActionException { 129 super.fire(); 130 if (input.hasToken(0)) { 131 DateToken inputToken = (DateToken) input.get(0); 132 133 DateToken token = new DateToken(inputToken.getValue(), 134 inputToken.getPrecision(), inputToken.getTimeZone()); 135 136 String operationString = ((StringToken) operation.getToken()) 137 .stringValue(); 138 String unitString = ((StringToken) unit.getToken()).stringValue(); 139 140 int val = ((IntToken) value.get(0)).intValue(); 141 if (operationString.equals("+")) { 142 //nothing to do; 143 } else if (operationString.equals("-")) { 144 val = val * (-1); 145 } else { 146 throw new IllegalActionException(this, 147 "Operation " + operationString + " not supported."); 148 } 149 150 boolean setUsingCalendar = true; 151 Calendar calendar = token.getCalendarInstance(); 152 if (unitString.equals("Year")) { 153 calendar.add(Calendar.YEAR, val); 154 } else if (unitString.equals("Month")) { 155 calendar.add(Calendar.MONTH, val); 156 } else if (unitString.equals("Day")) { 157 calendar.add(Calendar.DAY_OF_MONTH, val); 158 } else if (unitString.equals("Hour")) { 159 calendar.add(Calendar.HOUR_OF_DAY, val); 160 } else if (unitString.equals("Minute")) { 161 calendar.add(Calendar.MINUTE, val); 162 } else if (unitString.equals("Second")) { 163 calendar.add(Calendar.SECOND, val); 164 } else if (unitString.equals("Millisecond")) { 165 calendar.add(Calendar.MILLISECOND, val); 166 } else if (unitString.equals("Microsecond")) { 167 setUsingCalendar = false; 168 token.addMicroseconds(val); 169 // Update _value and _calendar in DateToken. 170 token.setTimeInMilliseconds(token.getTimeInMilliseconds()); 171 } else if (unitString.equals("Nanosecond")) { 172 setUsingCalendar = false; 173 token.addNanoseconds(val); 174 // Update _value and _calendar in DateToken. 175 token.setTimeInMilliseconds(token.getTimeInMilliseconds()); 176 } else { 177 throw new IllegalActionException(this, 178 "The unit " + unitString + " is not supported"); 179 } 180 181 // If units are greater than milliseonds 182 if (setUsingCalendar) { 183 // Update _value and _calendar in DateToken. 184 token.setTimeInMilliseconds(calendar.getTimeInMillis()); 185 } 186 187 output.send(0, token); 188 } 189 } 190}