简体   繁体   English

将UTC日期转换为当前时区

[英]Convert UTC date to current timezone

I have to convert a UTC date in this format "2016-09-25 17:26:12" to the current time zone of Android. 我必须将格式为“ 2016-09-25 17:26:12”的UTC日期转换为Android的当前时区。 I did this: 我这样做:

SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
simpleDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
Date myDate = simpleDateFormat.parse(temp.getString("date"));
System.out.println(mydate.toString());

This works but I don't know why it print also "GMT+02:00". 这行得通,但我不知道为什么还要打印“ GMT + 02:00”。 This is the Output: "Sun Sep 25 19:26:12 GMT+02:00 2016", I don't want to show "GMT+02:00". 这是输出:“ Sun Sep 25 19:26:12 GMT + 02:00 2016”,我不想显示“ GMT + 02:00”。

EDIT, CODE OF THE SOLUTION: 编辑,解决方案代码:

SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
simpleDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
SimpleDateFormat outputSdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date myDate = simpleDateFormat.parse(temp.getString("date"));
System.out.println(outputSdf.format(myDate));

it print GMT+02 because this is your "local" timezone. 它会打印GMT + 02,因为这是您的“本地”时区。 if you want to print the date without timezone information, use SimpleDateFormat to format the date to you liking. 如果要打印不带时区信息的日期,请使用SimpleDateFormat设置日期格式。

edit : adding the code example (with your variable 'myDate') 编辑:添加代码示例(带有变量“ myDate”)

SimpleDateFormat inputSDF = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
inputSDF.setTimeZone(TimeZone.getTimeZone("UTC"));
Date myDate = inputSDF.parse("2016-09-25 17:26:12");
//
SimpleDateFormat outputSDF = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println(outputSDF.format(myDate));
System.out.println(TimeZone.getDefault().getID());

yield on the (my) console (with my local timezone). (在我的)控制台上的收益(使用我的本地时区)。

2016-09-25 19:26:12
Europe/Paris

tl;dr tl; dr

LocalDateTime.parse( "2016-09-25 17:26:12".replace( " " , "T" ) )
             .atZoneSameInstant( ZoneId.systemDefault() )
             .format( DateTimeFormatter.ofLocalizedDateTime( FormatStyle.MEDIUM ) )

Avoid legacy date-time classes 避免使用旧的日期时间类

You are using troublesome old date-time classes bundled with the earliest versions of Java. 您正在使用与最早的Java版本捆绑在一起的麻烦的旧日期时间类。 Now supplanted by the java.time classes. 现在由java.time类取代。

ISO 8601 ISO 8601

You input string nearly complies with the standard ISO 8601 format used by default with the java.time classes. 您输入的字符串几乎符合java.time类默认使用的标准ISO 8601格式。 Replace the SPACE in the middle with a T . T代替中间的空格。

String input = "2016-09-25 17:26:12".replace( " " , "T" );

LocalDateTime

The input lacks any indication of offset-from-UTC or time zone . 输入缺少从UTC时区 偏移的任何指示。 So we parse as a LocalDateTime . 因此,我们将其解析为LocalDateTime

LocalDateTime ldt = LocalDateTime.parse( input );

OffsetDateTime

You claim to know from the context of your app that this date-time value was intended to be UTC . 您声称从您的应用程序上下文知道该日期时间值旨在为UTC So we assign that offset as the constant ZoneOffset.UTC to become a OffsetDateTime . 因此,我们将该偏移量分配为常量ZoneOffset.UTC成为OffsetDateTime

OffsetDateTime odt = ldt.atOffset( ZoneOffset.UTC );

ZonedDateTime

You also say you want to adjust this value into the current default time zone of the user's JVM (or Android runtime in this case). 您还说过要将此值调整为用户JVM(在本例中为Android运行时)的当前默认时区。 Know that this default can change at any time during your app's execution. 知道此默认值可以在应用执行期间随时更改。 If the time zone is critical, you should explicitly ask the user for a desired/expected time zone. 如果时区很关键,则应明确要求用户提供所需/期望的时区。 The ZoneId class represents a time zone. ZoneId类表示时区。

ZoneId z = ZoneId.systemDefault(); // Or, for example: ZoneId.of( "America/Montreal" )
ZonedDateTime zdt = odt.atZoneSameInstant( z );

