我想在IST
中将UTC
转换为Java
纪元
但不是从IST
减去5.30小时,而是在IST
public static long convertDateToEpochFormat(String date) {
Date convertedDate = null;
try {
LOGGER.info(date);
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
LOGGER.info(date);
convertedDate = formatter.parse(date);
LOGGER.info(convertedDate);
} catch (ParseException e) {
e.printStackTrace();
}
return convertedDate.getTime() / 1000L;
}
我获得的日志声明是:
2017-01-01 00:00:00
2017-01-01 00:00:00
Sun Jan 01 05:30:00 IST 2017
由于UTC转换,理想情况下应该是Dec 31 18:30:00。
谁能告诉我什么错了?
答案 0 :(得分:3)
为什么util.Date转发日期而不是减去日期?
因为印度时间是提前的UTC,而不是落后。
Instant.parse(
"2017-01-01 00:00:00".replace( " " , "T" ) + "Z"
).atZone(
ZoneId.of( "Asia/Kolkata" )
).toString()
2017-01-01T05:30 + 05:30 [亚/加尔各答]
你正在使用现在遗留下来的麻烦的旧日期时间类,取而代之的是java.time类。
您的输入字符串几乎采用标准ISO 8601格式。要完全遵守,请使用T
替换中间的空格。解析/生成字符串时,java.time类使用标准格式。因此无需指定格式化模式。
String input = "2017-01-01 00:00:00".replace( " " , "T" ) ;
如果该输入用于表示UTC中的时刻,则附加Z
,Zulu
的缩写,表示UTC。
String input = "2017-01-01 00:00:00".replace( " " , "T" ) + "Z" ; // Assuming this input was intended to be in UTC.
2017-01-01T00:00:00Z
如果可能,在将日期时间值序列化为字符串时,首先使用ISO 8601格式。
Instant
将输入字符串解析为Instant
,在时间轴上以UTC为单位,分辨率为纳秒。
Instant instant = Instant.parse( input ) ;
instant.toString():2017-01-01T00:00:00Z
ZonedDateTime
您似乎希望将此值调整为印度时间。应用ZoneId
获取ZonedDateTime
。
以continent/region
的格式指定proper time zone name,例如America/Montreal
,Africa/Casablanca
或Pacific/Auckland
。切勿使用诸如EST
或IST
之类的3-4字母缩写,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。
ZoneId z = ZoneId.of( "Asia/Kolkata" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
zdt.toString():2017-01-01T05:30 + 05:30 [亚洲/加尔各答]
请参阅此code run live at IdeOne.com。
你的问题预计印度时间会倒退,落后于UTC值。这毫无意义。印度时间+05:30
。请注意,一些旧协议则相反(使用负号)。
午夜时分,在午夜时分00:00:00在Prime Meridian,同时在印度早上五点半。
因此,所有这三个代表相同的同时时刻,时间轴中的相同点:
2017-01-01T00:00:00Z
2017-01-01T05:30+05:30[Asia/Kolkata]
2016-12-31T16:00-08:00[America/Los_Angeles]
在Java代码中,使用日期时间对象传递日期时间值,特别是java.time对象。在Java代码之外传递日期时间值时,使用实际的ISO 8601格式序列化为字符串。
依赖于从纪元开始的整数计数值令人困惑,难以调试,人类无法阅读,并且会导致挫折和错误(更糟糕的是:未观察到的错误)。
java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.Date
,Calendar
和& SimpleDateFormat
现在位于Joda-Time的maintenance mode项目建议迁移到java.time类。
要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310。
从哪里获取java.time类?
ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如Interval
,YearWeek
,YearQuarter
和more。
答案 1 :(得分:1)
The answer by Basil Bourque is not only correct, it is also very informative. I have already upvoted it. I’ll try just a little bit of a different angle.
As I understand your question, your date-time string 2017-01-01 00:00:00
should be interpreted in IST, AKA Asia/Kolkata time, and you want to convert it to seconds (not milliseconds) since the epoch. And you are asking why you are getting an incorrect result.
I think the answer is rather banal: When the date-time string is in India time, you should not set UTC time on the formatter you use for parsing it. This is sure to get an incorrect result (if you were to format the date-time into UTC, you would do well in setting UTC as time zone on the formatter used for formatting, but this is a different story).
I agree with Basil Bourque that you should avoid the outdated classes Date
and SimpleDateFormat
. So here’s my suggestion (assuming you do need epoch seconds and cannot use an Instant
as Basil Bourque recommends).
private static DateTimeFormatter parseFormatter = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss");
public static long convertDateToEpochFormat(String date) {
return LocalDateTime.parse(date, parseFormatter)
.atZone(ZoneId.of("Asia/Kolkata"))
.toInstant()
.getEpochSecond();
}
This will convert your example string into an instant of 2016-12-31T18:30:00Z
and return 1483209000. Please check for yourself that it is correct.
I have been assuming all the way that by IST you meant Indian Standard Time. Please be aware that three and four letter time zone abbreviations are ambiguous. For example, my JVM thinks that IST means Israel Standard Time. If you intended the same, please substitute Asia/Jerusalem
for Asia/Kolkata
. If you meant Irish Standard Time (another recognized/semi-official interpretation), please use Europe/Dublin
. You will of course get different output in each case.