在W3C XML Schema 1.0规范中定义的时间跨度的不可变表示。
Duration对象表示一个公历时间段,由六个字段(年、月、日、小时、分钟和秒)加上一个符号(+/-)字段组成。
前五个字段具有非负(>=0)整数或空值(表示该字段未设置),秒字段具有非负小数或空值。负号表示负持续时间。
该类提供了许多方法,使其易于用于XML Schema 1.0的持续时间数据类型与勘误。
顺序关系
Duration对象只有部分顺序,其中两个值A和B可能是:
- A<B(A比B短)
- A>B(A比B长)
- A==B(A和B持续时间相同)
- A<>B(A和B之间的比较不确定)
例如,30天无法与一个月有意义地进行比较。 compare(Duration duration)
方法实现了这种关系。
有关Duration
对象之间顺序关系的详细信息,请参阅isLongerThan(Duration)
方法。
持续时间操作
该类提供了一组基本算术操作,如加法、减法和乘法。由于持续时间没有完全顺序,某些操作的组合可能会失败。例如,无法从1个月中减去15天。请查看这些方法的javadoc,了解可能发生这种情况的详细条件。
此外,不提供将持续时间除以数字的操作,因为Duration
类只能处理有限精度的十进制数。例如,无法表示1秒除以3。
但是,您可以通过乘以数字(如0.3或0.333)来替代除以3。
允许值的范围
因为Duration
的一些操作依赖于Calendar
,即使Duration
可以保存非常大或非常小的值,某些方法可能无法在这些Duration
上正确工作。受影响的方法记录了它们对Calendar
的依赖性。
- 自版本:
- 1.5
- 参见:
-
Constructor Summary
-
Method Summary
Modifier and TypeMethodDescriptionabstract Duration
计算一个新的持续时间,其值为this+rhs
。abstract void
将此持续时间添加到Calendar
对象。void
将此持续时间添加到Date
对象。abstract int
与此Duration
实例的部分顺序关系比较。boolean
检查此持续时间对象是否与另一个Duration
对象具有相同的持续时间。int
getDays()
获取DAYS字段的值作为整数值,如果不存在则为0。abstract Number
getField
(DatatypeConstants.Field field) 获取字段的值。int
getHours()
获取HOURS字段的值作为整数值,如果不存在则为0。int
获取MINUTES字段的值作为整数值,如果不存在则为0。int
获取MONTHS字段的值作为整数值,如果不存在则为0。int
获取SECONDS字段的值作为整数值,如果不存在则为0。abstract int
getSign()
返回此持续时间的符号为-1、0或1。long
getTimeInMillis
(Calendar startInstant) 返回持续时间的长度(毫秒)。long
getTimeInMillis
(Date startInstant) 返回持续时间的长度(毫秒)。返回此实例映射到的XML Schema日期/时间类型的名称。int
getYears()
获取此Duration
的年份值作为int
,如果不存在则为0
。abstract int
hashCode()
返回与equals方法定义一致的哈希码。boolean
isLongerThan
(Duration duration) 检查此持续时间对象是否严格长于另一个Duration
对象。abstract boolean
isSet
(DatatypeConstants.Field field) 检查字段是否已设置。boolean
isShorterThan
(Duration duration) 检查此持续时间对象是否严格短于另一个Duration
对象。multiply
(int factor) 计算一个新的持续时间,其值为此持续时间值的factor
倍。abstract Duration
multiply
(BigDecimal factor) 计算一个新的持续时间,其值为此持续时间值的factor
倍。abstract Duration
negate()
返回一个新的Duration
对象,其值为-this
。abstract Duration
normalizeWith
(Calendar startTimeInstant) 通过使用特定时间点将年份和月份字段转换为天数字段。计算一个新的持续时间,其值为this-rhs
。toString()
返回此Duration Object
的String
表示。
-
Constructor Details
-
Duration
public Duration()默认无参数构造函数。注意:始终使用
DatatypeFactory
来构造Duration
的实例。此类上的构造函数无法保证生成具有一致状态的对象,并且可能在将来被移除。
-
-
Method Details
-
getXMLSchemaType
返回此实例映射到的XML Schema日期/时间类型的名称。类型是基于已设置字段计算的,即isSet(DatatypeConstants.Field field)
==true
。XML Schema 1.0日期/时间数据类型所需的字段。
(所有日期/时间数据类型的时区都是可选的)数据类型 年 月 日 小时 分钟 秒 DatatypeConstants.DURATION
X X X X X X DatatypeConstants.DURATION_DAYTIME
X X X X DatatypeConstants.DURATION_YEARMONTH
X X - 返回:
-
以下常量之一:
DatatypeConstants.DURATION
、DatatypeConstants.DURATION_DAYTIME
或DatatypeConstants.DURATION_YEARMONTH
。 - 抛出:
-
IllegalStateException
- 如果设置字段的组合不匹配XML Schema日期/时间数据类型之一。
-
getSign
public abstract int getSign()返回此持续时间的符号为-1、0或1。- 返回:
- 如果此持续时间为负,则返回-1,如果持续时间为零,则返回0,如果持续时间为正,则返回1。
-
getYears
public int getYears()获取此Duration
的年份值作为int
,如果不存在则为0
。getYears()
是getField(DatatypeConstants.YEARS)
的便利方法。由于返回值是一个
int
,对于年份超出int
范围的Duration
,可能会返回不正确的值。使用getField(DatatypeConstants.YEARS)
以避免可能的精度丢失。- 返回:
-
如果年份字段存在,则将其值作为
int
返回,否则返回0
。
-
getMonths
public int getMonths()获取MONTHS字段的值作为整数值,如果不存在则为0。此方法与getYears()
类似,只是此方法适用于MONTHS字段。- 返回:
-
此
Duration
的月份。
-
getDays
public int getDays()获取DAYS字段的值作为整数值,如果不存在则为0。此方法与getYears()
类似,只是此方法适用于DAYS字段。- 返回:
-
此
Duration
的天数。
-
getHours
public int getHours()获取HOURS字段的值作为整数值,如果不存在则为0。此方法与getYears()
类似,只是此方法适用于HOURS字段。- 返回:
-
此
Duration
的小时数。
-
getMinutes
public int getMinutes()获取MINUTES字段的值作为整数值,如果不存在则为0。此方法与getYears()
类似,只是此方法适用于MINUTES字段。- 返回:
-
此
Duration
的分钟数。
-
getSeconds
public int getSeconds()获取SECONDS字段的值作为整数值,如果不存在则为0。此方法与getYears()
类似,只是此方法适用于SECONDS字段。- 返回:
- 整数值中的秒数。秒的小数部分将被舍弃(例如,如果实际值为2.5,则此方法返回2)。
-
getTimeInMillis
返回持续时间的毫秒长度。如果秒字段的位数多于毫秒位数,那么这些位数将被简单地丢弃(或者换句话说,四舍五入为零)。例如,对于任何日历值
x
,new Duration("PT10.00099S").getTimeInMills(x) == 10000
new Duration("-PT10.00099S").getTimeInMills(x) == -10000
请注意,此方法使用
addTo(Calendar)
方法,该方法可能无法正确处理其字段中具有非常大值的Duration
对象。有关详细信息,请参阅addTo(Calendar)
方法。- 参数:
-
startInstant
- 月份/年份的长度会变化。startInstant
用于消除这种差异。具体而言,此方法返回startInstant
和startInstant+duration
之间的差异。 - 返回:
-
startInstant
和startInstant
加上此Duration
之间的毫秒数。 - 抛出:
-
NullPointerException
- 如果startInstant
参数为 null。
-
getTimeInMillis
返回持续时间的毫秒长度。如果秒字段的位数多于毫秒位数,那么这些位数将被简单地丢弃(或者换句话说,四舍五入为零)。例如,对于任何
Date
值x
,new Duration("PT10.00099S").getTimeInMills(x) == 10000
new Duration("-PT10.00099S").getTimeInMills(x) == -10000
请注意,此方法使用
addTo(Date)
方法,该方法可能无法正确处理其字段中具有非常大值的Duration
对象。有关详细信息,请参阅addTo(Date)
方法。- 参数:
-
startInstant
- 月份/年份的长度会变化。startInstant
用于消除这种差异。具体而言,此方法返回startInstant
和startInstant+duration
之间的差异。 - 返回:
-
startInstant
和startInstant
加上此Duration
之间的毫秒数。 - 抛出:
-
NullPointerException
- 如果startInstant
参数为 null。 - 另请参阅:
-
getField
获取字段的值。持续时间对象的字段可能包含任意大的值。因此,此方法旨在返回一个Number
对象。对于YEARS、MONTHS、DAYS、HOURS和MINUTES,返回的数字将是非负整数。对于秒,返回的数字可能是非负的十进制值。- 参数:
-
field
- 六个字段常量之一(YEARS、MONTHS、DAYS、HOURS、MINUTES或SECONDS)。 - 返回:
-
如果指定字段存在,则此方法返回一个非空的非负
Number
对象,表示其值。如果不存在,则返回null。对于YEARS、MONTHS、DAYS、HOURS和MINUTES,此方法返回一个BigInteger
对象。对于SECONDS,此方法返回一个BigDecimal
。 - 抛出:
-
NullPointerException
- 如果field
为null
。
-
isSet
检查字段是否已设置。持续时间对象的字段可能存在,也可能不存在。此方法可用于测试字段是否存在。- 参数:
-
field
- 六个字段常量之一(YEARS、MONTHS、DAYS、HOURS、MINUTES或SECONDS)。 - 返回:
- 如果字段存在,则返回true。如果不存在,则返回false。
- 抛出:
-
NullPointerException
- 如果字段参数为null。
-
add
计算一个新的持续时间,其值为this+rhs
。例如,
"1 day" + "-3 days" = "-2 days" "1 year" + "1 day" = "1 year and 1 day" "-(1 hour,50 minutes)" + "-20 minutes" = "-(1 hours,70 minutes)" "15 hours" + "-3 days" = "-(2 days,9 hours)" "1 year" + "-1 day" = IllegalStateException
由于没有有意义地从一个月中减去一天的方法,因此在某些情况下,操作会导致
IllegalStateException
异常。形式上,计算定义如下。
首先,我们可以假设要添加的两个
Duration
都是正数,而不失一般性(即,(-X)+Y=Y-X
,X+(-Y)=X-Y
,(-X)+(-Y)=-(X+Y)
)两个正数
Duration
的加法简单地定义为逐字段相加,其中缺失的字段被视为0。如果两个输入
Duration
的相应字段都未设置,则生成的Duration
的字段将未设置。请注意,如果
lhs.signum()*rhs.signum()!=-1
或两者都已标准化,则lhs.add(rhs)
将始终成功。- 参数:
-
rhs
- 要添加到此Duration
的Duration
- 返回:
-
非空有效的
Duration
对象。 - 抛出:
-
NullPointerException
- 如果rhs参数为null。 -
IllegalStateException
- 如果两个持续时间无法有意义地相加。例如,将负一天加到一个月中会导致此异常。 - 另请参阅:
-
addTo
将此持续时间添加到Calendar
对象。按照YEARS、MONTHS、DAYS、HOURS、MINUTES、SECONDS和MILLISECONDS的顺序调用
Calendar.add(int,int)
。因为Calendar
类使用int来保存值,所以在某些情况下,此方法可能无法正确工作(例如,如果字段的值超出int的范围)。此外,由于此持续时间类是一个公历持续时间,如果给定的
Calendar
对象基于其他日历系统,则此方法将无法正确工作。此
Duration
对象超出毫秒的任何小数部分将被简单地忽略。例如,如果此持续时间为"P1.23456S",则1将添加到SECONDS,234将添加到MILLISECONDS,其余部分将不使用。请注意,因为
Calendar.add(int, int)
使用int
,因此在字段中的值超出int
范围的Duration
将导致给定的Calendar
溢出/下溢。XMLGregorianCalendar.add(Duration)
提供了与此方法相同的基本操作,同时避免了溢出/下溢问题。- 参数:
-
calendar
- 将要修改其值的日历对象。 - 抛出:
-
NullPointerException
- 如果calendar参数为null。
-
addTo
将此持续时间添加到Date
对象。首先将给定日期转换为
GregorianCalendar
,然后像addTo(Calendar)
方法一样添加持续时间。然后将更新后的时间瞬间转换回
Date
对象,并用于更新给定的Date
对象。这种多余的计算是必要的,以明确确定月份和年份的持续时间。
- 参数:
-
date
- 将要修改其值的日期对象。 - 抛出:
-
NullPointerException
- 如果date参数为null。
-
subtract
计算一个新的持续时间,其值为this-rhs
。例如:
"1 day" - "-3 days" = "4 days" "1 year" - "1 day" = IllegalStateException "-(1 hour,50 minutes)" - "-20 minutes" = "-(1hours,30 minutes)" "15 hours" - "-3 days" = "3 days and 15 hours" "1 year" - "-1 day" = "1 year and 1 day"
由于无法有意义地从一个月中减去一天,因此在某些情况下操作会失败,抛出
IllegalStateException
异常。形式上,计算定义如下。首先,我们可以假设两个
Duration
都是正的而不失一般性。(即,(-X)-Y=-(X+Y)
,X-(-Y)=X+Y
,(-X)-(-Y)=-(X-Y)
)然后,逐个字段减去两个持续时间。如果任何非零字段
F
的符号与最重要字段的符号不同,则将从F
的下一个更大的单位中借用1(如果F
为负)或-1(否则)。这个过程重复进行,直到所有非零字段具有相同的符号。
如果在天字段中发生借位(换句话说,如果计算需要借用1或-1个月来补偿天数),则通过抛出
IllegalStateException
来使计算失败。- 参数:
-
rhs
- 从此Duration
中减去的Duration
。 - 返回:
-
从从此
Duration
中减去rhs
创建的新Duration
。 - 抛出:
-
IllegalStateException
- 如果两个持续时间无法有意义地相减。例如,从一个月中减去一天会导致此异常。 -
NullPointerException
- 如果rhs参数为null。 - 参见:
-
multiply
计算一个新的持续时间,其值为factor
倍于此持续时间的值。此方法提供了便利。它在功能上等同于以下代码:
multiply(new BigDecimal(String.valueOf(factor)))
- 参数:
-
factor
- 要创建新Duration
的倍数。 - 返回:
-
新的
Duration
,其长度是此Duration
的factor
倍。 - 参见:
-
multiply
计算一个新的持续时间,其值为factor
倍于此持续时间的值。例如,
"P1M"(1个月)* "12" = "P12M"(12个月) "PT1M"(1分钟)* "0.3" = "PT18S"(18秒) "P1M"(1个月)* "1.5" = IllegalStateException
由于
Duration
类是不可变的,此方法不会更改此对象的值。它只是计算一个新的Duration对象并返回它。操作将逐个字段执行,精度为
BigDecimal
。由于除秒以外的所有字段都受限于保存整数,计算产生的任何小数将向下传递到下一个较低的单位。例如,如果将“P1D”(1天)乘以“0.5”,那么它将是0.5天,将被传递到“PT12H”(12小时)。当月的分数无法有意义地传递到天,或者年到月时,这将导致抛出IllegalStateException
。例如,如果将一个月乘以0.5。为避免
IllegalStateException
,请使用normalizeWith(Calendar)
方法来移除年和月字段。- 参数:
-
factor
- 要乘以的因子 - 返回:
-
返回一个非空有效的
Duration
对象 - 抛出:
-
IllegalStateException
- 如果操作在月字段中产生分数。 -
NullPointerException
- 如果factor
参数为null
。
-
negate
返回一个新的Duration
对象,其值为-this
。由于
Duration
类是不可变的,此方法不会更改此对象的值。它只是计算一个新的Duration对象并返回它。- 返回:
-
始终返回一个非空有效的
Duration
对象。
-
normalizeWith
通过使用特定时间点将年和月字段转换为天字段。例如,给定开始时间实例“2003年7月8日,17:40:32”,一个月的持续时间将规范化为31天。
形式上,计算如下进行:
- 克隆给定的Calendar对象
- 使用
Calendar.add(int,int)
方法将年、月和天字段添加到Calendar
对象中 - 计算两个Calendar之间的毫秒差,并转换为天数,如果由于夏令时而产生余数,则将其丢弃
- 计算的天数,以及此持续时间对象的小时、分钟和秒字段用于构造一个新的Duration对象。
请注意,由于Calendar类使用
int
来保存年和月的值,如果此持续时间对象在年或月字段中具有非常大的值,则此方法可能会产生意外结果。- 参数:
-
startTimeInstant
-Calendar
参考点。 - 返回:
-
将此
Duration
的年和月转换为天数的Duration
。 - 抛出:
-
NullPointerException
- 如果startTimeInstant参数为null。
-
compare
与此Duration
实例的部分顺序关系比较。比较结果必须符合W3C XML Schema 1.0第2部分,第3.2.7.6.2节,持续时间的顺序关系。
返回:
DatatypeConstants.LESSER
如果此Duration
比duration
参数短DatatypeConstants.EQUAL
如果此Duration
等于duration
参数DatatypeConstants.GREATER
如果此Duration
比duration
参数长DatatypeConstants.INDETERMINATE
如果无法确定一个明确的部分顺序关系
- 参数:
-
duration
- 要比较的持续时间 - 返回:
-
this Duration
与duration
参数之间的关系为DatatypeConstants.LESSER
、DatatypeConstants.EQUAL
、DatatypeConstants.GREATER
或DatatypeConstants.INDETERMINATE
。 - 抛出:
-
UnsupportedOperationException
- 如果底层实现无法合理处理请求,例如,W3C XML Schema允许任意大/小/精确值,请求可能超出实现的能力。 -
NullPointerException
- 如果duration
为null
。 - 参见:
-
isLongerThan
检查此持续时间对象是否严格长于另一个Duration
对象。仅当X > Y时,持续时间X才“长于”Y,如XML Schema 1.0规范的第3.2.6.2节中所定义。
例如,“P1D”(一天)>“PT12H”(12小时)和“P2Y”(两年)>“P23M”(23个月)。
- 参数:
-
duration
- 要测试此Duration
是否长于的Duration
。 - 返回:
- 如果此对象表示的持续时间长于给定的持续时间,则为true。否则为false。
- 抛出:
-
UnsupportedOperationException
- 如果底层实现无法合理处理请求,例如,W3C XML Schema允许任意大/小/精确值,请求可能超出实现的能力。 -
NullPointerException
- 如果duration
为null。 - 参见:
-
isShorterThan
检查此持续时间对象是否严格短于另一个Duration
对象。- 参数:
-
duration
- 要与此Duration
进行比较的Duration
。 - 返回:
-
如果
duration
参数比此Duration
短,则返回true
,否则返回false
。 - 抛出:
-
UnsupportedOperationException
- 如果底层实现无法合理处理请求,例如W3C XML Schema允许任意大/小/精确值,请求可能超出实现的能力范围。 -
NullPointerException
- 如果duration
为null。 - 参见:
-
equals
检查此持续时间对象是否与另一个Duration
对象具有相同的持续时间。例如,"P1D"(1天)等于"PT24H"(24小时)。
如果且仅当XML Schema 1.0规范的第3.2.6.2节中指定的所有测试时间点的时间瞬时t+X和t+Y相同时,持续时间X等于Y。
请注意,有些情况下,两个
Duration
是相互“不可比较”的,比如一个月和30天。例如,!new Duration("P1M").isShorterThan(new Duration("P30D")) !new Duration("P1M").isLongerThan(new Duration("P30D")) !new Duration("P1M").equals(new Duration("P30D"))
- 覆盖:
-
equals
在类中Object
- 参数:
-
duration
- 要与此Duration
进行比较的对象。 - 返回:
-
如果此持续时间与
duration
具有相同长度,则返回true
。如果duration
为null
,不是Duration
对象,或其长度与此持续时间不同,则返回false
。 - 抛出:
-
UnsupportedOperationException
- 如果底层实现无法合理处理请求,例如W3C XML Schema允许任意大/小/精确值,请求可能超出实现的能力范围。 - 参见:
-
hashCode
public abstract int hashCode()返回与equals方法定义一致的哈希码。 -
toString
返回此Duration Object
的String
表示形式。结果按照XML Schema 1.0规范进行格式化,并且始终可以稍后解析为等效的
Duration Object
,方法是通过DatatypeFactory.newDuration(String lexicalRepresentation)
。形式上,对于任何
Duration
Object
x,以下内容成立:new Duration(x.toString()).equals(x)
-