我有timezone = "[PST -08:00] America/Los Angeles (Pacific Standard Time)"
格式。我有time["03:00 pm"]
和date[2018/4/22]
.我需要检查它是否少于当前当地时间的 12 小时。
乔达日期时区不接受此 ID[DateTimeZone.forID("[PST -08:00] America/Los Angeles (Pacific Standard Time)"]
。
有什么选择吗?
在这里,我只寻找时区选项。如何将时区字符串干净地转换为时区?
您应该仅使用 IANA 的区域名称,格式为Continent/Region
.在这种情况下,您应该使用:
DateTimeZone.forID("America/Los_Angeles");
请注意,名称是"洛杉矶">,而不是"洛杉矶"(洛杉矶和安吉利斯之间有一个_
而不是空格)。
您可以通过循环访问DateTimeZone.getAvailableIDs()
返回的集合来检查所有可用的名称:
for (String zoneName : DateTimeZone.getAvailableIDs()) {
System.out.println(zoneName);
}
在特定情况下,您应该解析字符串(如 Georg 的回答所解释的那样)或将其映射到有效的 IANA 名称:
Map<String, String> names = new HashMap<String, String>();
names.put("[PST -08:00] America/Los Angeles (Pacific Standard Time)", "America/Los_Angeles");
或者使用其他一些逻辑,例如:
if (timezoneName.contains("Los Angeles")) {
// use America/Los_Angeles
}
您必须决定是要解释多头偏移量还是空头偏移量。我选择了长偏移量,因为您可以从长名称"America/Los_Angeles"创建一个 ZoneId。然后,ZoneId 查询 IANA 时区数据库 - 请参阅规范。此测试用例从给定架构中提取名称。
import org.junit.Test;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Date;
public class Zone {
@Test
public void zoneId() throws ParseException {
String zoneName = "[PST -08:00] America/Los Angeles (Pacific Standard Time)";
String time = "03:00 pm";
String dateString = "2018/4/22";
String americaLosAngelesPST = zoneName.substring(zoneName.indexOf("]") + 2, zoneName.length());
String americaLosAngeles = americaLosAngelesPST.substring(0, americaLosAngelesPST.indexOf("(") - 1).replace(" ", "_");
ZoneId zone = ZoneId.of(americaLosAngeles);
SimpleDateFormat inputFormat = new SimpleDateFormat("yyyy/MM/dd KK:mm a");
Date parsedDateTime = inputFormat.parse(dateString + " " + time);
ZonedDateTime inputZonedDateTime = parsedDateTime.toInstant().atZone(zone);
// compare with ZonedDateTime.now()
}
}
还有一个java.time
答案。我去-08:00
:
String offsetString = timezone.replaceFirst("\[[^ ]+ ([+-]\d{2}:\d{2})\].*", "$1");
ZoneOffset offset = ZoneOffset.of(offsetString);
这给出了-08:00
的偏移量。如果你确实需要一个时区,我喜欢其他人会选择美国/洛杉矶,这是明确的,而三个和四个字母的缩写不是标准化的,通常是模棱两可的,而且通常不是真正的时区。例如,太平洋标准时间可能意味着太平洋标准时间、菲律宾标准时间或皮特凯恩标准时间。但是,要确定时间是否在当地时间中午 12 点之前,偏移量就足够了,并且更易于分析和使用。
有趣的是,如果不是因为时区在城市名称中带有空格America/Los Angeles
,您的整个时区字符串可能会被DateTimeFormatter.ofPattern("'['zzz xxx']' VV (zzzz)", Locale.US)
解析。IANA 时区 ID 在那里有一个下划线。只是因为这个,我需要在解析之前对字符串进行一些操作。然后我一路走来,只拿出了需要的偏移量。
Joda-Time 处于维护模式,预计不会进行重大增强,他们的开发团队建议迁移到java.time
。不太了解Joda-Time,我想如果你愿意,你可以把我的答案翻译成Joda-Time。