自定义kotlin DateTimeFormatter工具类

之前在项目代码中使用的都是SimpleDateFormat来解析和格式化时间,后来看到阿里巴巴Java技术手册中说SimpleDateFormat类是线程不安全的,不应该用static来定义。


阿里巴巴Java开发手册

然后看了看自己的代码,竟然有用static定义的SimpleDateFormat,好了,有事干了,重构,重构!

SimpleDateFormat的替代方案网上有很多,我这里就是包装了Java8的DateTimeFormatter做了一个DateUtils工具类。

既然DateTimeFormatter是不可变的,线程安全的,项目中使用到的时间格式也无非就是有限的几种,所以可以将时间格式的创建集中在DateUtils中并且整个代码运行周期只创建一次。所以这里利用枚举来创建单例模式。

enum class FormatterEnum(val format: DateTimeFormatter) {
    YYYY_MM_DD(DateTimeFormatter.ofPattern("yyyy-MM-dd")),
    YYYYMMDD(DateTimeFormatter.ofPattern("yyyyMMdd")),
    YYYY_MM_DD__HH_MM(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")),
    YYYY_MM_DD__HH_MM_SS(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")),
    YYYYMMDD__HH_MM(DateTimeFormatter.ofPattern("yyyyMMdd HH:mm")),
    YYYYMMDD__HH_MM_SS(DateTimeFormatter.ofPattern("yyyyMMdd HH:mm:ss")),
    HH_MM_SS(DateTimeFormatter.ofPattern("HH:mm:ss"))
}

如下是parse函数。因为LocalDate不能parse "2019-01-01 11:11"这种带time的时间串,LocalTime也不能parse带Date的时间串,所以这里用when来进行模式匹配。parse函数也要求两个参数dateStr、formatter格式相匹配。

fun parse(dateStr: String, formatter: FormatterEnum): Timestamp {
    when (formatter) {
        FormatterEnum.YYYY_MM_DD,
        FormatterEnum.YYYYMMDD
            -> return LocalDate.parse(dateStr, formatter.format).getTimestamp()

        FormatterEnum.YYYY_MM_DD__HH_MM,
        FormatterEnum.YYYYMMDD__HH_MM,
        FormatterEnum.YYYYMMDD__HH_MM_SS,
        FormatterEnum.YYYY_MM_DD__HH_MM_SS
            -> return LocalDateTime.parse(dateStr, formatter.format).getTimestamp()

        FormatterEnum.HH_MM_SS
            -> return LocalTime.parse(dateStr, formatter.format).getTimestamp()
    }
}

format函数

fun format(timestamp: Timestamp, formatter: FormatterEnum): String {
    return timestamp.toLocalDateTime().format(formatter.format)
}

main测试函数。这里创建了200个线程同时进行时间的解析和格式化。结果表明确实可以做到线程安全。

@JvmStatic
fun main(args: Array) {
    for (i in 1..200) {
        thread(start = true) {
            println(DateUtils.parse("2019-01-01 11:12", FormatterEnum.YYYY_MM_DD__HH_MM))
            println(DateUtils.parse("2019-01-01", FormatterEnum.YYYY_MM_DD))

            println(DateUtils.format(LocalDateTime.now().getTimestamp(), FormatterEnum.YYYY_MM_DD__HH_MM_SS))
            println(DateUtils.format(LocalDateTime.now().getTimestamp(), FormatterEnum.YYYY_MM_DD))

        }
    }
}

完整的DateUtils

package ewhine.tools

import java.sql.Timestamp
import java.time.LocalDate
import java.time.LocalDateTime
import java.time.LocalTime
import java.time.format.DateTimeFormatter
import kotlin.concurrent.thread

enum class FormatterEnum(val format: DateTimeFormatter) {
    YYYY_MM_DD(DateTimeFormatter.ofPattern("yyyy-MM-dd")),
    YYYYMMDD(DateTimeFormatter.ofPattern("yyyyMMdd")),
    YYYY_MM_DD__HH_MM(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")),
    YYYY_MM_DD__HH_MM_SS(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")),
    YYYYMMDD__HH_MM(DateTimeFormatter.ofPattern("yyyyMMdd HH:mm")),
    YYYYMMDD__HH_MM_SS(DateTimeFormatter.ofPattern("yyyyMMdd HH:mm:ss")),
    HH_MM_SS(DateTimeFormatter.ofPattern("HH:mm:ss"))
}

object DateUtils {

    fun parse(dateStr: String, formatter: FormatterEnum): Timestamp {
        when (formatter) {
            FormatterEnum.YYYY_MM_DD,
            FormatterEnum.YYYYMMDD
                -> return LocalDate.parse(dateStr, formatter.format).getTimestamp()

            FormatterEnum.YYYY_MM_DD__HH_MM,
            FormatterEnum.YYYYMMDD__HH_MM,
            FormatterEnum.YYYYMMDD__HH_MM_SS,
            FormatterEnum.YYYY_MM_DD__HH_MM_SS
                -> return LocalDateTime.parse(dateStr, formatter.format).getTimestamp()

            FormatterEnum.HH_MM_SS
                -> return LocalTime.parse(dateStr, formatter.format).getTimestamp()
        }
    }

    fun format(timestamp: Timestamp, formatter: FormatterEnum): String {
        return timestamp.toLocalDateTime().format(formatter.format)
    }



    @JvmStatic
    fun main(args: Array) {
        for (i in 1..200) {
            thread(start = true) {
                println(DateUtils.parse("2019-01-01 11:12", FormatterEnum.YYYY_MM_DD__HH_MM))
                println(DateUtils.parse("2019-01-01", FormatterEnum.YYYY_MM_DD))

                println(DateUtils.format(LocalDateTime.now().getTimestamp(), FormatterEnum.YYYY_MM_DD__HH_MM_SS))
                println(DateUtils.format(LocalDateTime.now().getTimestamp(), FormatterEnum.YYYY_MM_DD))

            }
        }
    }
}

对了,上面的代码还使用了几个扩展函数


fun LocalDateTime.getTimestamp(): Timestamp {
    return Timestamp.valueOf(this)
}

fun LocalDate.getTimestamp(): Timestamp {
    return Timestamp.valueOf(this.atStartOfDay())
}

fun LocalTime.getTimestamp(): Timestamp {
    return Timestamp.valueOf(this.atDate(LocalDate.now()))
}

你可能感兴趣的:(自定义kotlin DateTimeFormatter工具类)