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
- 参见:
-
构造方法总结
构造方法 -
方法总结
修饰符和类型方法描述abstract 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 架构日期/时间类型的名称。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()
返回值为-this
的新Duration
对象。abstract Duration
normalizeWith
(Calendar startTimeInstant) 以特定时刻为参考点,将年月字段转换为天字段。计算值为this-rhs
的新持续时间。toString()
返回此Duration Object
的String
表示。
-
构造方法详细信息
-
Duration
public Duration()默认无参数构造方法。注意:始终使用
DatatypeFactory
构造Duration
的实例。此类的构造函数不能保证生成状态一致的对象,将来可能会被删除。
-
-
方法详情
-
getXMLSchemaType
返回此实例映射到的 XML 架构日期/时间类型的名称。类型是根据设置的字段计算的,即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 架构日期/时间数据类型之一不匹配。
-
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
参数为空。
-
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 参数为空。- 参见:
-
getField
获取字段的值。 duration 对象的字段可以包含任意大的值。因此,此方法旨在返回一个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。)- 返回:
- 如果该字段存在,则为真。如果不是,则为假。
- 抛出:
NullPointerException
- 如果字段参数为空。
-
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
由于无法从 1 个月中有意义地减去 1 天,因此在
IllegalStateException
中有时会出现操作失败的情况。形式上,计算定义如下。
首先,我们可以假设要添加的两个
Duration
都是正的而不失一般性(即(-X)+Y=Y-X
,X+(-Y)=X-Y
,(-X)+(-Y)=-(X+Y)
)添加两个正
Duration
s 被简单地定义为逐字段添加,其中缺少的字段被视为 0。当且仅当两个输入
Duration
的相应字段未设置时,结果Duration
的字段将被取消设置。请注意,如果
lhs.signum()*rhs.signum()!=-1
或两者均已标准化,则lhs.add(rhs)
将始终成功。- 参数:
rhs
-Duration
添加到此Duration
- 返回:
- 非 null 有效 Duration 对象。
- 抛出:
NullPointerException
- 如果 rhs 参数为空。IllegalStateException
- 如果两个持续时间不能有意义地相加。例如,将负的一天添加到一个月会导致此异常。- 参见:
-
addTo
将此持续时间添加到Calendar
对象。如果存在这些字段,则按年、月、日、小时、分钟、秒和毫秒的顺序调用
Calendar.add(int,int)
。因为Calendar
类使用 int 来保存值,所以在某些情况下此方法将无法正常工作(例如,如果字段的值超出 int 的范围。)此外,由于此持续时间类是公历持续时间,如果给定的
Calendar
对象基于其他一些日历系统,则此方法将无法正常工作。此
Duration
对象的任何超过毫秒的小数部分都将被忽略。比如这个时长是“P1.23456S”,那么SECONDS加1,MILLISECONDS加234,其余不用。请注意,因为
Calendar.add(int, int)
使用的是int
,所以Duration
的字段中的值超出int
的范围将导致给定的Calendar
上溢/下溢。XMLGregorianCalendar.add(Duration)
提供与此方法相同的基本操作,同时避免上溢/下溢问题。- 参数:
calendar
- 一个日历对象,其值将被修改。- 抛出:
NullPointerException
- 如果日历参数为空。
-
addTo
将此持续时间添加到Date
对象。给定的日期首先转换为
GregorianCalendar
,然后像addTo(Calendar)
方法一样添加持续时间。然后将更新后的时间转换回
Date
对象并用于更新给定的Date
对象。这种有点多余的计算对于明确确定月和年的持续时间是必要的。
- 参数:
date
- 一个日期对象,其值将被修改。- 抛出:
NullPointerException
- 如果日期参数为空。
-
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"
由于无法从 1 个月中有意义地减去 1 天,因此在
IllegalStateException
中有时会出现操作失败的情况。形式上,计算定义如下。首先,我们可以假设两个
Duration
都是正的而不失一般性。 (即,(-X)-Y=-(X+Y)
、X-(-Y)=X+Y
、(-X)-(-Y)=-(X-Y)
)然后逐场减去两个持续时间。如果任何非零字段
F
的符号与最高有效字段的符号不同,则 1(如果F
为负)或 -1(否则)将从F
的下一个更大单元借用。重复此过程,直到所有非零字段都具有相同的符号。
如果在天数字段中发生借用(换句话说,如果计算需要借用 1 或 -1 个月来补偿天数),则计算将失败并抛出
IllegalStateException
。- 参数:
rhs
-Duration
从这个Duration
中减去。- 返回:
-
从这个
Duration
中减去rhs
创建新的Duration
。 - 抛出:
IllegalStateException
- 如果不能有意义地减去两个持续时间。例如,从一个月中减去一天会导致此异常。NullPointerException
- 如果 rhs 参数为空。- 参见:
-
multiply
计算一个新的持续时间,其值是此持续时间值的factor
倍。提供此方法是为了方便。它在功能上等同于以下代码:
multiply(new BigDecimal(String.valueOf(factor)))
- 参数:
factor
- 要创建的新Duration
的倍数。- 返回:
-
新的
Duration
比这个Duration
长factor
倍。 - 参见:
-
multiply
计算一个新的持续时间,其值是此持续时间值的factor
倍。例如,
"P1M" (1 month) * "12" = "P12M" (12 months) "PT1M" (1 min) * "0.3" = "PT18S" (18 seconds) "P1M" (1 month) * "1.5" = IllegalStateException
由于
Duration
类是不可变的,因此此方法不会更改此对象的值。它只是计算一个新的 Duration 对象并返回它。该操作将逐字段执行,精度为
BigDecimal
。由于除秒之外的所有字段都被限制为包含整数,因此计算产生的任何分数都将向下一个较低的单位进行。例如,如果您将“P1D”(1 天)乘以“0.5”,则为 0.5 天,将向下结转为“PT12H”(12 小时)。当月份的小数部分无法有意义地向下计算为天数或年份为月份时,这将导致抛出IllegalStateException
。例如,如果您将 1 个月乘以 0.5。为避免
IllegalStateException
,请使用normalizeWith(Calendar)
方法删除年和月字段。- 参数:
factor
- 乘以- 返回:
-
返回一个非空的有效
Duration
对象 - 抛出:
IllegalStateException
- 如果操作在月份字段中产生分数。NullPointerException
- 如果factor
参数为null
。
-
negate
返回值为-this
的新Duration
对象。由于
Duration
类是不可变的,因此此方法不会更改此对象的值。它只是计算一个新的 Duration 对象并返回它。- 返回:
-
总是返回一个非空的有效
Duration
对象。
-
normalizeWith
以特定时刻为参考点,将年月字段转换为天字段。例如,给定开始时间实例“2003 年 7 月 8 日,17:40:32”,一个月的持续时间标准化为 31 天。
形式上,计算如下:
- 给定的日历对象被克隆
- 年、月和日字段将使用
Calendar.add(int,int)
方法添加到Calendar
对象 - 两个日历之间的差异以毫秒为单位计算并转换为天,如果由于夏令时而出现余数,则将其丢弃
- 计算的天数以及此持续时间对象的小时、分钟和秒字段用于构造新的持续时间对象。
请注意,由于 Calendar 类使用
int
来保存年和月的值,如果此持续时间对象在年或月字段中保存非常大的值,则此方法可能会产生意外结果。- 参数:
startTimeInstant
-Calendar
参考点。- 返回:
Duration
年和月本Duration
为天。- 抛出:
NullPointerException
- 如果 startTimeInstant 参数为空。
-
compare
与此Duration
实例的偏序关系比较。比较结果必须符合W3C XML Schema 1.0 Part 2, Section 3.2.7.6.2, Order relation on duration。
返回:
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 模式允许任意大/小/精确值,则请求可能超出实现能力。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
。- 返回:
- 如果此对象表示的持续时间长于给定的持续时间,则为真。否则为假。
- 抛出:
UnsupportedOperationException
- 如果底层实现无法合理地处理请求,例如 W3C XML 模式允许任意大/小/精确值,则请求可能超出实现能力。NullPointerException
- 如果duration
为空。- 参见:
-
isShorterThan
检查此持续时间对象是否严格短于另一个Duration
对象。- 参数:
duration
-Duration
来测试这个Duration
。- 返回:
true
如果duration
参数比这个Duration
短,否则false
。- 抛出:
UnsupportedOperationException
- 如果底层实现无法合理地处理请求,例如 W3C XML 模式允许任意大/小/精确值,则请求可能超出实现能力。NullPointerException
- 如果duration
为空。- 参见:
-
equals
检查此持续时间对象是否与另一个Duration
对象具有相同的持续时间。例如,“P1D”(1 天)等于“PT24H”(24 小时)。
当且仅当时刻 t+X 和 t+Y 对于 XML 模式 1.0 规范的第 3.2.6.2 节中指定的所有测试时刻都相同时,持续时间 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
进行比较的对象。- 返回:
true
如果此持续时间与duration
的长度相同。false
如果duration
是null
,则不是Duration
对象,或者它的长度与此持续时间不同。- 抛出:
UnsupportedOperationException
- 如果底层实现无法合理地处理请求,例如 W3C XML 模式允许任意大/小/精确值,则请求可能超出实现能力。- 参见:
-
hashCode
public abstract int hashCode()返回与 equals 方法定义一致的哈希码。 -
toString
返回此Duration Object
的String
表示。结果根据 XML Schema 1.0 规范进行格式化,以后总是可以通过
DatatypeFactory.newDuration(String lexicalRepresentation)
解析回等效的Duration Object
。形式上,以下内容适用于任何
Duration
Object
x:new Duration(x.toString()).equals(x)
-