source: trunk/grails-app/domain/dbnp/studycapturing/RelTime.groovy @ 540

Last change on this file since 540 was 540, checked in by duh, 11 years ago
  • fixed indentation shite!!!
  • samples dev commit
  • Property svn:keywords set to Date Rev Author
File size: 7.5 KB
RevLine 
[497]1/**
2 * RelTime Domain Class
3 *
4 * Contains useful functions for the RelTime templatefield
5 *
[540]6 * @author Robert Horlings
7 * @since 20100529
8 * @package dbnp.studycapturing
[497]9 *
10 * Revision information:
11 * $Rev: 540 $
12 * $Author: duh $
13 * $Date: 2010-06-08 11:04:08 +0000 (di, 08 jun 2010) $
14 */
15package dbnp.studycapturing
16
17class RelTime {
[540]18        final static long s = 1L;
19        final static long m = 60L * s;
20        final static long h = 60L * m;
21        final static long d = 24L * h;
22        final static long w = 7L * d;
[497]23
[540]24        private long reltimeValue;
[497]25
[540]26        public RelTime() {
27                this(0L);
28        }
[497]29
[540]30        public RelTime(long reltime) {
31                setValue(reltime);
32        }
[497]33
[540]34        public RelTime(String reltime) {
35                parse(reltime);
36        }
[497]37
[540]38        /**
39         * Constructor to create a relative time from two given dates
40         *
41         * The reltime will be the second date, with the first date as reference,
42         * i.e. date2 - date1
43         */
44        public RelTime(Date date1, Date date2) {
45                computeDifference(date1, date2);
46        }
[497]47
[540]48        /**
49         * Constructor to create a relative time from two given relative times
50         *
51         * The reltime will be the second date, with the first date as reference,
52         * i.e. date2 - date1
53         */
54        public RelTime(RelTime date1, RelTime date2) {
55                this(date1.getValue(), date2.getValue());
56        }
[497]57
[540]58        /**
59         * Constructor to create a relative time from two given relative times
60         *
61         * The reltime will be the second date, with the first date as reference,
62         * i.e. date2 - date1
63         */
64        public RelTime(long date1, long date2) {
65                setValue(date2 - date1);
66        }
[497]67
[540]68        /**
69         * Return simple string version of this reltime
70         */
71        public String toString() {
72                def negative = this.reltimeValue < 0;
73                def reltime = this.reltimeValue.abs();
[497]74
[540]75                def seconds = Math.floor((reltime % m) / s).toInteger();
76                def minutes = Math.floor((reltime % h) / m).toInteger();
77                def hours = Math.floor((reltime % d) / h).toInteger();
78                def days = Math.floor((reltime % w) / d).toInteger();
79                def weeks = Math.floor(reltime / w).toInteger();
[497]80
[540]81                def stringValue = negative ? "-" : "";
82                if (weeks > 0) { stringValue += weeks + "w "; }
83                if (days > 0) { stringValue += days + "d "; }
84                if (hours > 0) { stringValue += hours + "h "; }
85                if (minutes > 0) { stringValue += minutes + "m "; }
86                if (seconds > 0) { stringValue += seconds + "s "; }
[497]87
[540]88                return stringValue.trim();
89        }
[497]90
[540]91        /**
92         * Return pretty human readable string of this reltime
93         */
94        public String toPrettyString() {
95                // Method to handle the difference between 1 day and 2 dayS
96                def handleNumerus = {number, string ->
97                        return number.toString() + (number == 1 ? string : string + 's')
98                }
[497]99
[540]100                def negative = this.reltimeValue < 0;
101                def reltime = this.reltimeValue.abs();
[497]102
[540]103                def seconds = Math.floor((reltime % m) / s).toInteger();
104                def minutes = Math.floor((reltime % h) / m).toInteger();
105                def hours = Math.floor((reltime % d) / h).toInteger();
106                def days = Math.floor((reltime % w) / d).toInteger();
107                def weeks = Math.floor(reltime / w).toInteger();
[497]108
[540]109                def stringValue = negative ? "-" : "";
110                def values = [];
111                if (weeks > 0) { values << handleNumerus(weeks, " week") }
112                if (days > 0) { values << handleNumerus(days, " day") }
113                if (hours > 0) { values << handleNumerus(hours, " hour") }
114                if (minutes > 0) { values << handleNumerus(minutes, " minute") }
115                if (seconds > 0) { values << handleNumerus(seconds, " second") }
[497]116
[540]117                return stringValue + values.join(', ').trim();
118        }
[497]119
[540]120        /**
121         * Return pretty human readable string of this reltime
122         */
123        public String toPrettyRoundedString() {
124                // Method to handle the difference between 1 day and 2 dayS
125                def handleNumerus = {number, string ->
126                        return number.toString() + (number == 1 ? string : string + 's')
127                }
[497]128
[540]129                def negative = this.reltimeValue < 0;
130                def reltime = this.reltimeValue.abs();
[497]131
[540]132                def seconds = Math.floor((reltime % m) / s).toInteger();
133                def minutes = Math.floor((reltime % h) / m).toInteger();
134                def hours = Math.floor((reltime % d) / h).toInteger();
135                def days = Math.floor((reltime % w) / d).toInteger();
136                def weeks = Math.floor(reltime / w).toInteger();
[497]137
[540]138                def stringValue = negative ? "-" : "";
139                if (weeks > 0) { return stringValue + handleNumerus(weeks, " week") }
140                if (days > 0) { return stringValue + handleNumerus(days, " day") }
141                if (hours > 0) { return stringValue + handleNumerus(hours, " hour") }
142                if (minutes > 0) { return stringValue + handleNumerus(minutes, " minute") }
143                if (seconds > 0) { return stringValue + handleNumerus(seconds, " second") }
[497]144
[540]145                return "";
146        }
[497]147
[540]148        /**
149         * Returns the value in seconds
150         */
151        public long getValue() {
152                return reltimeValue;
153        }
[497]154
[540]155        /**
156         * Sets the value in seconds
157         */
158        public void setValue(long value) {
159                reltimeValue = value;
160        }
[497]161
[540]162        /**
163         * Sets the value as a string.
164         */
165        public void setValue(String value) {
166                parse(value);
167        }
[497]168
[540]169        /**
170         * Parses a string into a RelTime long
171         *
172         * The relative time may be set as a string, using the following format
173         *
174         *     #w #d #h #m #s
175         *
176         * Where w = weeks, d = days, h = hours, m = minutes, s = seconds
177         *
178         * The spaces between the values are optional. Every timespan
179         * (w, d, h, m, s) must appear at most once. You can also omit
180         * timespans if needed or use a different order.
181         * Other characters are disregarded, allthough results may not
182         * always be as expected.
183         *
184         * If an incorrect format is used, which can't be parsed
185         * an IllegalArgumentException is thrown.
186         *
187         * An empty span is treated as zero seconds.
188         *
189         * Examples:
190         * ---------
191         *    5d 3h 20m     // 5 days, 3 hours and 20 minutes
192         *    6h 2d         // 2 days, 6 hours
193         *    10m 200s      // 13 minutes, 20 seconds (200s == 3m + 20s)
194         *    5w4h15m       // 5 weeks, 4 hours, 15 minutes
195         *
196         *    16x14w10d     // Incorrect. 16x is disregarded, so the
197         *                  // result is 15 weeks, 3 days
198         *    13days        // Incorrect: days should be d, but this is
199         *                  // parsed as 13d, 0 seconds
200         */
201        public void parse(String value) {
202                long newvalue;
[497]203
[540]204                // An empty string should be parsed as 0
205                if (value == null || value.trim() == "" || value.trim() == "-") {
206                        newvalue = 0L;
207                } else {
208                        // Check whether it is a negative number
209                        // this is indicated by a dash in front
210                        def multiplier = 1L;
211                        if (value.trim()[0] == '-') {
212                                multiplier = -1L;
213                        }
[497]214
[540]215                        // Find all parts that contain numbers with
216                        // a character w, d, h, m or s after it
217                        def periodMatch = value =~ /([0-9]+)\s*([wdhms])/
218                        if (periodMatch.size() > 0) {
219                                def seconds = 0L;
[497]220
[540]221                                // Now check if every part contains data for
222                                // the time interval
223                                periodMatch.each {
224                                        def partValue
[497]225
[540]226                                        if (it[1].isLong()) {
227                                                partValue = Long.parseLong(it[1]);
228                                        } else {
229                                                partValue = 0;
230                                        }
[497]231
[540]232                                        switch (it[2]) {
233                                                case 'w':
234                                                        seconds += w * partValue;
235                                                        break;
236                                                case 'd':
237                                                        seconds += d * partValue;
238                                                        break;
239                                                case 'h':
240                                                        seconds += h * partValue;
241                                                        break;
242                                                case 'm':
243                                                        seconds += m * partValue;
244                                                        break;
245                                                case 's':
246                                                        seconds += s * partValue;
247                                                        break;
248                                                default:
249                                                        adf.error.warn('Parsing relative time: ' + it[0] + it[1] + ' is not understood and disregarded');
250                                                        break;
251                                        }
252                                }
[497]253
[540]254                                // Continue with the computed value
255                                newvalue = multiplier * seconds;
256                        } else {
257                                throw new IllegalArgumentException("String " + value + " cannot be parsed as a relative time. Use format #w #d #h #m #s.");
258                                return;
259                        }
260                }
[497]261
[540]262                setValue(newvalue);
263        }
264
265        public void computeDifference(Date start, Date end) {
266                println([start, end]);
267                println([start.getTime(), end.getTime()]);
268
269                if (start && end) {
270                        long seconds = (end.getTime() - start.getTime()) / 1000L;
271                        setValue(seconds);
272                } else {
273                        setValue(0);
274                }
275        }
276
277        static RelTime parseRelTime(String value) {
278                RelTime reltime = new RelTime();
279                reltime.parse(value);
280                return reltime;
281        }
[497]282}
Note: See TracBrowser for help on using the repository browser.