是否有 Avro 的“持续时间”逻辑类型的 API 实现?

Rus*_*ips 6 java duration avro

当前的 Apache Avro (1.8.2) 文档提到了“持续时间”逻辑类型:

持续时间逻辑类型注释大小为 12 的 Avro 固定类型,它存储三个小端无符号整数,代表不同时间粒度的持续时间。第一个以月为单位存储一个数字,第二个以天为单位存储一个数字,第三个以毫秒为单位存储一个数字。

虽然这一切都说得通,但我在 .Net 或 Java 库中都找不到实际的实现。逻辑类型文档清楚地列出了除持续时间(日期、时间毫秒、时间微秒、时间戳毫秒和时间戳微秒)之外的所有逻辑类型。

“持续时间”在我的 Avro 架构中相应定义:

{
    "type": "record",
    "name": "DataBlock",
    "fields": [
    {
        "name": "duration",
        "type": {
            "type": "fixed",
            "name": "DataBlockDuration",
            "size": 12
        }
    }]
}
Run Code Online (Sandbox Code Playgroud)

在.Net(请原谅VB)中,我必须手动序列化持续时间:

Dim ret(11) As Byte
Dim months = BitConverter.GetBytes(duration.Months)
Dim days = BitConverter.GetBytes(duration.Days)
Dim milliseconds = BitConverter.GetBytes(duration.Milliseconds)

Array.Copy(months, 0, ret, 0, 4)
Array.Copy(days, 0, ret, 4, 4)
Array.Copy(milliseconds, 0, ret, 8, 4)
Run Code Online (Sandbox Code Playgroud)

在 Java 中反序列化时,我必须通过执行以下操作转换为 org.joda.time.Period:

IntBuffer buf = ByteBuffer
                  .wrap(dataBlock.getDuration().bytes())
                  .order(ByteOrder.LITTLE_ENDIAN)
                  .asIntBuffer();

Period period = Period
                  .months(buf.get(0))
                  .withDays(buf.get(1))
                  .withMillis(buf.get(2));
Run Code Online (Sandbox Code Playgroud)

我是否遗漏了什么,或者 Avro 团队是否编写了规范而忘记实施它?似乎特别是这种数据类型必须在没有 Avro API 任何帮助的情况下实现。

Bas*_*que 2

乔达时间

\n\n

Joda -Time项目现在处于维护模式,团队建议迁移到java.time类。概念很相似,因为这两个项目都是由同一个人 Stephen Colebourne 领导的。

\n\n

java.time

\n\n

java.time框架提供两个单独的类来表示不附加到时间线的时间跨度:

\n\n
    \n
  • Period
    数年、数月、数日。
  • \n
  • Duration
    天数(与日历无关的通用 24 小时时间段)、小时、分钟、秒和小数秒(纳秒)。
  • \n
\n\n

您可以使用前两个数字作为 a Period,第三个数字作为 a Duration

\n\n
Period p = Period.ofMonths( months ).plusDays( days ) ;\nDuration d = Duration.ofMillis( millis ) ;\n
Run Code Online (Sandbox Code Playgroud)\n\n

您可能想要标准化对象的年份和月份Period。例如,“15 个月”的时间段将标准化为“1 年零 3 个月”。

\n\n
Period p = Period.ofMonths( months ).plusDays( days ).normalized() ;\n
Run Code Online (Sandbox Code Playgroud)\n\n

ISO 8601

\n\n

java.time类在解析/生成字符串时使用标准 ISO 8601 标准格式

\n\n

对于一段时间或持续时间,这意味着使用该PnYnMnDTnHnMnS格式。标记P开始,并且将T任何年-月-日与任何时-分-秒分开。例如,“P3Y6M4DT12H30M5S”表示持续时间“三年六个月四天十二小时三十分钟五秒”。

\n\n

要生成这样的字符串,只需调用toStringaPeriodDuration。要解析,请调用parse.

\n\n

Avro 中奇怪的概念

\n\n

Avro 的持续时间概念(月+天+毫秒)对我来说似乎很奇怪。最大的问题是,将年-月-日与小时-分钟-秒混合在一起很少有任何实际意义(想想看)。令人惊讶的是,追踪的是几个月而不是几年。

\n\n

org.threeten.extra.PeriodDuration

\n\n

如果您坚持要将年-月-日与小时-分钟-秒合并,请考虑将ThreeTen-Extra库添加到您的项目中。它提供一PeriodDuration堂课。

\n\n
PeriodDuration pd = PeriodDuration.of( p , d ) ;  // Pass `Period` and `Duration` objects as covered above.\n
Run Code Online (Sandbox Code Playgroud)\n\n

同样,您可能想致电normalizedStandardDaysnormalizedYears

\n\n
\n\n

关于java.time

\n\n

java.time框架内置于 Java 8 及更高版本中这些类取代了麻烦的旧遗留日期时间类,例如java.util.Date, Calendar, & SimpleDateFormat

\n\n

Joda -Time项目现在处于维护模式,建议迁移到java.time类。

\n\n

要了解更多信息,请参阅Oracle 教程。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310

\n\n

您可以直接与数据库交换java.time对象。使用与JDBC 4.2或更高版本兼容的JDBC 驱动程序。不需要字符串,不需要类。java.sql.*

\n\n

从哪里获取 java.time 类?

\n\n\n\n

ThreeTen -Extra项目通过附加类扩展了 java.time。该项目是 java.time 未来可能添加的内容的试验场。您可能会在这里找到一些有用的类,例如Interval、、、等等。YearWeekYearQuarter

\n