将本地时间转换为UTC时间和反向转换

35

我正在开发 Android 应用程序,希望将本地时间(设备时间)转换为 UTC 并保存到数据库中。在从数据库中检索后,我必须再次将其转换并在设备的时区中显示。 有人能建议我如何使用 Java 实现这个功能吗?

8个回答

39

我使用这两种方法将本地时间转换为GMT/UTC,反之亦然,对我来说这很好地运作,没有任何问题。

public static Date localToGMT() {
    Date date = new Date();
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
    sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
    Date gmt = new Date(sdf.format(date));
    return gmt;
}

将您想转换成设备本地时间的 GMT/UTC 日期传递给此方法:

public static Date gmttoLocalDate(Date date) {

    String timeZone = Calendar.getInstance().getTimeZone().getID();
    Date local = new Date(date.getTime() + TimeZone.getTimeZone(timeZone).getOffset(date.getTime()));
    return local
}

4
new Date(String date) 方法已被弃用,不应再使用!请勿使用该方法。 - Pushpendra Pal
1
你可以使用DateFormat.parse(String date)代替new Date(String date),因为后者已经被弃用。 - Abhishek Sharma
这里看到的日期时间类非常有缺陷,现在已经被现代的java.time类所取代,这些类是在JSR 310中定义的。 - Basil Bourque
我使用了这段代码将Android系统的Alarm Manager返回的UTC时间更改为IST。所有内容都保持不变,只需直接将时区字符串值更改为“IST”,而无需从日历中获取,因为在我的情况下它无法正常工作。 - Explosive

31

被接受答案的简化和压缩版本:

public static Date dateFromUTC(Date date){
    return new Date(date.getTime() + Calendar.getInstance().getTimeZone().getOffset(new Date().getTime()));
}

public static Date dateToUTC(Date date){
    return new Date(date.getTime() - Calendar.getInstance().getTimeZone().getOffset(date.getTime()));
}

是的,这是一个简单的一行代码的正确答案,干得好伙计。 - Siddharth Thakkar
但是 TimeZone#getOffset() 接受 UTC 时间... - Viktor Mukhachev
2
我建议了一次编辑,但被拒绝了。第一个函数(即“dateFromUTC”)有一个错误。如果输入的“date”参数是UTC时间,则必须添加本地时间的时间差才能到达本地时间。那么它必须像这样:return new Date(date.getTime() + Calendar.getInstance().getTimeZone().getOffset(new Date().getTime())); - MJBZA

16
尝试这个:
//将时间从UTC转换为本地格式
 public Date getUTCToLocalDate(String date) {
            Date inputDate = new Date();
            if (date != null && !date.isEmpty()) {
                @SuppressLint("SimpleDateFormat") SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
                simpleDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
                try {
                    inputDate = simpleDateFormat.parse(date);
                } catch (ParseException e) {
                    e.printStackTrace();
                }
            }
            return inputDate;
        }  

//将本地日期转换为UTC

public String getLocalToUTCDate(Date date) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    calendar.setTimeZone(TimeZone.getTimeZone("UTC"));
    Date time = calendar.getTime();
    @SuppressLint("SimpleDateFormat") SimpleDateFormat outputFmt = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
    outputFmt.setTimeZone(TimeZone.getTimeZone("UTC"));
    return outputFmt.format(time);
}

这是一个可行的解决方案。 - Parth Patel

9

简而言之

ZoneId z = ZoneId.systemDefault() ;  // Or, ZoneId.of( "Africa/Tunis" ) 
ZonedDateTime zdt = ZonedDateTime.now( z ) ;  // Capture current moment as seen in a particular time zone.
Instant instant = zdt.toInstant() ;  // Adjust to UTC, an offset of zero hours-minutes-seconds.
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;  // Make an `OffsetDateTime` object to exchange with the database.
myPreparedStatement.setObject( … , odt ) ;  // Write moment to database column of a type akin to the SQL standard type `TIMESTAMP WITH TIME ZONE`.
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;  // Retrieve a moment from database.
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;  // Adjust into a particular tim zone. Same moment, different wall-clock time.

