![](/img/trans.png)
[英]How to convert string with this format to Java 8 time and convert to long milliseconds
[英]Convert Java long type value of specific format to seconds/milliseconds
如何以有效的方式将特定格式的 long 值转换为秒或毫秒。
我们系统中的示例长值是20210425 ,它代表格式yyyyMMdd的日期。
long val = 20210425;
我需要将以上转换为秒或毫秒,我在这里寻找的所需 output 将是:1619308800000
首先,您不应该使用long
来表示这样的日期。 日期不是 integer。 (就像电话号码和信用卡不是整数一样。)
但是,如果您已经有一个表示为long
值的日期......就像那样......那么有几种方法可以解决这个问题。
首先您需要做的是将long
转换为String
; 例如使用Long.toString(long)
。
然后使用日期解析器将字符串转换为日期/时间 object
最后,您从日期/时间 object 中获得毫秒时间
首先做一些算术从你的long
中提取年、月和日数。
接下来做更多的算术,将年/月/日转换为自 1970 年 1 月 1 日以来的天数。这很重要,因为您需要考虑闰年以及不同月份有不同天数的事实。
最后乘以一天中的毫秒数。
LocalDateTime
进行算术运算还有另一种方法。 如上所述使用算术提取年、月和日。
然后使用LocalDateTime.of(year, month, day, 0, 0)
创建一个LocalDateTime
。 (确保month
和day
的基础正确!)
最后从LocalDateTime
object 中得到毫秒时间
最后一点。 正如 Andy Turner 在评论中指出的那样,您尚未指定long
所基于的时区或您所针对的毫秒时钟的时区。 这些都需要考虑在内……无论您使用什么方法进行转换。
不要将数学用于日期时间处理。 为此,我们有java.time类。
LocalDate // Represent a date-only value, without a time-of-day and without a time zone or offset-from-UTC.
.parse( // Interpret a piece of text as representing a date value.
String.valueOf( 20210425L ) , // Becomes a `String` object, "20210425".
DateTimeFormatter.BASIC_ISO_DATE // YYYYMMDD format.
) // Returns a `LocalDate` object.
.atStartOfDay( ZoneOffset.UTC ) // Determine the first moment of the day in that time zone or offset.
.toInstant() // Adjust from some offset to an offset of zero hours-minutes-seconds.
.toEpochMilli() // Calculate a count of milliseconds since the epoch reference of first moment of 1970 UTC.
1619308800000
阅读Stephen C 的正确答案中的所有有效点。 然后考虑这个代码解决方案。
将您的long
变量转换为文本,并解析为日期。 出于其他答案中讨论的原因,如果可能的话,更可取的是完全跳过long
。
您的数字20210425
的文本版本恰好表示使用标准ISO 8601日期格式的“基本”(紧凑)版本的日期。 DateTimeFormatter
class 有一个预定义格式的常量DateTimeFormatter.BASIC_ISO_DATE
。
long val = 20210425;
String input = String.valueOf( val ) ;
DateTimeFormatter f = DateTimeFormatter.BASIC_ISO_DATE ;
LocalDate localDate = LocalDate.parse( input , f ) ;
显然,您需要自 1970 年 1 月 UTC 以来的毫秒数。 显然,您希望将该输入解释为在 UTC 中看到的(零时分秒的偏移量)。
因此,在获取一天的第一刻时,对日期应用零偏移量,以生成ZonedDateTime
。 从中提取一个Instant
,它是java.time的基本构建块,根据定义始终为 UTC。
Instant instant = localDate.atStartOfDay( ZoneOffset.UTC ).toInstant() ;
获取自 1970-01-01T00:00Z 的纪元参考以来的毫秒数。
long millisecondsSinceEpoch = instant.toEpochMilli() ;
localDate.toString(): 2021-04-25
即时.toString(): 2021-04-25T00:00:00Z
毫秒SinceEpoch:1619308800000
java.time框架内置于 Java 8 及更高版本中。 这些类取代了麻烦的旧日期时间类,例如java.util.Date
、 Calendar
和SimpleDateFormat
。
要了解更多信息,请参阅Oracle 教程。 并在 Stack Overflow 上搜索许多示例和解释。 规范是JSR 310 。
现在处于维护模式的Joda-Time项目建议迁移到java.time类。
您可以直接与数据库交换java.time对象。 使用符合JDBC 4.2或更高版本的JDBC 驱动程序。 不需要字符串,不需要java.sql.*
类。 Hibernate 5 & JPA 2.2 支持java.time 。
从哪里获得 java.time 课程?
你的问题有两个部分。
long
转换为日期。对于第一部分,简单地做一些基本的算术来提取所需的值。
对于第二部分,如果您至少使用 Java 8,则使用日期时间 API 。
/*
* import java.time.LocalDateTime;
* import java.time.ZoneOffset;
*/
long l = 20210425;
int year = (int) (l / 10_000);
System.out.println("year = " + year);
int month = (int) (l % 10_000 / 100);
System.out.println("month = " + month);
int day = (int) (l % 100);
System.out.println("day = " + day);
LocalDateTime ldt = LocalDateTime.of(year, month, day, 0, 0);
System.out.println(ldt.toEpochSecond(ZoneOffset.of("Z")));
请注意,根据您的问题,我无法确定您是否需要考虑时区,因此我使用了 0(零)的偏移量。 如果相关,您需要更改ZoneOffset
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.