写python程序最佳实践_最佳实践

由于Java提供了新旧两套日期和时间的API,除非涉及到遗留代码,否则我们应该坚持使用新的API。

如果需要与遗留代码打交道,如何在新旧API之间互相转换呢?

旧API转新API

如果要把旧式的Date或Calendar转换为新API对象,可以通过toInstant()方法转换为Instant对象,再继续转换为ZonedDateTime:

// Date -> Instant:

Instant ins1 = new Date().toInstant();

// Calendar -> Instant -> ZonedDateTime:

Calendar calendar = Calendar.getInstance();

Instant ins2 = calendar.toInstant();

ZonedDateTime zdt = ins2.atZone(calendar.getTimeZone().toZoneId());

从上面的代码还可以看到,旧的TimeZone提供了一个toZoneId(),可以把自己变成新的ZoneId。

新API转旧API

如果要把新的ZonedDateTime转换为旧的API对象,只能借助long型时间戳做一个“中转”:

// ZonedDateTime -> long:

ZonedDateTime zdt = ZonedDateTime.now();

long ts = zdt.toEpochSecond() * 1000;

// long -> Date:

Date date = new Date(ts);

// long -> Calendar:

Calendar calendar = Calendar.getInstance();

calendar.clear();

calendar.setTimeZone(TimeZone.getTimeZone(zdt.getZone().getId()));

calendar.setTimeInMillis(zdt.toEpochSecond() * 1000);

从上面的代码还可以看到,新的ZoneId转换为旧的TimeZone,需要借助ZoneId.getId()返回的String完成。

在数据库中存储日期和时间

除了旧式的java.util.Date,我们还可以找到另一个java.sql.Date,它继承自java.util.Date,但会自动忽略所有时间相关信息。这个奇葩的设计原因要追溯到数据库的日期与时间类型。

在数据库中,也存在几种日期和时间类型:

DATETIME:表示日期和时间;

DATE:仅表示日期;

TIME:仅表示时间;

TIMESTAMP:和DATETIME类似,但是数据库会在创建或者更新记录的时候同时修改TIMESTAMP。

在使用Java程序操作数据库时,我们需要把数据库类型与Java类型映射起来。下表是数据库类型与Java新旧API的映射关系:

数据库对应Java类(旧)对应Java类(新)

DATETIMEjava.util.DateLocalDateTime

DATEjava.sql.DateLocalDate

TIMEjava.sql.TimeLocalTime

TIMESTAMPjava.sql.TimestampLocalDateTime

实际上,在数据库中,我们需要存储的最常用的是时刻(Instant),因为有了时刻信息,就可以根据用户自己选择的时区,显示出正确的本地时间。所以,最好的方法是直接用长整数long表示,在数据库中存储为BIGINT类型。

通过存储一个long型时间戳,我们可以编写一个timestampToString()的方法,非常简单地为不同用户以不同的偏好来显示不同的本地时间:

import java.time.*;

import java.time.format.*;

import java.util.Locale;

----

public class Main {

public static void main(String[] args) {

long ts = 1574208900000L;

System.out.println(timestampToString(ts, Locale.CHINA, "Asia/Shanghai"));

System.out.println(timestampToString(ts, Locale.US, "America/New_York"));

}

static String timestampToString(long epochMilli, Locale lo, String zoneId) {

Instant ins = Instant.ofEpochMilli(epochMilli);

DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM, FormatStyle.SHORT);

return f.withLocale(lo).format(ZonedDateTime.ofInstant(ins, ZoneId.of(zoneId)));

}

}

对上述方法进行调用,结果如下:

2019年11月20日 上午8:15

Nov 19, 2019, 7:15 PM

小结

处理日期和时间时,尽量使用新的java.time包;

在数据库中存储时间戳时,尽量使用long型时间戳,它具有省空间,效率高,不依赖数据库的优点。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值