Generate string 产生字串

And you say you want to generate a string to represent this date-time value. 您说要生成一个字符串来表示此日期时间值。 You can specify any format you desire. 您可以指定所需的任何格式。 But generally best to let java.time automatically localize for you according to the human language and cultural norms defined in a Locale object. 但是通常最好让java.time根据Locale对象中定义的人类语言和文化规范为您自动本地化。 Use FormatStyle to specify length or abbreviation ( FULL , LONG , MEDIUM , SHORT ). 使用FormatStyle指定长度或缩写( FULLLONGMEDIUMSHORT )。

Locale locale = Locale.getDefault();  // Or, for example: Locale.CANADA_FRENCH
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.MEDIUM ).withLocale( locale );
String output = zdt.format( f );

About java.time 关于java.time

The java.time framework is built into Java 8 and later. java.time框架内置于Java 8及更高版本中。 These classes supplant the troublesome old date-time classes such as java.util.Date , .Calendar , & java.text.SimpleDateFormat . 这些类取代了麻烦的旧日期时间类,例如java.util.Date.Calendarjava.text.SimpleDateFormat

The Joda-Time project, now in maintenance mode , advises migration to java.time. 现在处于维护模式Joda-Time项目建议迁移到java.time。

To learn more, see the Oracle Tutorial . 要了解更多信息,请参见Oracle教程 And search Stack Overflow for many examples and explanations. 并在Stack Overflow中搜索许多示例和说明。

Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport and further adapted to Android in ThreeTenABP (see How to use… ). 大部分的java.time功能后移植到Java 6和7 ThreeTen,反向移植 ,并进一步适应的AndroidThreeTenABP (见如何使用...... )。

The ThreeTen-Extra project extends java.time with additional classes. ThreeTen-Extra项目使用其他类扩展了java.time。 This project is a proving ground for possible future additions to java.time. 该项目为将来可能在java.time中添加内容提供了一个试验场。 You may find some useful classes here such as Interval , YearWeek , YearQuarter , and more . 您可以在这里找到一些有用的类,比如IntervalYearWeekYearQuarter ,和更多

You can use : 您可以使用 :

system.out.println(myDate.getDay()+" "+myDate.getMonth()+" "+myDate.getYear());

Put what you need 把你需要的

You can do it with set timezone method. 您可以使用设置时区方法来实现。

SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
simpleDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
Date myDate = simpleDateFormat.parse(rawQuestion.getString("AskDateTime"));

Below is the toString() implementation of Date class: 下面是Date类的toString()实现:

public String toString() {
        // "EEE MMM dd HH:mm:ss zzz yyyy";
        BaseCalendar.Date date = normalize();
        StringBuilder sb = new StringBuilder(28);
        int index = date.getDayOfWeek();
        if (index == BaseCalendar.SUNDAY) {
            index = 8;
        }
        convertToAbbr(sb, wtb[index]).append(' ');                        // EEE
        convertToAbbr(sb, wtb[date.getMonth() - 1 + 2 + 7]).append(' ');  // MMM
        CalendarUtils.sprintf0d(sb, date.getDayOfMonth(), 2).append(' '); // dd

        CalendarUtils.sprintf0d(sb, date.getHours(), 2).append(':');   // HH
        CalendarUtils.sprintf0d(sb, date.getMinutes(), 2).append(':'); // mm
        CalendarUtils.sprintf0d(sb, date.getSeconds(), 2).append(' '); // ss
        TimeZone zi = date.getZone();
        if (zi != null) {
            sb.append(zi.getDisplayName(date.isDaylightTime(), TimeZone.SHORT, Locale.US)); // zzz
        } else {
            sb.append("GMT");
        }
        sb.append(' ').append(date.getYear());  // yyyy
        return sb.toString();
    }

If you see, it appends Time zone info to the dates. 如果看到,它将时区信息附加到日期。 If you don't want it to be printed, you can use SimpleDateFormat to convert Date to string, eg: 如果您不想打印它,则可以使用SimpleDateFormatDate转换为字符串,例如:

SimpleDateFormat format = new SimpleDateFormat("dd-MM-yyyy");
System.out.println(format.format(new Date()));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM