在 android 表单中,我接受来自用户的 GMT 值(偏移量),例如 +5:30、+3:00。
从这个值,我想计算“印度/德里”的时区。
关于如何做的任何想法......Plzz
在 android 表单中,我接受来自用户的 GMT 值(偏移量),例如 +5:30、+3:00。
从这个值,我想计算“印度/德里”的时区。
关于如何做的任何想法......Plzz
If you already have a specific instant in time at which that offset is valid, you could do something like this:
import java.util.*;
public class Test {
public static void main(String [] args) throws Exception {
// Five and a half hours
int offsetMilliseconds = (5 * 60 + 30) * 60 * 1000;
for (String id : findTimeZones(System.currentTimeMillis(),
offsetMilliseconds)) {
System.out.println(id);
}
}
public static List<String> findTimeZones(long instant,
int offsetMilliseconds) {
List<String> ret = new ArrayList<String>();
for (String id : TimeZone.getAvailableIDs()) {
TimeZone zone = TimeZone.getTimeZone(id);
if (zone.getOffset(instant) == offsetMilliseconds) {
ret.add(id);
}
}
return ret;
}
}
On my box that prints:
Asia/Calcutta
Asia/Colombo
Asia/Kolkata
IST
(As far as I'm aware, India/Delhi isn't a valid zoneinfo ID.)
If you don't know an instant at which the offset is valid, this becomes rather harder to really do properly. Here's one version:
public static List<String> findTimeZones(int offsetMilliseconds) {
List<String> ret = new ArrayList<String>();
for (String id : TimeZone.getAvailableIDs()) {
TimeZone zone = TimeZone.getTimeZone(id);
if (zone.getRawOffset() == offsetMilliseconds ||
zone.getRawOffset() + zone.getDSTSavings() == offsetMilliseconds) {
ret.add(id);
}
}
return ret;
}
... but that assumes that there are only ever two offsets per time zone, when in fact time zones can change considerably over history. It also gives you a much wider range of IDs, of course. For example, an offset of one hour would include both Europe/London and Europe/Paris, because in summer time London is at UTC+1, whereas in winter Paris is at UTC+1.
通常,时区 ID 和时区偏移量之间的关系是多对一的,即多个时区 ID 可以具有相同的时区偏移量。事实上,由于DST的原因,一个时区 ID 可以有两个时区偏移量,例如时区 ID 的时区偏移量,“欧洲/伦敦”在夏季和夏季是“+00:00”和“+01:00”分别是冬天。
除此之外,在某些情况下,国家的时区偏移已被其统治者/政治家多次更改,正如 Ole VV 在以下评论中所提到的:
时区 ID 和时区偏移量之间的关系是多对一的……如果您正在考虑一个时间点,则为真。如果看历史,真的是多对多。
因此,考虑到夏令时和这些历史事件,我们可以说时区 ID 和时区偏移量之间的关系是多对多的。
使用java.time
现代日期时间 API 的解决方案:
您可以遍历ZoneId.getAvailableZoneIds()
过滤并收集与使用输入偏移字符串创建的ZoneId
相等ZoneOffset
的值。ZoneOffset
演示:
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args) {
// Test
System.out.println(getTimeZoneId("+5:30"));
System.out.println(getTimeZoneId("-5:00"));
}
static List<String> getTimeZoneId(String input) {
List<String> list = new ArrayList<>();
// Convert +5:30 to +05:30; similarly, -5:00 to -05:00
String[] arr = input.split(":");
if (arr.length == 2) {
input = arr[0].substring(0, 1) + String.format("%02d", Integer.parseInt(arr[0].replaceAll("\\D", ""))) + ":"
+ arr[1];
ZoneOffset offset = ZoneOffset.of(input);
Instant now = Instant.now();
list = ZoneId.getAvailableZoneIds()
.stream()
.filter(tzId -> ZoneId.of(tzId).getRules().getOffset(now).equals(offset))
.collect(Collectors.toList());
}
return list;
}
}
输出:
[Asia/Kolkata, Asia/Colombo, Asia/Calcutta]
[America/Panama, America/Chicago, America/Eirunepe, Etc/GMT+5, Mexico/General, America/Porto_Acre, America/Guayaquil, America/Rankin_Inlet, US/Central, America/Rainy_River, America/Indiana/Knox, America/North_Dakota/Beulah, America/Monterrey, America/Jamaica, America/Atikokan, America/Coral_Harbour, America/North_Dakota/Center, America/Cayman, America/Indiana/Tell_City, America/Mexico_City, America/Matamoros, CST6CDT, America/Knox_IN, America/Bogota, America/Menominee, America/Resolute, SystemV/EST5, Canada/Central, Brazil/Acre, America/Cancun, America/Lima, America/Bahia_Banderas, US/Indiana-Starke, America/Rio_Branco, SystemV/CST6CDT, Jamaica, America/Merida, America/North_Dakota/New_Salem, America/Winnipeg]
注意:正则表达式模式\D
指定一个非数字字符。
从Trail: Date Time了解有关现代日期时间 API 的更多信息。
* 出于任何原因,如果您必须坚持使用 Java 6 或 Java 7,则可以使用ThreeTen-Backport,它将大部分java.time功能向后移植到 Java 6 和 7。如果您正在为 Android 项目和 Android API 工作level 仍然不符合 Java-8,请检查Java 8+ APIs available through desugaring和How to use ThreeTenABP in Android Project。
如果我正确地解释了你的问题,那么试试这个,
final SimpleDateFormat date=
new SimpleDateFormat("EEE, MMM d, yyyy hh:mm:ss a z");
date.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println("GMT time: " + date.format(currentTime));
在此您可以添加偏移量。看看这是否对您有帮助。