1 | package desmoj.core.simulator; |
2 | |
3 | import java.util.concurrent.TimeUnit; |
4 | import static java.util.concurrent.TimeUnit.*; |
5 | |
6 | /** |
7 | * Represents spans of simulation time. Each span of simulation time is |
8 | * represented by an individual object of this class and offers its own methods |
9 | * for arithmetic operations and comparison. Ensures that only valid spans of |
10 | * time are generated. |
11 | * |
12 | * @version DESMO-J, Ver. 2.3.3 copyright (c) 2011 |
13 | * @author Felix Klueckmann |
14 | * |
15 | * Licensed under the Apache License, Version 2.0 (the "License"); you |
16 | * may not use this file except in compliance with the License. You may |
17 | * obtain a copy of the License at |
18 | * http://www.apache.org/licenses/LICENSE-2.0 |
19 | * |
20 | * Unless required by applicable law or agreed to in writing, software |
21 | * distributed under the License is distributed on an "AS IS" BASIS, |
22 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or |
23 | * implied. See the License for the specific language governing |
24 | * permissions and limitations under the License. |
25 | * |
26 | */ |
27 | public final class TimeSpan implements Comparable<TimeSpan> { |
28 | |
29 | /** |
30 | * ZERO defines the value for scheduling an object immediately, even |
31 | * replacing the current SimProcess. |
32 | */ |
33 | public static final TimeSpan ZERO = new TimeSpan(0, MICROSECONDS); |
34 | |
35 | /** |
36 | * The span of time in the unit of epsilon |
37 | */ |
38 | private final long _durationInEpsilon; |
39 | |
40 | /** |
41 | * Constructs a TimeSpan object with the given time value in the time unit |
42 | * of the given parameter. It represents a time span in simulation time. |
43 | * Note that trying to create a TimeSpan object with a negative value will |
44 | * stop the simulation immediately. The simulation will also stop |
45 | * immediately if the TimeSpan is larger than Long.MAX_VALUE-1 (in the unit |
46 | * of epsilon). |
47 | * |
48 | * @param duration |
49 | * long : The time value of this TimeSpan |
50 | * @param unit |
51 | * TimeUnit: the TimeUnit |
52 | */ |
53 | public TimeSpan(long duration, TimeUnit unit) { |
54 | if (unit == null) { // no time unit given |
55 | throw (new desmoj.core.exception.SimAbortedException( |
56 | new desmoj.core.report.ErrorMessage( |
57 | null, |
58 | "Can't create TimeSpan object! Simulation aborted.", |
59 | "Class : TimeSpan Constructor : TimeSpan(long, TimeUnit)", |
60 | "Time unit passed is null", |
61 | "Make sure to pass a non-null time unit. \nNote that before " + |
62 | "connecting model and experiment, TimeSpans must explicitly\n" + |
63 | "refer to a time unit as the reference unit is not yet defined," + |
64 | "e.g. use \nTimeSpan(long time, TimeUnit unit) instead of" + |
65 | "TimeInstant(long time).", |
66 | null))); |
67 | } |
68 | if (duration < 0) { // points of time must be postive |
69 | throw (new desmoj.core.exception.SimAbortedException( |
70 | new desmoj.core.report.ErrorMessage( |
71 | null, |
72 | "Can't create TimeSpan object! Simulation aborted.", |
73 | "Class : TimeSpan Constructor : TimeSpan(long, TimeUnit)", |
74 | "the value passed for instantiation is negative : " |
75 | + duration, |
76 | "Negative values for simulation time are illegal.", |
77 | null))); |
78 | } |
79 | _durationInEpsilon = TimeOperations.getEpsilon().convert(duration, unit); |
80 | if (_durationInEpsilon == Long.MAX_VALUE) { |
81 | /*The timeSpan is too big. |
82 | (The method TimeUnit.convert(duration,unit)returns Long.MAX_VALUE if |
83 | the result of the conversion is to big*/ |
84 | |
85 | throw (new desmoj.core.exception.SimAbortedException( |
86 | new desmoj.core.report.ErrorMessage( |
87 | null, |
88 | "Can't create TimeSpan object! Simulation aborted.", |
89 | "Class : TimeSpan Constructor : TimeSpan(long,TimeUnit)", |
90 | "the TimeSpan is too big. ", |
91 | "Can only create TimeSpan objects which are smaller than Long.MAX_VALUE (in the TimeUnit of epsilon).", |
92 | null))); |
93 | } |
94 | } |
95 | |
96 | /** |
97 | * Constructs a TimeSpan object with the given time value in the time unit |
98 | * of the reference time. It represents a time span in simulation time. Note |
99 | * that trying to create a TimeSpan object with a negative value will stop |
100 | * the simulation immediately. The simulation will also stop immediately if |
101 | * the TimeSpan is larger than Long.MAX_VALUE-1 (in the unit of epsilon). |
102 | * |
103 | * @param duration |
104 | * long : The time value of this TimeSpan in the time unit of the |
105 | * reference time. |
106 | */ |
107 | public TimeSpan(long duration) { |
108 | this(duration, TimeOperations.getReferenceUnit()); |
109 | } |
110 | |
111 | /** |
112 | * Constructs a TimeSpan object with the given time value in the given |
113 | * timeUnit. It represents a time span in simulation time. Note that trying |
114 | * to create a TimeSpan object with a negative value will stop the |
115 | * simulation immediately. The simulation will also stop immediately if the |
116 | * TimeSpan is larger than Long.MAX_VALUE-1 (in the unit of epsilon). |
117 | * |
118 | * @param duration |
119 | * double : The time value of this TimeSpan in the time unit of |
120 | * the reference time. |
121 | * @param unit |
122 | * TimeUnit : the time unit |
123 | */ |
124 | public TimeSpan(double duration, TimeUnit unit) { |
125 | if (unit == null) { // no time unit given |
126 | throw (new desmoj.core.exception.SimAbortedException( |
127 | new desmoj.core.report.ErrorMessage( |
128 | null, |
129 | "Can't create TimeSpan object! Simulation aborted.", |
130 | "Class : TimeSpan Constructor : TimeSpan(double, TimeUnit)", |
131 | "Time unit passed is null", |
132 | "Make sure to pass a non-null time unit. \nNote that before " + |
133 | "connecting model and experiment, TimeSpans must explicitly\n" + |
134 | "refer to a time unit as the reference unit is not yet defined," + |
135 | "e.g. use \nTimeSpan(double time, TimeUnit unit) instead of" + |
136 | "TimeInstant(double time).", |
137 | null))); |
138 | } |
139 | _durationInEpsilon = (long) (duration * TimeOperations.getEpsilon().convert(1, unit)); |
140 | |
141 | if (_durationInEpsilon < 0) { // points of time must be postive |
142 | throw (new desmoj.core.exception.SimAbortedException( |
143 | new desmoj.core.report.ErrorMessage( |
144 | null, |
145 | "Can't create TimeSpan object! Simulation aborted.", |
146 | "Class : TimeSpan Constructor : TimeSpan(long, TimeUnit)", |
147 | "the value passed for instantiation is negative : " |
148 | + _durationInEpsilon, |
149 | "Negative values for simulation time are illegal.", |
150 | null))); |
151 | } |
152 | if (_durationInEpsilon == Long.MAX_VALUE) { |
153 | /*The timeSpan is too big. |
154 | (The method TimeUnit.convert(duration,unit)returns Long.MAX_VALUE if |
155 | the result of the conversion is to big*/ |
156 | |
157 | throw (new desmoj.core.exception.SimAbortedException( |
158 | new desmoj.core.report.ErrorMessage( |
159 | null, |
160 | "Can't create TimeSpan object! Simulation aborted.", |
161 | "Class : TimeSpan Constructor : TimeSpan(long,TimeUnit)", |
162 | "the TimeSpan is too big. ", |
163 | "Can only create TimeSpan objects which are smaller than Long.MAX_VALUE (in the TimeUnit of epsilon).", |
164 | null))); |
165 | } |
166 | } |
167 | |
168 | /** |
169 | * Constructs a TimeSpan object with the given time value in the time unit |
170 | * of the reference time. It represents a time span in simulation time. Note |
171 | * that trying to create a TimeSpan object with a negative value will stop |
172 | * the simulation immediately.The simulation will also stop immediately if |
173 | * the TimeSpan is larger than Long.MAX_VALUE-1 (in the unit of epsilon). |
174 | * |
175 | * @param duration |
176 | * double : The time value of this TimeSpan in the time unit of |
177 | * the reference time. |
178 | */ |
179 | public TimeSpan(double duration) { |
180 | this(duration, TimeOperations.getReferenceUnit()); |
181 | } |
182 | |
183 | /** |
184 | *Use the Builder to create TimeSpans specified as the sum of durations |
185 | * with different TimeUnits Example (timeSpan with the length of one hour |
186 | * and 30 minutes): new TimeSpan.Builder().hours(1).minutes(30).build(); |
187 | * |
188 | */ |
189 | public static class Builder { |
190 | private long durationInEpsilon; |
191 | |
192 | public Builder() { |
193 | durationInEpsilon = 0L; |
194 | } |
195 | |
196 | public Builder nanoseconds(long nanoseconds) { |
197 | if (nanoseconds < 0) { // points of time must be postive |
198 | throw (new desmoj.core.exception.SimAbortedException( |
199 | new desmoj.core.report.ErrorMessage( |
200 | null, |
201 | "Can't set the value of nanoseconds of the Builder for TimeSpan object! Simulation aborted.", |
202 | "Class : TimeSpan Builder : Builder.nanoseconds(long)", |
203 | "the value passed for the setting of nanoseconds is negative : " |
204 | + nanoseconds, |
205 | "Negative values for simulation time are illegal.", |
206 | null))); |
207 | } |
208 | durationInEpsilon += TimeOperations.getEpsilon().convert( |
209 | nanoseconds, NANOSECONDS); |
210 | return this; |
211 | } |
212 | |
213 | public Builder microseconds(long microseconds) { |
214 | if (microseconds < 0) { // points of time must be positive |
215 | throw (new desmoj.core.exception.SimAbortedException( |
216 | new desmoj.core.report.ErrorMessage( |
217 | null, |
218 | "Can't set the value of microseconds of the Builder for TimeSpan object! Simulation aborted.", |
219 | "Class : TimeSpan Builder : Builder.microseconds(long)", |
220 | "the value passed for the setting of microseconds is negative : " |
221 | + microseconds, |
222 | "Negative values for simulation time are illegal.", |
223 | null))); |
224 | } |
225 | durationInEpsilon += TimeOperations.getEpsilon().convert( |
226 | microseconds, MICROSECONDS); |
227 | return this; |
228 | } |
229 | |
230 | public Builder milliseconds(long milliseconds) { |
231 | if (milliseconds < 0) { // points of time must be postive |
232 | throw (new desmoj.core.exception.SimAbortedException( |
233 | new desmoj.core.report.ErrorMessage( |
234 | null, |
235 | "Can't set the value of milliseconds of the Builder for TimeSpan object! Simulation aborted.", |
236 | "Class : TimeSpan Builder : Builder.milliseconds(long)", |
237 | "the value passed for the setting of milliseconds is negative : " |
238 | + milliseconds, |
239 | "Negative values for simulation time are illegal.", |
240 | null))); |
241 | } |
242 | durationInEpsilon += TimeOperations.getEpsilon().convert( |
243 | milliseconds, MILLISECONDS); |
244 | return this; |
245 | } |
246 | |
247 | public Builder seconds(long seconds) { |
248 | if (seconds < 0) { // points of time must be postive |
249 | throw (new desmoj.core.exception.SimAbortedException( |
250 | new desmoj.core.report.ErrorMessage( |
251 | null, |
252 | "Can't set the value of seconds of the Builder for TimeSpan object! Simulation aborted.", |
253 | "Class : TimeSpan Builder : Builder.seconds(long)", |
254 | "the value passed for the setting of seconds is negative : " |
255 | + seconds, |
256 | "Negative values for simulation time are illegal.", |
257 | null))); |
258 | } |
259 | durationInEpsilon += TimeOperations.getEpsilon().convert(seconds, |
260 | SECONDS); |
261 | return this; |
262 | } |
263 | |
264 | public Builder minutes(long minutes) { |
265 | if (minutes < 0) { // points of time must be postive |
266 | throw (new desmoj.core.exception.SimAbortedException( |
267 | new desmoj.core.report.ErrorMessage( |
268 | null, |
269 | "Can't set the value of minutes of the Builder for TimeSpan object! Simulation aborted.", |
270 | "Class : TimeSpan Builder : Builder.minutes(long)", |
271 | "the value passed for the setting of minutes is negative : " |
272 | + minutes, |
273 | "Negative values for simulation time are illegal.", |
274 | null))); |
275 | } |
276 | durationInEpsilon += TimeOperations.getEpsilon().convert(minutes, |
277 | MINUTES); |
278 | return this; |
279 | } |
280 | |
281 | public Builder hours(long hours) { |
282 | if (hours < 0) { // points of time must be postive |
283 | throw (new desmoj.core.exception.SimAbortedException( |
284 | new desmoj.core.report.ErrorMessage( |
285 | null, |
286 | "Can't set the value of hours of the Builder for TimeSpan object! Simulation aborted.", |
287 | "Class : TimeSpan Builder : Builder.hours(long)", |
288 | "the value passed for the setting of hours is negative : " |
289 | + hours, |
290 | "Negative values for simulation time are illegal.", |
291 | null))); |
292 | } |
293 | durationInEpsilon += TimeOperations.getEpsilon().convert(hours, |
294 | HOURS); |
295 | return this; |
296 | } |
297 | |
298 | public Builder days(long days) { |
299 | if (days < 0) { // points of time must be postive |
300 | throw (new desmoj.core.exception.SimAbortedException( |
301 | new desmoj.core.report.ErrorMessage( |
302 | null, |
303 | "Can't set the value of days of the Builder for TimeSpan object! Simulation aborted.", |
304 | "Class : TimeSpan Builder : Builder.days(long)", |
305 | "the value passed for the setting of days is negative : " |
306 | + days, |
307 | "Negative values for simulation time are illegal.", |
308 | null))); |
309 | } |
310 | durationInEpsilon += TimeOperations.getEpsilon() |
311 | .convert(days, DAYS); |
312 | return this; |
313 | } |
314 | /** |
315 | * Use this method to create TimeSpan objects with the builder pattern. |
316 | * |
317 | */ |
318 | public TimeSpan build() { |
319 | return new TimeSpan(this); |
320 | } |
321 | } |
322 | |
323 | /** |
324 | * private constructor for the Builder pattern |
325 | */ |
326 | private TimeSpan(Builder builder) { |
327 | _durationInEpsilon = builder.durationInEpsilon; |
328 | } |
329 | |
330 | /** |
331 | * Returns the value of the TimeSpan object as a long type in the time unit |
332 | * of epsilon |
333 | * |
334 | * @return long: the time value of the TimeSpan object as a long type in the |
335 | * time unit of epsilon |
336 | */ |
337 | public long getTimeInEpsilon() { |
338 | return _durationInEpsilon; |
339 | } |
340 | |
341 | /** |
342 | * Returns the value of this TimeSpan object as a long type in the time unit |
343 | * given as a parameter. If the parameter has a coarser granularity than |
344 | * epsilon the returned value will be truncated, so lose precision. |
345 | * |
346 | * @param unit |
347 | * : the TimeUnit |
348 | * |
349 | * @return long: the time value of the TimeSpan object as a long type in the |
350 | * time unit given as a parameter or Long.MIN_VALUE if conversion |
351 | * would negatively overflow, or Long.MAX_VALUE if it would |
352 | * positively overflow. |
353 | */ |
354 | public long getTimeTruncated(TimeUnit unit) { |
355 | return unit.convert(_durationInEpsilon, TimeOperations.getEpsilon()); |
356 | } |
357 | |
358 | /** |
359 | * Returns the value of this TimeSpan object as a long type in the time unit |
360 | * of the reference time. If the parameter has a coarser granularity than |
361 | * epsilon the returned value will be truncated, so lose precision. |
362 | * |
363 | * |
364 | * @return long: the time value of the TimeSpan object as a long type in the |
365 | * time unit given as a parameter or Long.MIN_VALUE if conversion |
366 | * would negatively overflow, or Long.MAX_VALUE if it would |
367 | * positively overflow. |
368 | */ |
369 | public long getTimeTruncated() { |
370 | return getTimeTruncated(TimeOperations.getReferenceUnit()); |
371 | } |
372 | |
373 | /** |
374 | * Returns the value of this TimeSpan object as a long type in the time unit |
375 | * given as a parameter. If the parameter has a coarser granularity than |
376 | * epsilon the returned value will be rounded, so lose precision. |
377 | * |
378 | * @param unit |
379 | * : the TimeUnit |
380 | * |
381 | * @return long: the time value of the TimeSpan object as a long type in the |
382 | * time unit given as a parameter or Long.MIN_VALUE if conversion |
383 | * would negatively overflow, or Long.MAX_VALUE if it would |
384 | * positively overflow. |
385 | */ |
386 | public long getTimeRounded(TimeUnit unit) { |
387 | if(unit.compareTo(TimeOperations.getEpsilon())>0){ |
388 | //unit has a coarser granularity than epsilon |
389 | long halfAUnitInEpsilon = TimeOperations.getEpsilon().convert(1, unit) / 2; |
390 | long durationInUnitTruncated = getTimeTruncated(unit); |
391 | long difference = _durationInEpsilon |
392 | - TimeOperations.getEpsilon().convert(durationInUnitTruncated, |
393 | unit); |
394 | // if the time value in the unit Epsilon is bigger than |
395 | if (difference >= halfAUnitInEpsilon) { |
396 | return durationInUnitTruncated + 1; |
397 | } |
398 | return durationInUnitTruncated; |
399 | } |
400 | else { |
401 | //unit has a finer granularity or is equal than epsilon |
402 | return getTimeTruncated(unit); |
403 | } |
404 | |
405 | } |
406 | |
407 | /** |
408 | * Returns the value of this TimeSpan object as a long type in the time unit |
409 | * of the reference time. If the parameter has a coarser granularity than |
410 | * epsilon the returned value will be rounded, so lose precision. |
411 | * |
412 | * |
413 | * @return long: the time value of the TimeSpan object as a long type in the |
414 | * time unit given as a parameter or Long.MIN_VALUE if conversion |
415 | * would negatively overflow, or Long.MAX_VALUE if it would |
416 | * positively overflow. |
417 | */ |
418 | public long getTimeRounded() { |
419 | return getTimeRounded(TimeOperations.getReferenceUnit()); |
420 | } |
421 | |
422 | /** |
423 | * Returns the value of this TimeSpan object as a double type in the time unit |
424 | * given as a parameter. |
425 | * |
426 | * @return double: the time value of the TimeSpan object as a double type in the |
427 | * time unit given as a parameter |
428 | */ |
429 | public double getTimeAsDouble(TimeUnit unit) { |
430 | return _durationInEpsilon |
431 | / (double) TimeOperations.getEpsilon().convert(1, unit); |
432 | } |
433 | |
434 | /** |
435 | * Returns the value of this TimeSpan object as a double type in the time unit |
436 | * of the reference time. |
437 | * |
438 | * @return double: the time value of the TimeSpan object as a double type in the |
439 | * time unit given as a parameter |
440 | */ |
441 | public double getTimeAsDouble() { |
442 | return getTimeAsDouble(TimeOperations.getReferenceUnit()); |
443 | } |
444 | |
445 | |
446 | /** |
447 | * Checks if the first of two spans of simulation time is longer than the |
448 | * second. Note that this is a static method available through calling the |
449 | * class <code>TimeSpan</code> i.e. <code>TimeSpan.isLonger(a,b)</code> |
450 | * where a and b are valid TimeSpan objects. |
451 | * |
452 | * @return boolean : True if a is longer than b |
453 | * @param a |
454 | * TimeSpan : first comparand |
455 | * @param b |
456 | * TimeSpan : second comparand |
457 | */ |
458 | public static boolean isLonger(TimeSpan a, TimeSpan b) { |
459 | return (a._durationInEpsilon > b._durationInEpsilon); |
460 | } |
461 | |
462 | /** |
463 | * Checks if the first of two spans of simulation time is longer than the |
464 | * second or equal to the second. Note that this is a static method |
465 | * available through calling the class <code>TimeSpan</code> i.e. |
466 | * <code>TimeSpan.isLonger(a,b)</code> where a and b are valid TimeSpan |
467 | * objects. |
468 | * |
469 | * @return boolean : True if a is longer than b or equal to b. |
470 | * @param a |
471 | * TimeSpan : first comparand |
472 | * @param b |
473 | * TimeSpan : second comparand |
474 | */ |
475 | public static boolean isLongerOrEqual(TimeSpan a, TimeSpan b) { |
476 | return (isLonger(a, b) || isEqual(a, b)); |
477 | } |
478 | |
479 | /** |
480 | * Checks if the first of two spans of simulation time is shorter than the |
481 | * second. Note that this is a static method available through calling the |
482 | * class <code>TimeSpan</code> i.e. <code>TimeSpan.isShorter(a,b)</code> |
483 | * where a and b are valid TimeSpan objects. |
484 | * |
485 | * @return boolean : True if a is shorter than b |
486 | * @param a |
487 | * TimeSpan : first comparand |
488 | * @param b |
489 | * TimeSpan : second comparand |
490 | */ |
491 | public static boolean isShorter(TimeSpan a, TimeSpan b) { |
492 | return (a._durationInEpsilon < b._durationInEpsilon); |
493 | } |
494 | |
495 | /** |
496 | * Checks if the first of two spans of simulation time is shorter than the |
497 | * second or equal to the second. Note that this is a static method |
498 | * available through calling the class <code>TimeSpan</code> i.e. |
499 | * <code>TimeSpan.isShorterOrEqual(a,b)</code> where a and b are valid |
500 | * TimeSpan objects. |
501 | * |
502 | * @return boolean : True if a is shorter than b or equal to b. |
503 | * @param a |
504 | * TimeSpan : first comparand |
505 | * @param b |
506 | * TimeSpan : second comparand |
507 | */ |
508 | public boolean isShorterOrEqual(TimeSpan a, TimeSpan b) { |
509 | return (isShorter(a, b) || isEqual(a, b)); |
510 | } |
511 | |
512 | /** |
513 | * Indicates whether TimeSpan a is equal to TimeSpan b, i.e. they are of |
514 | * equal length. |
515 | * |
516 | * @param a TimeSpan: first comparand |
517 | * @param b TimeSpan: second comparand |
518 | * @return true if a is equal to b; false otherwise. |
519 | */ |
520 | public static boolean isEqual(TimeSpan a, TimeSpan b) { |
521 | return (a._durationInEpsilon == b._durationInEpsilon); |
522 | } |
523 | |
524 | /** |
525 | * Indicates whether this TimeSpan is equal to the given parameter. Returns |
526 | * true if the obj argument is a TimeSpan and is of equal length as this |
527 | * TimeSpan; false otherwise. This method overrides |
528 | * java.lang.Object.equals() |
529 | * |
530 | * @param obj the reference object with which to compare. |
531 | * @return true if the obj argument is a TimeSpan and is of equal length as |
532 | * this TimeSpan; false otherwise. |
533 | */ |
534 | @Override |
535 | public boolean equals(Object obj) { |
536 | if (!(obj instanceof TimeSpan)) |
537 | return false; |
538 | TimeSpan span = (TimeSpan) obj; |
539 | return isEqual(this, span); |
540 | } |
541 | |
542 | /** |
543 | * Returns a hash code value for the object. This methode overides |
544 | * java.lang.Object.hashCode().The method is supported for the benefit of |
545 | * hashtables such as those provided by java.util.Hashtable. |
546 | * |
547 | * @return int: a hash code value for this TimeSpan. |
548 | */ |
549 | @Override |
550 | public int hashCode() { |
551 | return (int) (this._durationInEpsilon ^ (this._durationInEpsilon >>> 32)); |
552 | } |
553 | |
554 | /** |
555 | * Compares the given TimeSpan to this TimeSpan. This method implements the |
556 | * Comparable<TimeSpan> Interface |
557 | * |
558 | * @param anotherTimeSpan The TimeSpan to be compared to this TimeSpan |
559 | * |
560 | * @return int: Returns a negative integer, zero, or a positive integer as |
561 | * this TimeSpan is shorter than, equal to, or longer than the |
562 | * given parameter. |
563 | */ |
564 | public int compareTo(TimeSpan anotherTimeSpan) { |
565 | long difference = this.getTimeInEpsilon() |
566 | - anotherTimeSpan.getTimeInEpsilon(); |
567 | // if the given parameter is longer than this return -1 |
568 | if (difference < 0) |
569 | return -1; |
570 | // if the given parameter is shorter than this return 1 |
571 | if (difference > 0) |
572 | return 1; |
573 | // if they are equal return 0 |
574 | return 0; |
575 | } |
576 | |
577 | /**Returns the String Representation of this TimeSpan. |
578 | * |
579 | * @see java.lang.Object#toString() |
580 | */ |
581 | @Override |
582 | public String toString() { |
583 | return TimeOperations.formatTimeSpan(this); |
584 | } |
585 | |
586 | /** |
587 | * Returns the String Representation of this TimeSpan according to the |
588 | * TimeFormatter, truncating digits after the decimal point if necessary. |
589 | * |
590 | * @param digits Maximum number of digits after decimal point |
591 | * |
592 | * @see java.lang.Object#toString() |
593 | * @see desmoj.core.simulator.TimeFormatter |
594 | */ |
595 | public String toString(int digits) { |
596 | |
597 | String result = TimeOperations.formatTimeSpan(this); |
598 | |
599 | if (result.lastIndexOf(".") >= 0) { |
600 | result = result.substring(0, Math.max(result.length()-1, result.lastIndexOf(".") + digits)); |
601 | } |
602 | return result; |
603 | } |
604 | } |