我对Java很陌生,我对使用SimpleDateFormat
和Calendar
感到困惑。我有一个Date-Object,想要提取像yyyy-MM-dd HH:mm:ss
这样的GMT日期字符串。我住在德国,目前我们是GMT +0200。我的日期 - 对象的时间是例如2011-07-18 13:00:00
。我现在需要的是2011-07-18 11:00:00
。我的时区的偏移量应该自动计算。
我试过这样的事情,但我想某处有一个错误:
private String toGmtString(Date date){
SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
TimeZone timeZone = TimeZone.getDefault();
Calendar cal = Calendar.getInstance(new SimpleTimeZone(timeZone.getOffset(date.getTime()), "GMT"));
sd.setCalendar(cal);
return sd.format(date);
}
在某些设备上,datetring会像我想要的那样返回。在其他设备上,偏移量未正确计算,我从输入日期 - 对象接收日期和时间。你能给我一些提示或建议吗?我想我的方法是获取默认时区不起作用?
答案 0 :(得分:5)
private String toGmtString(Date date){
SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
sd.setTimeZone(TimeZone.getTimeZone("GMT"));
return sd.format(date);
}
您不需要创建新的SimpleTimeZone
,因为您没有创建新的时区 - 您的程序中有2个现有的时区,GMT和您的默认时区。
您也不需要修改现有的日期对象,因为您不想表示不同的时间点 - 您只需要一种不同的方式来显示相同的时间点。
您需要做的就是告诉SimpleDateFormat
在格式化中使用哪个时区。
答案 1 :(得分:2)
private String toGmtString(Date date){
//date formatter
SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//getting default timeZone
TimeZone timeZone = TimeZone.getDefault();
//getting current time
Calendar cal = Calendar.getInstance()
cal.setTime(date) ;
//adding / substracting curren't timezone's offset
cal.add(Calendar.MILLISECOND, -1 * timeZone.getRawOffset());
//formatting and returning string of date
return sd.format(cal.getTime());
}
答案 2 :(得分:0)
使用现代日期时间 API java.time
,有很多方法可以做到:
LocalDateTime
➡️ 将其与您的时区结合以获得 ZonedDateTime
➡️ 转换为 Instant
➡️ 使用 Instant#atZone
和 UTC 时区转换为 ZonedDateTime
。< /li>
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
String strDateTime = "2011-07-18 13:00:00";
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss", Locale.ENGLISH);
LocalDateTime ldt = LocalDateTime.parse(strDateTime, dtf);
// Using ZoneId.of("Europe/Berlin") for the demo. Change it to
// ZoneId.systemDefault()
Instant instant = ldt.atZone(ZoneId.of("Europe/Berlin")).toInstant();
ZonedDateTime zdtUtc = instant.atZone(ZoneId.of("Etc/UTC"));
System.out.println(zdtUtc.format(dtf)); // 2011-07-18 11:00:00
}
}
LocalDateTime
➡️ 将其与您的时区结合以获得 ZonedDateTime
➡️ 转换为 Instant
➡️ 使用 ZonedDateTime#ofInstant
和 UTC 时区转换为 ZonedDateTime
。< /li>
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
String strDateTime = "2011-07-18 13:00:00";
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss", Locale.ENGLISH);
LocalDateTime ldt = LocalDateTime.parse(strDateTime, dtf);
// Using ZoneId.of("Europe/Berlin") for the demo. Change it to
// ZoneId.systemDefault()
Instant instant = ldt.atZone(ZoneId.of("Europe/Berlin")).toInstant();
ZonedDateTime zdtUtc = ZonedDateTime.ofInstant(instant, ZoneId.of("Etc/UTC"));
System.out.println(zdtUtc.format(dtf)); // 2011-07-18 11:00:00
}
}
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
String strDateTime = "2011-07-18 13:00:00";
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss", Locale.ENGLISH);
LocalDateTime ldt = LocalDateTime.parse(strDateTime, dtf);
// Using ZoneId.of("Europe/Berlin") for the demo. Change it to
// ZoneId.systemDefault()
ZonedDateTime zdtPak = ldt.atZone(ZoneId.of("Europe/Berlin"));
ZonedDateTime zdtUtc = zdtPak.withZoneSameInstant(ZoneId.of("Etc/UTC"));
System.out.println(zdtUtc.format(dtf)); // 2011-07-18 11:00:00
}
}
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
String strDateTime = "2011-07-18 13:00:00";
// Using ZoneId.of("Europe/Berlin") for the demo. Change it to
// ZoneId.systemDefault()
DateTimeFormatter dtfInput = DateTimeFormatter.ofPattern("u-M-d H:m:s", Locale.ENGLISH)
.withZone(ZoneId.of("Europe/Berlin"));
ZonedDateTime zdtPak = ZonedDateTime.parse(strDateTime, dtfInput);
ZonedDateTime zdtUtc = zdtPak.withZoneSameInstant(ZoneId.of("Etc/UTC"));
DateTimeFormatter dtfOutput = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss", Locale.ENGLISH);
System.out.println(zdtUtc.format(dtfOutput)); // 2011-07-18 11:00:00
}
}
从 modern date-time API 了解有关 Trail: Date Time* 的更多信息。
* 出于任何原因,如果您必须坚持使用 Java 6 或 Java 7,您可以使用 ThreeTen-Backport,它将大部分 java.time 功能向后移植到 Java 6 & 7. 如果您正在为 Android 项目工作并且您的 Android API 级别仍然不符合 Java-8,请检查 Java 8+ APIs available through desugaring 和 How to use ThreeTenABP in Android Project。