我正在尝试以"HH:mm"的格式取一个字符串,并将其从local转换为utc,反之亦然。 这是我到目前为止所拥有的:
private String doTimeConversion(String time, boolean type) {
DateFormat dfLocal = new SimpleDateFormat("HH:mm");
DateFormat dfUTC = new SimpleDateFormat("HH:mm");
TimeZone local = TimeZone.getDefault();
TimeZone utc = TimeZone.getTimeZone("UTC");
dfLocal.setTimeZone(local);
dfUTC.setTimeZone(utc);
Date date;
String newTime ="00:00";
try {
//If true: local to utc/If false: utc to local
if (type) {
date = dfLocal.parse(time);
newTime = dfUTC.format(date);
} else {
date = dfUTC.parse(time);
newTime = dfLocal.format(date);
}
} catch (ParseException e) {
e.printStackTrace();
}
return newTime;
}
这似乎主要起作用,但我遇到的问题是,虽然我应该使用TimeZone.getDefault()抓住设备时间,但它没有考虑夏令时。 而不是将12:00(UTC)更改为08:00(EDT),而是将其更改为07:00(美国东部时间)。
总的来说,我只是希望能够花时间用户输入(字符串)并使用设备时区来假设用户输入的是根据他们的时区并将其转换为utc以及从utc返回到 设备时区。
那么我们应该假设今天的日期或哪个日期? 为了知道我们是否在夏令时(DST)。 (SimpleDateFormat假设1970年1月1日。)
仅供参考,麻烦的旧日期时间类如java.util.Date,java.util.Calendar和java.text.SimpleDateFormat现在已经遗留下来,取而代之的是java.time类。 大多数java.time功能都被反向移植到Java 6& ThreeTen-Backport项目中的Java 7。 在ThreeTenABP项目中进一步适应早期的Android。 请参见如何使用ThreeTenABP ....
使用ThreeTenABP我能够将我的代码转换为以下代码:
/**
* @param d int arr that holds date vals
* @param from Time zone to convert from
* @param to Time zone to convert to
* @return Converted date as String
*/
protected String doConvertTime(int[] d, ZoneId from, ZoneId to, DateTimeFormatter format){
LocalDateTime before = LocalDateTime.of(d[0], d[1], d[2], d[3], d[4]);
ZonedDateTime beforeTime = ZonedDateTime.of(before, from);
ZonedDateTime afterTime = beforeTime.withZoneSameInstant(to);
return afterTime.format(format);
}
int [] d:
我正在解析保存值的字符串片段并将它们放入一个传递给上面显示的函数的整数数组中。这似乎比直接从String解析更容易,因为我正在处理多个字符串。这样我就能确保将所有数据压缩到一个区域。
ZoneId来自& ZoneId:
我在主函数的开头初始化了两个ZoneId,这样我可以互换使用它们。例如。 local to utc:from = local,to = utc / utc to local:from = utc,to = local。实际上,可以使用任何两个时区。
DateTimeFormatter格式:
我只想以"MM / dd / yy"或"HH:mm"的格式返回一个String,因为这是我之前保持这些值的字符串的分离方式。但是,我需要有关日期的所有数据,以确保正在使用正确的时区以及由于时区更改而未更改日期,月份或年份。例如。 2018-12-31 22:00(美国东部时间)"America / New_York" - > 2019-01-01 03:00(UTC)( - 05:00偏移)如果我只有时间(HH:mm)值那么日期不会改变。
感谢您分享您的解决方案。将字符串解析为int s是非标准的,我不一定相信它是最好的解决方案,但是无论什么对你有用并让你开心......
毫无疑问,将我的字符串解析为int s并不是最好的解决方案,我当然不会建议其他人这样做。这正是我现在正在为我工??作的东西,也许稍后我会回来找到更好的方法。
java.time
import org.threeten.bp.LocalDate;
import org.threeten.bp.LocalDateTime;
import org.threeten.bp.LocalTime;
import org.threeten.bp.ZoneId;
import org.threeten.bp.ZoneOffset;
import org.threeten.bp.ZonedDateTime;
public class ConvertTimeToAndFromUtc {
/** @param type If true: local to utc/If false: utc to local */
private static String doTimeConversion(String time, boolean type) {
ZoneId localZone = ZoneId.systemDefault();
LocalTime lt = LocalTime.parse(time);
LocalDateTime ldt = LocalDate.now(localZone).atTime(lt);
ZonedDateTime resultTime;
if (type) {
resultTime = ldt.atZone(localZone).withZoneSameInstant(ZoneOffset.UTC);
} else {
resultTime = ldt.atOffset(ZoneOffset.UTC).atZoneSameInstant(localZone);
}
LocalTime newTime = resultTime.toLocalTime();
return newTime.toString();
}
public static void main(String[] args) {
System.setProperty("user.timezone","Asia/Gaza");
System.out.println("09.21 local to UTC:" + doTimeConversion("09:21", true));
System.out.println("23:13 UTC to local:" + doTimeConversion("23:13", false));
}
}
今天打印上面的程序(在Java 7上测试):
09.21 local to UTC: 06:21
23:13 UTC to local: 02:13
加沙地带在一年的这个时间偏移+03:00,在标准/正常时间偏移+02:00,所以看来转换是考虑到夏令时(DST)(后一次转换是在午夜过后)。
我正在使用java.time,现代Java日期和时间API。您使用的日期时间类DateFormat,SimpleDateFormat,TimeZone和Date都已过时,并且存在一系列设计问题。他们也不适合手头的问题。
问题:我可以在Android上使用java.time吗?
是的,java.time适用于较旧和较新的Android设备。它至少需要Java 6。
在Java 8及更高版本和更新的Android设备上(来自API级别26),现代API内置。仅在这种情况下从java.time包导入日期时间类(不是org.threeten.bp)。
在Java 6和7中获取ThreeTen Backport,新类的后端端口(适用于JSR 310的ThreeTen;请参见底部的链接)。
在(较旧的)Android上使用Android版的ThreeTen Backport。它被称为ThreeTenABP。并确保从子包中导入org.threeten.bp的日期和时间类。
链接
Oracle教程:日期时间,解释如何使用java.time。
Java规范请求(JSR)310,其中首先描述java.time。
ThreeTen Backport项目,java.time的后端到Java 6和7(用于JSR-310的ThreeTen)。
ThreeTenABP,Android版ThreeTen Backport
问题:如何在Android项目中使用ThreeTenABP,有一个非常详尽的解释。
这似乎工作得很好,我现在已经实现了ThreeTenABP,但是我有一个奇怪的问题,"America / New_York"的偏移恰好出现-04:56:02 [America / New_York]当我非常积极时它应该只是-04:00:00。但是,示例中的时区可以正常工作。
@KentJ。直到1882年,纽约在-4:56:02抵消了!您的日期时间可能会落在这段历史时期吗?美国纽约纽约时区从下拉列表中选择1800-1849或1850-1899。
是的,当把年份传递给我的LocalDateTime时,我给它一个两位数的数字(从一个字符串中解析,格式为MM / dd / yy),我猜这使得它相信年份是0018而不是2018年。令人难以置信。谢谢您的帮助。