如何在Java中将2021-09-29T17:04:31.0000 +05:30
转换为2021-09-29 17:04:31.0000000 Asia/Calcutta
?
和附加问题在这里-我尝试了许多方法从offset(+05:30)
中获得timezone(Asia/Calcutta)
,但无法获得。有人能帮帮我吗?
由于您不能(可靠地)从偏移量中派生区域,因此您可能需要使用其他解决方法。
下面是一个示例,使用合适的DateTimeFormatter
将输入String
解析为OffsetDateTime
,然后创建所需的ZoneId
,并将其应用于OffsetDateTime
以创建ZonedDateTime
。
public static void main(String[] args) {
// your example input
String offsetTime = "2021-09-29T17:04:31.0000 +05:30";
// define a formatter that parses a String of this format
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSSS xxx");
// then parse it to an object that knows date, time and offset
OffsetDateTime odt = OffsetDateTime.parse(offsetTime, dtf);
// print the result
System.out.println(odt);
// now define the desired zone
ZoneId asiaCalcutta = ZoneId.of("Asia/Calcutta");
// and use the offset-aware object to apply the zone
ZonedDateTime zdt = odt.atZoneSameInstant(asiaCalcutta);
// print it
System.out.println(zdt);
}
这个输出
2021-09-29T17:04:31+05:30
2021-09-29T17:04:31+05:30[Asia/Calcutta]
请注意:只有当偏移量和区域实际匹配时,才会保持相同的偏移量。我不知道你的具体要求,所以只有你才能知道这种方法是否适合你的情况。
如果你想找出当前使用特定偏移量的时区,然后让你的代码决定哪个是正确的,你可能想看看这个问题和它的答案。
我试着写这段代码来涵盖三种可能性字符串参数,或LocalDateTime参数andZonedDateTime参数:
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
public class SpecialFormater {
// parameter : ZonedDateTime
public static String specialFormaterZonedDateTime(ZonedDateTime zdt) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSSSSS");
ZoneId zid = zdt.getZone();
System.out.println("Your initial format =" + zdt);
String result = "Your expected format =" + zdt.format(formatter) + " " + zid;
return result;
}
// parameter : LocalDateTime
public static String specialFormaterLocalDateTime(LocalDateTime dt) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSSSSS");
ZoneId zid = ZoneId.of("Asia/Calcutta");
System.out.println("Your initial format =" + dt);
ZonedDateTime zdt = ZonedDateTime.of(dt, zid);
System.out.println("Your zoned dateTime default format =" + zdt);
String result = "Your expected format =" + dt.format(formatter) + " " + zid;
return result;
}
// Parameter : String
public static String specialFormaterString(String localDateTime) {
System.out.println("String before formatting =" + localDateTime);
String pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSS xxx";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
LocalDateTime dt = LocalDateTime.parse(localDateTime, formatter);
ZoneId zid = ZoneId.of("Asia/Calcutta");
DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSSSSS");
String result = "String after formatting =" + dt.format(formatter2) + " " + zid;
return result;
}
public static void main(String[] args) {
System.out.println("specialFormaterLocalDateTime");
System.out.println(specialFormaterLocalDateTime(LocalDateTime.now()));
System.out.println("***********");
System.out.println();
System.out.println("specialFormaterString");
System.out.println(specialFormaterString("2021-09-29T17:04:31.0000 +05:30"));
System.out.println("**********");
System.out.println();
System.out.println("specialFormaterZonedDateTime");
System.out.println(specialFormaterZonedDateTime(ZonedDateTime.now()));
}
}
输出:
specialFormaterLocalDateTime
Your initial format =2021-10-06T12:35:45.029
Your zoned dateTime default format =2021-10-06T12:35:45.029+05:30[Asia/Calcutta]
Your expected format =2021-10-06 12:35:45.0290000 Asia/Calcutta
***********
specialFormaterString
String before formatting =2021-09-29T17:04:31.0000 +05:30
String after formatting =2021-09-29 17:04:31.0000000 Asia/Calcutta
**********
specialFormaterZonedDateTime
Your initial format =2021-10-06T12:35:45.064+02:00[Europe/Paris]
Your expected format =2021-10-06 12:35:45.0640000 Europe/Paris
如何使用java.time
获取刚好一些与偏移量匹配的时区我倾向于从你在Arvind Kumar Avinash的回答下的评论中理解,你通过简单地采用第一个具有正确偏移量的时区(或你认为是正确的偏移量)来解决它。当然是java。time,现代Java日期和时间API,可以做到这一点。我想给你指条路。
String input = "2021-09-29T17:04:31.0000 +05:30";
// Remove space and parse
OffsetDateTime dateTime = OffsetDateTime.parse(input.replace(" ", ""));
ZoneOffset offset = dateTime.getOffset();
// Find and convert to a zone that matches the offset (there will usually be many)
ZonedDateTime zonedDateTime = ZoneId.getAvailableZoneIds()
.stream()
.map(ZoneId::of)
.map(dateTime::atZoneSameInstant)
.filter(zdt -> zdt.getOffset().equals(offset))
.findFirst()
// If all else fails, use the offset as time zone
.orElse(dateTime.atZoneSameInstant(offset));
// Convert to 2021-09-29 17:04:31.0000000 Asia/Calcutta format
String result = zonedDateTime.format(FORMATTER);
System.out.println(result);
我已经使用这个格式化器来格式化输出:
private static final DateTimeFormatter FORMATTER
= DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss.SSSSSS VV", Locale.ROOT);
输出是(在我的Java 11上):
20121-09-29 17:04:31.000000亚洲/加尔各答
Asia/Kolkata是以前被称为Asia/Calcutta的时区现在的名称。这样够近吗?
在我的代码中,我考虑了不存在合适时区的情况。让我们用一个偏移量来看看,我认为这个偏移量在任何实际时区都不会使用:
String input = "2021-10-06T18:54:31.0000 +00:30";
2018-10-06 18:54:31.000000 +00:30
如果你不想要这个,你将至少需要改变与调用orElse()
。