繁体   English   中英

将特定格式的Java long类型值转换为秒/毫秒

[英]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 (确保monthday的基础正确!)

最后从LocalDateTime object 中得到毫秒时间


最后一点。 正如 Andy Turner 在评论中指出的那样,您尚未指定long所基于的时区或您所针对的毫秒时钟的时区。 这些都需要考虑在内……无论您使用什么方法进行转换。

tl;博士

不要将数学用于日期时间处理。 为此,我们有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() ;

请参阅在 IdeOne.com 上实时运行的代码

localDate.toString(): 2021-04-25

即时.toString(): 2021-04-25T00:00:00Z

毫秒SinceEpoch:1619308800000


关于java.time

java.time框架内置于 Java 8 及更高版本中。 这些类取代了麻烦的日期时间类,例如java.util.DateCalendarSimpleDateFormat

要了解更多信息,请参阅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 课程?

你的问题有两个部分。

  1. long转换为日期。
  2. 获取该日期的毫秒数。

对于第一部分,简单地做一些基本的算术来提取所需的值。

对于第二部分,如果您至少使用 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM