[英]Unix time/ epoch time: Date representation or time block?
我最近已经接管了数据库的一些职责,其中一个字段是“工作时间”。 它在MySQL中表示为VARCHAR,格式为:
'1970-01-01 00:05:46'(示例)所有条目均以1970-01-01 hh:MM:ss开头,并且格式相同。
我想弄清楚,如果这仅仅代表一天的日期和时间,或一定量的时间总花费(如用了2小时20分钟才能完成修复客户X的手机)。
如果这表示时间量,如何将其转换为正常的时/分/秒单位制?
我只是在猜。 看来您的客户端接收到某些过程完成所需的毫秒数。 但是,您的客户错误地(这是我的猜测)会由此产生一个日期。 由于在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)之后的5:46。 因此(如果我是正确的话),您需要修复客户端中的错误,并将毫秒数解释为持续时间而不是日期,然后修复由错误逻辑生成的旧数据库数据
在Mysql中,您使用
Select SEC_TO_TIME(UNIX_TIMESTAMP('1970-01-01 00:05:46'));
你得到
05:46
因此,工作时间为5分46秒。
显然,这是一个不幸的设计决策,需要使用数据类型来表示时刻(时间轴上的特定点)(标准SQL中的TIMESTAMP WITH TIME ZONE
),并滥用它来存储未附加到时间轴上的时间跨度。
给定示例文本的格式,我怀疑数据实际上可能存储在日期时间类型的列中。 仔细检查有关该VARCHAR
声明(或者如果确实为VARCHAR
,请完整阅读此答案的结尾)。
在内部,该数据类型可能存储着自1970年UTC的第一时刻的纪元参考以来的毫秒或微秒的计数。 因此,我们的目标是达到这个数字。
使用JDBC 4.2或更高版本的驱动程序将伪矩作为OffsetDateTime
对象检索。
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
如果您只关心几秒钟,而又不想忽略小数秒,请调用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 ) ;
如果确定原始值存储为文本,那将是一个更加棘手的设计决策。
通过在中间用T
重新包装SPACE来操纵文本以符合ISO 8601。
String input = "1970-01-01 00:05:46".replace( " " , "T" ) ;
解析为LocalDateTime
因为我们缺少时区或UTC偏移量的指示符。
LocalDateTime ldt = LocalDateTime.parse( input ) ;
应用从UTC偏移量以获得OffsetDateTime
。
OffsetDateTime odt = ldt.atOffset( ZoneOffset.UTC ) ;
从那里开始,如上所述继续。
如果这表示时间量,如何将其转换为正常的时/分/秒单位制?
如果您是在Java方面而不是MySQL方面进行操作,则有两种选择。 可能最简单的方法是稍微按摩一下字符串,以便将其送入Duration.parse
,然后在Duration
实例上使用各种访问器来获取值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.