java.time

现代方法使用java.time类,几年前取代了可怕的日期时间类,例如DateCalendar

以UTC时间为准捕获当前时刻。

OffsetDateTime odt = OffsetDateTime.now( ZoneOffset.UTC ) ;

使用符合JDBC 4.2或更高版本的驱动程序将数据存储在数据库中。

myPreparedStatement( … , odt ) ;

从数据库中检索。

OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;

调整到所在时区。

ZoneId z = ZoneId.systemDefault() ;
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;

生成文本以呈现给用户。

DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.FULL ).withLocale( Locale.getDefault() ) ;
String output = zdt.format( f ) ;

Android 26+内置了java.time的实现。对于早期的Android版本,通过“API desugaring”功能可以使用最新工具提供的大部分功能。如果此方法无法使用,请使用ThreeTenABP库获取大部分java.time功能。这个库基于ThreeTen-Backport项目中回溯到Java 6和Java 7的时间API。


调用需要API级别26(当前最小值为21):java.time.OffsetDateTime#now - yozhik
1
@yozhik 不,那已经不再正确了。请看我最后一段的编辑。 - Basil Bourque

3

您可以尝试类似以下方式将数据插入到数据库中:

    SimpleDateFormat f = new SimpleDateFormat("h:mm a E zz");
    f.setTimeZone(TimeZone.getTimeZone("UTC"));
    System.out.println(f.format(new Date()));
    String dd = f.format(new Date());

以下是您评论中的内容:

输出:

1:43 PM Mon UTC

针对此内容,需要再次进行转换并显示为设备所在时区的时间。

更新:

String dd = f.format(new Date());

        Date date = null;
        DateFormat sdf = new SimpleDateFormat("h:mm a E zz");
        try {
            date = sdf.parse(dd);
        }catch (Exception e){

        }
        sdf.setTimeZone(TimeZone.getTimeZone("Asia/Kolkata"));
        System.out.println(sdf.format(date));

输出结果:

GMT+05:30周一晚上7:30

您可以像这样显示。


尝试再次转换时,它显示了空指针异常。 - Mew
不可能,我已经尝试过了,它运行良好。你能给我你的应用程序的堆栈跟踪吗? - User Learning
我刚刚初始化了Date date = new Date(),一切正常,谢谢。 - Mew

2

Time.getCurrentTimezone()

这个函数会获取当前时区。

Calendar c = Calendar.getInstance(); int seconds = c.get(Calendar.SECOND)

这段代码会获取UTC时间,并以秒为单位表示。当然,您可以更改值以获取其他单位的时间。


假设今天是IST时区的星期一下午5:34,那么如何将其转换为UTC时区的星期一上午12:04? - Mew
你实际上是否可以访问到一个时间对象来进行转换,还是只有一个字符串? - der_Fidelis
我只有一个字符串。 - Mew
@Dyo 这应该能帮助你解决问题。https://docs.oracle.com/javase/tutorial/datetime/iso/timezones.html - s7vr

2

试试这个

DateFormat formatterIST = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
        formatterIST.setTimeZone(TimeZone.getTimeZone("Asia/Kolkata"));
        Date dateobj = new Date();
        Date date = formatterIST.parse(formatterIST.format(dateobj));
        System.out.println(formatterIST.format(date));

        DateFormat formatterUTC = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
        formatterUTC.setTimeZone(TimeZone.getTimeZone("UTC")); // UTC timezone
        System.out.println(formatterUTC.format(date));

0

获取当前UTC时间:

public String getCurrentUTC(){
        Date time = Calendar.getInstance().getTime();
        SimpleDateFormat outputFmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        outputFmt.setTimeZone(TimeZone.getTimeZone("UTC"));
        return outputFmt.format(time);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接