java - 考虑本地时区,在java中将日期转换为纪元秒
问题描述
我想将日期转换为纪元范围(当天上午 12 点,当天格林威治标准时间晚上 11.59)。
- fromDate=2019-10-25T00:00:00-07:00, toDate=2019-10-25T23:59:59-07:00: 想返回 (1571986800,1572073199) (相当于GMT 10月25日的时间戳, 2019 年上午 7:00:00,格林威治标准时间 2019 年 10 月 26 日上午 6:59:59)
- fromDate=2019-10-24T00:00:00-07:00, toDate=2019-10-24T23:59:59-07:00: 想返回 (1571900400,1571986799) (相当于GMT 10月24日的时间戳, 2019 年上午 7:00:00,格林威治标准时间 2019 年 10 月 25 日上午 6:59:59)
我的尝试:
fromDate = String.valueOf(formatter.parse(fromDate.substring(0, 19)).toInstant().getEpochSecond());
toDate = String.valueOf(formatter.parse(toDate.substring(0, 19)).toInstant().getEpochSecond());
epochDateRange.append("(").append(fromDate).append(",").append(toDate).append(")");
通过设置为其他时区进行调试时:即在eclipse中添加以下参数-调试配置
'-Duser.timezone=Asia/Kuala_Lumpur'
对于上述时区,它在 10 月 25 日返回 (1571932800,1572019199) 但想要的结果是 (1571986800,1572073199)
对于上述时区,在 Oct24 它返回 (1571846400,1571932799) 但想要的结果是 (1571900400,1571986799)
任何帮助将不胜感激。谢谢。
解决方案
你的问题很混乱。所以我只能猜测你想要做什么。但主要问题可能是您误解了什么是从纪元开始计数。
一方面,常用的时代参考日期时间有几十个。总是说出你的意思。与 Java 捆绑在一起的日期时间类使用 1970 年 UTC 的第一刻,即 1970-01-01T00:00Z。
另一方面,您可能没有意识到 count-from-epoch 必须引用偏移量或时区才有意义。同样,在 Java 中,我们使用上面提到的 UTC,并且在上面看到Z
的字符串的末尾可以看到,采用标准ISO 8601格式。
另一个问题是,您似乎试图通过确定一天的最后一刻来代表一整天的开始和结束。这是有问题的。在日期时间处理中,我们通常使用半开方法来定义时间跨度。在半开中,开头是包容的,而结尾是排斥的。因此,一天从第一刻开始,一直持续到但不包括第二天的第一刻。
OffsetDateTime start = OffsetDateTime.parse( "2019-10-25T00:00:00-07:00" );
OffsetDateTime stop = start.plusDays( 1 ) ;
start.toString(): 2019-10-25T00:00-07:00
stop.toString(): 2019-10-26T00:00-07:00
另一个问题是使用12:00:00 AM
. 这可能是表示午夜滚动的一种棘手方式。我建议坚持使用 24 时钟进行编码。因此,UTC 中的一天总是从 00:00:00.0 开始。(顺便说一句,在某些日期的某些时区,这一天并不总是从 00:00 开始。)
另一个问题是您使用偏移量而不是时区。例如,如果您知道时区是 ,请America/Phoenix
使用该时区而不是-07:00
.
至于你从-07:00 的偏移量跳到格林威治标准时间,你把我弄丢了。我不明白你的意思。但也许这会有所帮助。
如果您想查看 2019-10-25T00:00:00-07:00 的 UTC 时间,只需Instant
从OffsetDateTime
. 根据定义, AnInstant
始终采用 UTC。
OffsetDateTime
.parse( "2019-10-25T00:00:00-07:00" )
.toInstant()
.toString()
2019-10-25T07:00:00Z
因此,您调用 2019-10-25T00:00:00-07:00 相当于 2019 年 10 月 25 日 12:00:00 AM GMT(实际上,GMT 和 UTC 是相同的)是荒谬的。第-07:00
一个字符串上的表示日期时间比 UTC 晚七个小时。因此,UTC 中具有相同时间的同一日期不可能代表同一时刻。
也许您的目标是获得某个地区(某个时区)的人们所看到的一天中的第一刻。
ZoneId z = ZoneId.of( "Asia/Kuala_Lumpur" ) ;
LocalDate ld = LocalDate.parse( "2019-10-25" ) ;
ZonedDateTime zdtStart = ld.atStartOfDay( z ) ;
ZonedDateTime zdtStop = zdtStart.plusDays( 1 ) ;
当调整为 UTC 时,请查看启动和停止。
Instant utcStart = zdtStart.toInstant() ;
Instant utcStop = zdtStop.toInstant() ;
以整秒为粒度获取从 1970-01-01T00:00:00Z 开始的计数。
long secondsSinceEpochStart = utcStart.getEpochSecond() ;
long secondsSinceEpochStop = utcStop.getEpochSecond() ;
zdtStart/zdtStop: 2019-10-25T00:00+08:00[Asia/Kuala_Lumpur]/2019-10-26T00:00+08:00[Asia/Kuala_Lumpur]
utcStart/utcStop: 2019-10-24T16:00:00Z/2019-10-25T16:00:00Z
secondsSinceEpochStart/secondsSinceEpochStop: 1571932800/1572019200
查看所有这些代码在 IdeOne.com 上实时运行。你可以在那里轻松地进行分叉和实验。
顺便说一句,如果您在跟踪一对时刻的时间跨度上做了大量工作,请将ThreeTen-Extra库添加到您的项目中以访问该类Interval
。此类表示一对Instant
对象,以及许多有用的方法,例如abuts
、contains
等。
ZonedDateTime start = LocalDate.of( 2019, Month.OCTOBER , 25 ).atStartOfDay( ZoneOffset.UTC ) ;
Interval dayInUtc = Interval.of(
start.toInstant() ,
start.plusDays( 1 ).toInstant()
) ;
String epochCounts = dayInUtc.getStart().getEpochSecond() + "/" + dayInUtc.getEnd().getEpochSecond() ;
…并且在一个时区:
ZonedDateTime start = LocalDate.of( 2019, Month.OCTOBER , 25 ).atStartOfDay( ZoneId.of( "Asia/Kuala_Lumpur" ) ) ;
Interval dayInKualaLumpur = Interval.of(
start.toInstant() ,
start.plusDays( 1 ).toInstant()
) ;
String epochCounts = dayInKualaLumpur.getStart().getEpochSecond() + "/" + dayInKualaLumpur.getEnd().getEpochSecond() ;
推荐阅读
- printf - printf 不会在屏幕上返回任何内容
- python - 尝试使用 numpy.gradient 查找数组的梯度时出现错误
- html - 如何管理表格中的边框间距?
- php - XERO PHP API 将文件附加到发票 - 发送时不包含文件
- point - 无法使用 Geopandas / Shapely 从浮点数据创建几何点
- python - 使用 bootstrap4 轮播的 django 网站中的滑块
- c# - 带有 IEWebDriver 的 Selenium 无法识别输入的输入值
- plotly-dash - 是否可以在单个独立的 html 文件中导出 Plotly Dash 应用程序?
- django - 如果用户已经登录并转到 Django 中的登录页面,我如何重定向离开登录页面?
- python - 在 Python 中修改类成员