如何将Java Calendar
对象从本地时间转换为UTC?这是我尝试过的:
Calendar calendar = Calendar.getInstance();
calendar.setTimeZone(TimeZone.getTimeZone("UTC"));
calendar.setTime(localDateTime.getTime());
SimpleDateFormat outputFmt = new SimpleDateFormat("MMM dd, yyy h:mm a zz");
String dateAsString = outputFmt.format(calendar.getTime());
System.out.println(dateAsString)
时间始终以MT而非GMT显示。我想将日历以UTC格式存储在数据库中(我不关心格式或显示时间)。
答案 0 :(得分:3)
请勿将日期时间转换为字符串以存储到SQL数据库中。使用日期时间对象。
我假设您要存储到数据类型为datetime
或timestamp
的不带时区的数据库列中,并且该列将包含UTC值(建议做法)。在这种情况下,进一步假设您至少使用Java 8和JDBC 4.2,则将UTC中的LocalDateTime
存储到数据库中。
ZonedDateTime dateTime = ZonedDateTime.of(
2018, 7, 1, 9, 0, 0, 0, ZoneId.of("America/Denver"));
LocalDateTime dateTimeInUtc = dateTime.withZoneSameInstant(ZoneOffset.UTC)
.toLocalDateTime();
System.out.println("UTC: " + dateTimeInUtc);
PreparedStatement ps = yourDatabaseConnection.prepareStatement(
"insert into your_table(date_time) values (?)");
ps.setObject(1, dateTimeInUtc);
ps.executeUpdate();
此代码示例在丹佛的7月1日上午9点进行转换并打印:
UTC:2018-07-01T15:00
然后将打印的UTC时间存储到数据库中。请注意setObject
方法的使用。
您使用的Calendar
类早已过时,并且设计总是很差。如果您是从旧版API获得的Calendar
对象,但您现在无法更改或不想更改,请先将其转换为Instant
,然后再从那里进行进一步转换:
Calendar localDateTime = // …;
LocalDateTime dateTimeInUtc = localDateTime.toInstant()
.atOffset(ZoneOffset.UTC)
.toLocalDateTime();
编辑:这取决于您在数据库中使用的数据类型和JDBC驱动程序的要求。就像我说的那样,我假设您您知道数据库中的值采用UTC,并且您使用的数据类型没有时区,所以数据库不知道。如果是这种情况,那么使用带有时区或偏移量信息的Java类型是没有意义的,因为在存储它时无论如何都会丢失它。
有人会说,在那种情况下,您已经在数据库中使用了错误的类型,并建议您使用timestamp with timezone
列,以便数据库也知道时间以UTC为单位。在这种情况下,您当然应该在存储的值中包括偏移信息。例如,在这种情况下,PostgreSQL JDBC驱动程序需要一个OffsetDateTime
,这是合乎逻辑的(因为它存储的是UTC偏移量,而不是实时区)。
取决于您的DBMS的功能,可能还有其他选择。我在底部添加了两个链接,您可以寻求更多的机会。
您到Calendar
的转换正常进行,并且您在UTC上的时间相同。麻烦只有在您尝试将其格式化为String
时才开始:当您使用calendar.getTime()
时,您将得到一个包含相同时间点的Date
对象(仍然是正确的时间点) ,但是Date
无法保存时区信息,因此您丢失了有关UTC的信息。接下来,您使用Date
格式化SimpleDateFormat
。 SimpleDateFormat
有一个时区,如果您自己没有设置,那么它会使用JVM的时区设置,这可能是Mountain Time的一种变体。因此,您的时间以MT打印。
java.time
(现代Java日期和时间API)。java.time
类型。答案 1 :(得分:2)
您需要在setTimeZone
而不是SimpleDateFormat
上致电Calendar
:
//getting local time
Calendar calendar = Calendar.getInstance(Locale.getDefault());
SimpleDateFormat outputFmt = new SimpleDateFormat("MMM dd, yyy h:mm a zz");
outputFmt.setTimeZone(TimeZone.getTimeZone("GMT")); //set timezone here
//shows calendar time correctly set
System.out.println(outputFmt.format(calendar.getTime()));
答案 2 :(得分:0)
这是我将正常日期转换为UTC的方式。因此,首先将Calendar对象转换为Date对象:
public static String convertToUTC(Date date) {
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.US);
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
return dateFormat.format(date);
}
答案 3 :(得分:0)
这是我准备自己的日历对象并将时区设置为 UTC,然后获取日期对象。获得日期对象后,您可以获得以毫秒为单位的时间,即自纪元以来的毫秒数。
private static Date internalDate(int year, int month, int day, int hour, int minute, int second) {
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
calendar.set(Calendar.YEAR, year);
calendar.set(Calendar.MONTH, month - 1);
calendar.set(Calendar.DAY_OF_MONTH, day);
calendar.set(Calendar.HOUR_OF_DAY, hour);
calendar.set(Calendar.MINUTE, minute);
calendar.set(Calendar.SECOND, second);
// get the Date Object and now your time is in UTC and you can easily convert it to
// local or UTC by getting the milli seconds which is date.gerTime();
return calendar.getTime();
}