此Java代码(以日期作为字符串给出)应该在CET区域的午夜打印同一日期的纪元时间戳(假设我不在同一区域中)。
public static void main(String[] args) throws ParseException {
String dateStr = "1995-06-06";
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
formatter.setTimeZone(TimeZone.getTimeZone("CET"));
Date date = formatter.parse(dateStr);
Calendar c = new GregorianCalendar();
c.setTimeZone(TimeZone.getTimeZone("CET"));
c.setTime(date);
c.set(Calendar.HOUR_OF_DAY, 0);
c.set(Calendar.MINUTE, 0);
c.set(Calendar.SECOND, 0);
c.set(Calendar.MILLISECOND, 0);
System.out.println("Epoch timestamp = " + c.getTime().getTime());
}
如果运行上面的程序,我应该得到打印:
Epoch timestamp = 802389600000
我可以在这里验证它是正确的:
https://www.epochconverter.com/timezones?q=802389600&tz=Europe%2FMalta
现在,这适用于大多数日期。但是,有些奇怪的日期(例如“ 1975-09-19”)无法使用。实际上,它生成180313200000作为时间戳,该时间戳为凌晨1点而不是午夜:
https://www.epochconverter.com/timezones?q=180313200&tz=Europe%2FMalta
问题来源:Stack Overflow
时区差异 您的Java代码使用CET,它实际上不是时区(例如,因为一年中的大部分时间都使用CEST而不是时区)。Java将CET转换为欧洲/巴黎。法国和巴黎在1975年没有使用夏令时(DST)。1976年3月重新引入。
您指向纪元转换器的链接指定了马耳他时区(欧洲/马耳他)。马耳他确实在1975年使用夏季时间:从4月20日至当年9月21日为CEST。
这说明了结果的差异。
用Java代码 如果您想要马耳他时间:
String dateStr = "1975-09-19";
long epochTimestamp =
LocalDate
.parse(dateStr)
.atStartOfDay(ZoneId.of("Europe/Malta"))
.toInstant()
.toEpochMilli();
System.out.println("Epoch timestamp = " + epochTimestamp);
打印:
纪元时间戳= 180309600000
您链接到的时代转换器很高兴同意:
转换结果(180309600) 180309600 在欧洲/马耳他(CEST)时区转换为1975年9月19日,星期五,上午00:00:00(上午),偏移量(与格林威治标准时间/格林尼治标准时间之间的差异)为+02:00或7200秒。此日期为白天节约时间。
在Java中,请使用java.time(现代的Java日期和时间API)进行日期和时间工作。它是如此的好得多相比于旧的日期和时间类,如与工作SimpleDateFormat,TimeZone,Date和Calendar。另外,将小时等设置为0也不是获取当天第一时间的正确方法。在某些情况下,夏令时从一天的开始开始,因此一天的第一时刻是01:00:00。Java知道这一点,因此该atStartOfDay方法将为您提供当天相关的正确信息。
而且,无论使用过时的类还是现代的类,都始终以区域/城市格式指定时区,例如,欧洲/巴黎或欧洲/马耳他。三个,四个和五个字母的时区缩写通常是模棱两可的,并且通常不是真实的时区,因此请不要依赖。
链接 - 时区在巴黎,法兰西岛,法国 - 马耳他瓦莱塔所在时区 - Oracle教程:Date Time说明如何使用java.time。
回答来源:Stack Overflow
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。