Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT License. See License.txt in the project root for license information.
/** * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for * license information. */
package com.microsoft.azure.management.servicebus.implementation; import org.joda.time.Period; import rx.functions.Func0;
Represents a time interval.
/** * Represents a time interval. */
public class TimeSpan { private static long ticksPerMillisecond = 10000; private static long ticksPerSecond = ticksPerMillisecond * 1000; private static long ticksPerMinute = ticksPerSecond * 60; private static long ticksPerHour = ticksPerMinute * 60; private static long ticksPerDay = ticksPerHour * 24; private static double millisecondsPerTick = 1.0 / ticksPerMillisecond; private static double secondsPerTick = 1.0 / ticksPerSecond; private static double minutesPerTick = 1.0 / ticksPerMinute; private int days; private int hours; private int minutes; private int seconds; private int milliseconds;
Creates TimeSpan.
/** * Creates TimeSpan. */
public TimeSpan() { }
Specifies the number of days.
Params:
  • days – number of days
Returns:TimeSpan
/** * Specifies the number of days. * * @param days number of days * @return TimeSpan */
public TimeSpan withDays(final int days) { this.days = days; return this; }
Specifies the number of hours.
Params:
  • hours – number of hours
Returns:TimeSpan
/** * Specifies the number of hours. * * @param hours number of hours * @return TimeSpan */
public TimeSpan withHours(final int hours) { this.hours = hours; return this; }
Specifies the number of minutes.
Params:
  • minutes – number of minutes
Returns:TimeSpan
/** * Specifies the number of minutes. * * @param minutes number of minutes * @return TimeSpan */
public TimeSpan withMinutes(final int minutes) { this.minutes = minutes; return this; }
Specifies the number of seconds.
Params:
  • seconds – number of seconds
Returns:TimeSpan
/** * Specifies the number of seconds. * * @param seconds number of seconds * @return TimeSpan */
public TimeSpan withSeconds(final int seconds) { this.seconds = seconds; return this; }
Specifies the number of milliseconds.
Params:
  • milliseconds – number of milliseconds
Returns:TimeSpan
/** * Specifies the number of milliseconds. * * @param milliseconds number of milliseconds * @return TimeSpan */
public TimeSpan withMilliseconds(final int milliseconds) { this.milliseconds = milliseconds; return this; }
Returns:days value
/** * @return days value */
public int days() { return this.days; }
Returns:hours value
/** * @return hours value */
public int hours() { return this.hours; }
Returns:minutes value
/** * @return minutes value */
public int minutes() { return this.minutes; }
Returns:seconds value
/** * @return seconds value */
public int seconds() { return this.seconds; }
Returns:mill-seconds value
/** * @return mill-seconds value */
public int milliseconds() { return this.milliseconds; }
Returns:total number of milliseconds represented by this instance
/** * @return total number of milliseconds represented by this instance */
public double totalMilliseconds() { return totalTicks() * millisecondsPerTick; }
Returns:total number of seconds represented by this instance
/** * @return total number of seconds represented by this instance */
public double totalSeconds() { return totalTicks() * secondsPerTick; }
Returns:total number of minutes represented by this instance
/** * @return total number of minutes represented by this instance */
public double totalMinutes() { return totalTicks() * minutesPerTick; }
Gets TimeSpan from given period.
Params:
  • period – duration in period format
Returns:TimeSpan
/** * Gets TimeSpan from given period. * * @param period duration in period format * @return TimeSpan */
public static TimeSpan fromPeriod(Period period) { // Normalize (e.g. move weeks to hour part) // Period p = new Period(period.toStandardDuration().getMillis()); return TimeSpan.parse((new TimeSpan() .withDays(p.getDays()) .withHours(p.getHours()) .withMinutes(p.getMinutes()) .withSeconds(p.getSeconds()) .withMilliseconds(p.getMillis())).toString()); }
Parses the TimeSpan in string format. Valid formats for TimeSpan are: [-]d\0 [-]d.hh:mm\0 [-]hh:mm\0 [-]dd.hh:mm:ss\0 [-]hh:mm:ss\0 [-]dd.hh:mm:ss:ffffffff\0 [-]hh:mm:ss:ffffffff\0
Params:
  • input – the string representation of TimeSpan
Returns:TimeSpan
/** * Parses the TimeSpan in string format. * * Valid formats for TimeSpan are: * [-]d\0 * [-]d.hh:mm\0 * [-]hh:mm\0 * [-]dd.hh:mm:ss\0 * [-]hh:mm:ss\0 * [-]dd.hh:mm:ss:ffffffff\0 * [-]hh:mm:ss:ffffffff\0 * * @param input the string representation of TimeSpan * @return TimeSpan */
public static TimeSpan parse(String input) { if (input == null) { throw new IllegalArgumentException("input cannot be null"); } final String str = input.trim(); TimeSpan timeSpan = new TimeSpan(); TokenParser parser = new TokenParser(str, str.charAt(0) == '-' ? 1 : 0); Token token = parser.nextToken(); // Empty string not allowed // token.throwIfEmpty(); int sign = str.charAt(0) == '-' ? -1 : 1; if (token.isTerminalCharNull()) { // 'dd\0' // timeSpan.withDays(toInt(token.getRawValue()) * sign); return timeSpan; } if (token.isTerminalMatched('.')) { // 'dd.hh' // timeSpan.withDays(toInt(token.getRawValue()) * sign); token = parser.nextToken(); // If '.' follows 'dd' then there must be 'hh' token // token.throwIfEmpty(); timeSpan.withHours(toInt(token.getRawValue()) * sign); } else { // 'hh' // timeSpan.withDays(0); timeSpan.withHours(toInt(token.getRawValue()) * sign); } if (timeSpan.hours() > 23) { parser.throwOutOfRange(); } // there must be ':' followed by 'dd.hh' or 'hh' // token.throwIfTerminalCharNotMatch(':'); token = parser.nextToken(); // there must be 'mm' token // token.throwIfEmpty(); timeSpan.withMinutes(toInt(token.getRawValue()) * sign); if (timeSpan.minutes() > 59) { parser.throwOutOfRange(); } if (token.isTerminalCharNull()) { // 'dd.hh:mm\0' or 'hh:mm\0' // return timeSpan; } token.throwIfTerminalCharNotMatch(':'); token = parser.nextToken(); // There must be 'ss' token // token.throwIfEmpty(); timeSpan.withSeconds(toInt(token.getRawValue()) * sign); if (timeSpan.seconds() > 59) { parser.throwOutOfRange(); } if (token.isTerminalCharNull()) { // 'dd.hh:mm:ss\0' or 'hh:mm:ss\0' // return timeSpan; } token.throwIfTerminalCharNotMatch('.'); token = parser.nextToken(); // There must be 'fraction' token // token.throwIfEmpty(); String milliStr = "." + token.getRawValue(); if (milliStr.length() > 8) { parser.throwOutOfRange(); } int milliSeconds = (int) (Double.parseDouble(milliStr) * 1000); timeSpan.withMilliseconds(milliSeconds * sign); // There should not be more tokens // if (!token.isTerminalCharNull()) { TokenParser.throwParseError(); } return timeSpan; }
Returns:TimeSpan in [-][d.]hh:mm:ss[.fffffff] format
/** * @return TimeSpan in [-][d.]hh:mm:ss[.fffffff] format */
public String toString() { long totalTicks = totalTicks(); int days = (int) Math.abs(totalTicks / ticksPerDay); StringBuilder stringBuilder = new StringBuilder(); // Sign part // if (totalTicks < 0) { stringBuilder.append("-"); } // Days part // if (days != 0) { stringBuilder.append(String.format("%d.", days)); } long remainingTicks = Math.abs(totalTicks % ticksPerDay); int hours = (int) (remainingTicks / ticksPerHour % 24); int minutes = (int) (remainingTicks / ticksPerMinute % 60); int seconds = (int) (remainingTicks / ticksPerSecond % 60); // Hour, Minute, Second part // stringBuilder.append(String.format("%02d:%02d:%02d", hours, minutes, seconds)); int fraction = (int) (remainingTicks % ticksPerSecond); // Fraction part // if (fraction != 0) { stringBuilder.append(String.format(".%07d", fraction)); } return stringBuilder.toString(); }
Returns:total number of ticks represented by this instance
/** * @return total number of ticks represented by this instance */
private long totalTicks() { long totalMilliSeconds = ((long) days * 3600 * 24 + (long) hours * 3600 + (long) minutes * 60 + seconds) * 1000 + milliseconds; return totalMilliSeconds * ticksPerMillisecond; } private static int toInt(String intStr) { return Integer.parseInt(intStr); } }
Parses the TimeSpan in string format.
/** * Parses the TimeSpan in string format. */
class TokenParser { private final String str; private final int startIndex; private Func0<Token> nextTokenProvider; TokenParser(final String str, final int startIndex) { this.str = str; this.startIndex = startIndex; this.nextTokenProvider = nextTokenProvider(); }
Gets the next token from the string represented in TimeSpan format. Each token is a number followed by single char. For the last token-character will be null. This method return an empty token if there is no more token left in the string.
Returns:next token
/** * Gets the next token from the string represented in TimeSpan format. * Each token is a number followed by single char. For the last token-character * will be null. This method return an empty token if there is no more token left * in the string. * * @return next token */
Token nextToken() { return nextTokenProvider.call(); } static void throwParseError() { throw new IllegalArgumentException("String was not recognized as a valid TimeSpan"); } static void throwOutOfRange() { throw new IllegalArgumentException("The TimeSpan could not be parsed because at least one of the numeric components is out of range or contains too many digits"); } private Func0<Token> nextTokenProvider() { return new Func0<Token>() { int currentIndex = startIndex; int length = str.length(); @Override public Token call() { if (currentIndex >= length) { return new Token(null, null); } StringBuilder builder = new StringBuilder(); while (currentIndex < length && Character.isDigit(str.charAt(currentIndex))) { builder.append(str.charAt(currentIndex)); currentIndex++; } String val = builder.toString(); if (val == null) { throwParseError(); } try { Integer.parseInt(val); } catch (Exception ex) { throwOutOfRange(); } if (currentIndex < length) { return new Token(val, str.charAt(currentIndex++)); } return new Token(val, null); } }; } }
Represents a token (part of) a TimeSpan represented in string format.
/** * Represents a token (part of) a TimeSpan represented in string format. */
class Token { private String rawValue; private Character terminalChar; Token(String rawValue, Character terminalChar) { this.rawValue = rawValue; this.terminalChar = terminalChar; } String getRawValue() { return this.rawValue; } boolean isTerminalMatched(Character charToMatch) { if (terminalChar == null && charToMatch == null) { return true; } return terminalChar != null && charToMatch != null && terminalChar.equals(charToMatch); } boolean isTerminalCharNull() { return isTerminalMatched(null); } void throwIfTerminalCharNotMatch(Character matchChar) { if (!isTerminalMatched(matchChar)) { throw new IllegalArgumentException("String was not recognized as a valid TimeSpan"); } } void throwIfEmpty() { if (isEmpty()) { throw new IllegalArgumentException("String was not recognized as a valid TimeSpan"); } } boolean isEmpty() { return this.rawValue == null && this.terminalChar == null; } }