【问题标题】:Joda-Time: convert SimpleDateFormat pattern to DateTimeFormat.forPatternJoda-Time:将 SimpleDateFormat 模式转换为 DateTimeFormat.forPattern
【发布时间】:2015-12-17 15:32:19
【问题描述】:

我正在尝试修改一些代码以使用Joda-Time 而不是java.sql.Timestamp

目前代码使用Threadlocal和SimpleDateFormat:

 public static final ThreadLocal<DateFormat> FORMAT_TIMESTAMP = new ThreadLocal<DateFormat>() {
    @Override
    protected DateFormat initialValue() {
        return new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX");
    }
};

public static String format(Timestamp timestamp) {
    return FORMAT_TIMESTAMP.get().format(timestamp);
}

我的理解是Joda-time是线程安全的,所以不用ThreadLocal

考虑到这一点,我将代码修改为:

 public static String format(Instant timestamp) {

    Instant formated = Instant.parse(timestamp.toString(), DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ssXXX"));

    return formated.toString();
}

如果我想稍后在代码中将值插入数据库,我计划使用this 方法。

假设我以正确的方式进行此操作,是否可以像

一样格式化 DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ssXXX")

SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX")

目前我收到Invalid format 异常

【问题讨论】:

  • 我不明白。在您的第一个示例中,您是 formatting Timestamp。在您的第二个示例中,您尝试将Timestamp#toString 创建的String 解析为Instant 实例,然后返回Instant#toString 结果(这可能与DateTimeFormat 的格式不同。DateTimeFormat 确实如此没有X 模式字符。只需使用DateTimeFormat#print(timestamp.getTime())。我没有注意到timestamp 在您的第二个示例中是Instant。Timestamp 发生了什么?
  • 对不起,这是我犯的一个愚蠢的错误

标签: java jodatime thread-local sql-timestamp


【解决方案1】:

X 未被 Joda 识别。将 XXX 替换为 ZZ 应该可以满足您的需要。

因为DateTimeFormat 是线程安全的,所以可以跨线程共享。所以你的代码可能是这样的:

private static final DateTimeFormatter FORMAT_TIMESTAMP =
                                      DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ssZZ");

public static String format(Instant timestamp) {
    return FORMAT_TIMESTAMP.print(timestamp);
}

【讨论】:

    【解决方案2】:

    tl;博士

    • 无需为标准输入定义格式模式。
    • 直接解析成 java.time 对象。

    例子……

    // offset-from-UTC
    OffsetDateTime.parse( "2016-01-23T12:34:56.123456789-07:00" ) 
    

    …

    // Z = Zulu = UTC
    Instant.parse( "2016-01-23T12:34:56.123456789Z" )  
    

    …

    // ISO 8601 format extended with time zone name appended in square brackets.
    ZonedDateTime.parse( "2016-01-23T12:34:56.123456789-05:30[Asia/Kolkata]" )  
    

    详情

    Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。

    java.time

    不需要ThreadLocal,因为java.time 类本身就是thread-safe,因为它们是immutable objects。

    在 java.time 类中默认使用日期时间值的标准 ISO 8601 格式。因此通常不需要为此类输入指定格式模式。

    Instant

    Instant 类表示UTC 中时间轴上的时刻,分辨率为nanoseconds(最多九 (9) 位小数)。

    Instant.parse方法可以解析以Z结尾的标准输入字符串,是Zulu的缩写,意思是UTC。

    Instant instant = Instant.parse( 
        "2016-01-23T12:34:56.123456789Z" );
    

    OffsetDateTime

    对于包含特定offset-from-UTC 的标准输入字符串,请使用OffsetDateTime 类及其parse 方法。

    OffsetDateTime odt = OffsetDateTime.parse( 
        "2016-01-23T12:34:56.123456789-07:00" );
    

    ZonedDateTime

    ZonedDateTime 类及其toString 方法通过在方括号中附加名称来生成格式超出 ISO 8601 格式的字符串。这是明智的,因为time zone 不仅仅是offset-from-UTC。时区是一个偏移量加上一组用于处理异常的规则,例如Daylight Saving Time (DST)。

    这个类可以解析和生成这样的字符串。

    ZonedDateTime zdt = ZonedDateTime.parse( 
        "2016-01-23T12:34:56.123456789-05:30[Asia/Kolkata]" ) ;
    

    DateTimeFormatter

    对于非标准字符串格式,在 Stack Overflow 中搜索 java.time.format.DateTimeFormatter 类。

    数据库

    要通过支持 JDBC 4.2 或更高版本的 JDBC 驱动程序将此值发送到数据库,请使用 PreparedStatement::setObject 方法和用于获取的 ResultSet::getObject 方法。

    myPreparedStatement.setObject( … , instant );
    

    如果您的驱动程序不符合要求,请退回到转换为旧的 java.sql 类型。查看添加到旧类中的new conversion methods。

    java.sql.Timestamp ts = java.sql.Timestamp.from( instant );
    

    关于java.time

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

    Joda-Time 项目现在位于maintenance mode,建议迁移到 java.time。

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

    从哪里获得 java.time 类?

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-03-04
      • 1970-01-01
      • 2011-02-12
      • 1970-01-01
      • 2015-05-15
      • 1970-01-01
      • 2020-06-24
      相关资源
      最近更新 更多