/* * Funambol is a mobile platform developed by Funambol, Inc. * Copyright (C) 2010 Funambol, Inc. * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU Affero General Public License version 3 as published by * the Free Software Foundation with the addition of the following permission * added to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED * WORK IN WHICH THE COPYRIGHT IS OWNED BY FUNAMBOL, FUNAMBOL DISCLAIMS THE * WARRANTY OF NON INFRINGEMENT OF THIRD PARTY RIGHTS. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU Affero General Public License * along with this program; if not, see http://www.gnu.org/licenses or write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301 USA. * * You can contact Funambol, Inc. headquarters at 643 Bair Island Road, Suite * 305, Redwood City, CA 94063, USA, or at email address info@funambol.com. * * The interactive user interfaces in modified source and object code versions * of this program must display Appropriate Legal Notices, as required under * Section 5 of the GNU Affero General Public License version 3. * * In accordance with Section 7(b) of the GNU Affero General Public License * version 3, these Appropriate Legal Notices must retain the display of the * "Powered by Funambol" logo. If the display of the logo is not reasonably * feasible for technical reasons, the Appropriate Legal Notices must display * the words "Powered by Funambol". */ package com.funambol.common.pim.model.utility; public class Duration { private final long FACTOR_MINUTE = 60; private final long FACTOR_HOUR = 60*FACTOR_MINUTE; private final long FACTOR_DAY = 24*FACTOR_HOUR; private final long FACTOR_WEEK = 7*FACTOR_DAY; private final long FACTOR_MONTH = 30*FACTOR_DAY; private final long FACTOR_YEAR = 365*FACTOR_DAY; public int sign; public int seconds; public int minutes; public int hours; public int days; public int weeks; public int months; public int years; public long millis; public Duration() { sign = 1; } /** * Parse according to ISO8601 * * @param str * @throws IllegalArgumentException */ public void parse(String str) throws IllegalArgumentException { sign = 1; years = months = weeks = days = hours = minutes = seconds = 0; int len = str.length(); int index = 0; char c; if (len < 1) { throw new IllegalArgumentException("Invalid duration: " + str); } c = str.charAt(0); if (c == '-') { sign = -1; index++; } else if (c == '+') { index++; } if (len <= index) { throw new IllegalArgumentException("Invalid duration: " + str); } c = str.charAt(index); if (c != 'P') { throw new IllegalArgumentException ( "Duration.parse(str='" + str + "') expected 'P' at index=" + index); } index++; int n = 0; boolean time = false; for (; index < len; index++) { c = str.charAt(index); if (c >= '0' && c <= '9') { n *= 10; n += ((c-'0')); } else if (c == 'Y') { years = n; n = 0; } else if (c == 'W') { weeks = n; n = 0; } else if (c == 'H') { hours = n; n = 0; } else if (c == 'M') { if(time) { minutes = n; } else { months = n; } n = 0; } else if (c == 'S') { seconds = n; n = 0; } else if (c == 'D') { days = n; n = 0; } else if (c == 'T') { time = true; } else { throw new IllegalArgumentException ( "Duration.parse(str='" + str + "') unexpected char '" + c + "' at index=" + index); } } if (n > 0) { throw new IllegalArgumentException("Invalid duration: " + str); } } /** * Format according to ISO8601 * * @return */ public String format() { StringBuffer sb = new StringBuffer(10); if(sign == -1) { sb.append('-'); } sb.append('P'); if(years > 0) { sb.append(years).append('Y'); } if(months > 0) { sb.append(months).append('M'); } if(weeks > 0) { sb.append(weeks).append('W'); } if(days > 0) { sb.append(days).append('D'); } if((hours + minutes + seconds) > 0) { sb.append('T'); } if(hours > 0) { sb.append(hours).append('H'); } if(minutes > 0) { sb.append(minutes).append('M'); } if(seconds > 0) { sb.append(seconds).append('S'); } return sb.toString(); } public long getMillis() { long factor = 1000 * sign; millis = factor * (FACTOR_YEAR*years + (FACTOR_MONTH*months) + (FACTOR_WEEK*weeks) + (FACTOR_DAY*days) + (FACTOR_HOUR*hours) + (FACTOR_MINUTE*minutes) + seconds); return millis; } public void setMillis(long millis) { this.millis = millis; sign = 1; years = months = weeks = days = hours = minutes = seconds = 0; if(millis < 0) { sign = -1; } long factor = 1000 * sign; millis /= factor; years = (int)(millis/FACTOR_YEAR); millis -= years*FACTOR_YEAR; months = (int)(millis/FACTOR_MONTH); millis -= months*FACTOR_MONTH; days = (int)(millis/FACTOR_DAY); millis -= days*FACTOR_DAY; hours = (int)(millis/FACTOR_HOUR); millis -= hours*FACTOR_HOUR; minutes = (int)(millis/FACTOR_MINUTE); millis -= minutes*FACTOR_MINUTE; seconds = (int)millis%(60); } }