为了账号安全,请及时绑定邮箱和手机立即绑定

Unix 时间/纪元时间:日期表示还是时间块?

Unix 时间/纪元时间:日期表示还是时间块?

GCT1015 2023-05-24 16:01:26
我最近接手了数据库的一些职责,其中一个字段是“工作时间”。这在 MySQL 中表示为 VARCHAR,格式如下:'1970-01-01 00:05:46'(示例)所有条目都以 1970-01-01 hh:MM:ss 开头并具有相同的格式。我想弄清楚这是否仅表示一天中的日期和时间,或者总花费的时间(例如完成客户 x 的手机维修需要 2 小时 20 分钟)。如果这代表时间量,我如何将其转换为正常的小时/分钟/秒单位集?
查看完整描述

4 回答

?
缥缈止盈

TA贡献2041条经验 获得超4个赞

我只是在这里猜测。看起来您的客户端收到了某些进程完成所需的毫秒数。但是,您的客户错误地(这是我的猜测)从中生成了一个日期。由于在 Java 内部,日期存储为自格林威治标准时间 1970 年 1 月 1 日 00:00:00.000 以来的毫秒数。您的值“1970-01-01 00:05:46”是 5:46(5 分 46 秒),表示与任何特定日期无关的时间段或持续时间。但是错误地被客户认为是 ZERRO 时间(1970 年 1 月 1 日 00:00:00.000 GMT)之后的 5:46 的日期。所以(如果我是正确的)你需要修复客户端中的错误并将你的毫秒数解释为持续时间而不是日期然后修复由错误逻辑产生的旧数据库数据



查看完整回答
反对 回复 2023-05-24
?
catspeake

TA贡献1111条经验 获得超0个赞

在你使用的Mysql中

Select SEC_TO_TIME(UNIX_TIMESTAMP('1970-01-01 00:05:46'));

你得到

05:46

所以工作时间是 5 分 46 秒。


查看完整回答
反对 回复 2023-05-24
?
白猪掌柜的

TA贡献1893条经验 获得超10个赞

时刻与时间跨度

这显然是一个不幸的设计决定,采用数据类型来表示一个时刻,时间轴上的一个特定点,(TIMESTAMP WITH TIME ZONE在标准 SQL 中)并滥用它来存储未附加到时间轴的时间跨度。

从数据库中检索时刻

鉴于示例文本的格式,我怀疑数据实际上可能存储在日期时间类型的列中。仔细检查您关于列的陈述VARCHAR(或者如果它确实是VARCHAR,请一直阅读到本答案的结尾)。

在内部,该数据类型可能存储自 1970 UTC 第一时刻的纪元参考以来的毫秒数或微秒数。所以我们的目标是达到这个数字。

OffsetDateTime使用 JDBC 4.2 或更高版本的驱动程序将伪矩作为对象检索。

OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;

如果您只关心 while 秒并且不想忽略小数秒,请调用toEpochSecond().

long secondsSinceEpoch = odt.toEpochSecond() ;

将该计数传递给Duration班级。此类用于表示未附加到时间轴的时间跨度,时间范围为小时-分钟-秒加上小数秒。

Duration d = Duration.ofSeconds( secondsSinceEpoch ) ;

然后,您可以生成标准 ISO 8601 格式的字符串。

String output = d.toString() ;

对于 5 分 46 秒的示例,那将是:

PT5M46S

您可以查询小时、分钟和秒部分。

long hours = d.toHoursPart() ;long minutes = d.toMinutesPart() ;

… 等等。

如果您关心亚秒级的细节,请将您的OffsetDateTime对象转换为更基本的类型Instant

Instant instant = odt.toInstant() ;

然后以纳秒为单位提取整秒和小数秒。

long seconds = instant.getEpochSecond() ;int nanos = instant.getNano() ;

喂那些给Duration

Duration d = Duration.ofSeconds( seconds , nanos ) ;

从数据库中检索文本

如果您确定您的原始值存储为文本,那么这将是一个更棘手的设计决策。

通过将中间的 SPACE 用T.

String input = "1970-01-01 00:05:46".replace( " " , "T" ) ;

解析为 aLocalDateTime因为我们缺少时区指示符或与 UTC 的偏移量。

LocalDateTime ldt = LocalDateTime.parse( input ) ;

应用与 UTC 的偏移量以获得OffsetDateTime.

OffsetDateTime odt = ldt.atOffset( ZoneOffset.UTC ) ;

从那里,继续如上所述。


查看完整回答
反对 回复 2023-05-24
?
倚天杖

TA贡献1828条经验 获得超3个赞

如果这代表时间量,我如何将其转换为正常的小时/分钟/秒单位集?

如果您在 Java 端而不是 MySQL 端执行此操作,您有几个选择。可能最简单的方法是稍微调整字符串,使其适合输入Duration.parse,然后使用实例上的各种访问器Duration来获取值。


查看完整回答
反对 回复 2023-05-24
  • 4 回答
  • 0 关注
  • 135 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信