在Android中将UTC日期转换为本地时间?

时间:2017-09-16 05:15:31

标签: java android datetime timezone jodatime

我的日期String2017-09-16T05:06:18.157类似,我希望将其转换为当地时间(IST)。在印度标准时间,它将在2017-09-16 10:36:18左右。

使用Joda-Time,我试图将其转换为本地但我无法做到。

以下是我的代码:

private String getConvertDate(String date_server) {
    DateTimeFormatter inputFormatter = DateTimeFormat
            .forPattern("yyyy-MM-dd'T'HH:mm:ss.SSS")
            .withLocale(Locale.US);

    DateTime parsed = inputFormatter.parseDateTime(date_server);

    DateTimeFormatter outputFormatter = DateTimeFormat
            .forPattern("yyyy-MM-dd HH:mm:ss")
            .withLocale(Locale.US)
            .withZone(DateTimeZone.getDefault());

    return outputFormatter.print(parsed);
}

3 个答案:

答案 0 :(得分:4)

您找到了import { TestBed, inject } from '@angular/core/testing'; import { AngularFireAuth } from 'angularfire2/auth'; import 'rxjs/add/observable/of'; import { Observable } from 'rxjs/Rx'; import { AuthService } from './auth.service'; import { environment } from '../environments/environment'; describe('AuthService', () => { const mockAngularFireAuth: any = { auth: jasmine.createSpyObj('auth', { 'signInAnonymously': Promise.resolve('foo'), // 'signInWithPopup': Promise.reject(), // 'signOut': Promise.reject() }), authState: Observable.of(null) }; beforeEach(() => { TestBed.configureTestingModule({ providers: [ { provide: AngularFireAuth, useValue: mockAngularFireAuth }, { provide: AuthService, useClass: AuthService } ] }); }); it('should be created', inject([ AuthService ], (service: AuthService) => { expect(service).toBeTruthy(); })); // // // // // describe('when we can’t authenticate', () => { beforeEach(() => { mockAngularFireAuth.auth.signInAnonymously.and.returnValue(Promise.reject('bar')); }); it('should thow', inject([ AuthService ], (service: AuthService) => { expect(mockAngularFireAuth.auth.signInAnonymously).toThrow(); })); }); // // // // // }); 的解决方案。我只想添加更多有关它的见解(主要是因为旧类(SimpleDateFormatDateCalendar)有lots of problemsdesign issues,他们正在被新的API取代。)

输入SimpleDateFormatString)仅包含日期(年/月/日)和时间(小时/分钟/秒/毫秒),但不包含时区信息。因此,当调用2017-09-16T05:06:18.157时,Joda-Time只是假设它在JVM默认时区。

如果您知道输入是UTC格式,但输入本身没有相关信息,则必须告诉它。一种方法是在格式化程序中设置:

parseDateTime

另一种方法是首先将输入解析为// set the formatter to UTC DateTimeFormatter inputFormatter = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss.SSS") .withZone(DateTimeZone.UTC); // DateTime will be in UTC DateTime parsed = inputFormatter.parseDateTime("2017-09-16T05:06:18.157"); (表示没有时区的日期和时间的类),然后将其转换为UTC中的org.joda.time.LocalDateTime

DateTime

两者都生成相同的// parse to LocalDateTime DateTime = parsed = LocalDateTime.parse("2017-09-16T05:06:18.157") // convert to a DateTime in UTC .toDateTime(DateTimeZone.UTC); ,对应于UTC DateTime

要将其格式化为“IST timezone”(实际上不是时区 - 更多内容如下),您还可以在格式化程序中设置时区:

2017-09-16T05:06:18.157Z

或者您可以使用withZone() method// convert to Asia/Kolkata DateTimeFormatter outputFormatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss") .withZone(DateTimeZone.forID("Asia/Kolkata")); System.out.println(outputFormatter.print(parsed)); 转换为另一个时区:

DateTime

两者都会打印出来:

  

2017-09-16 10:36:18

在您的代码中,您正在使用DateTimeFormatter outputFormatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss"); // convert to Asia/Kolkata System.out.println(outputFormatter.print(parsed.withZone(DateTimeZone.forID("Asia/Kolkata")))); ,它获取JVM默认时区(有一些tricky details)。但是默认时区can be changed without notice, even at runtime,因此最好指定您要使用的时区。

另外,请记住 IST 等短名称不是真正的时区。始终更喜欢使用IANA timezones names(始终采用DateTimeZone.getDefault()格式,例如Region/CityAsia/Kolkata

避免使用3个字母的缩写(例如Europe/BerlinIST),因为它们是ambiguous and not standard。只需登记this list IST可以是“印度标准时间”,“以色列标准时间”和“爱尔兰标准时间”。

您可以致电PST获取可用时区列表(并选择最适合您系统的时区)。

Java新日期/时间API

Joda-Time处于维护模式,正在被新的API取代,因此我不建议使用它来启动新项目。即使在joda's website中它也说:“请注意,Joda-Time被认为是一个很大程度上”完成“的项目。没有计划大的增强。如果使用Java SE 8,请迁移到java.time(JSR) -310)。“即可。

如果您不能(或不想)从Joda-Time迁移到新API,则可以忽略此部分。

在Android中,您可以使用ThreeTen Backport,这是Java 8新日期/时间类的绝佳后端。为了使其有效,您还需要ThreeTenABP(更多关于如何使用它here)。

这种新API针对每种情况都有lots of different date/time types

首先,您可以将输入解析为DateTimeZone.getAvailableIDs(),然后我使用org.threeten.bp.LocalDateTime将其转换为UTC,从而产生org.threeten.bp.ZoneOffset

然后,我使用org.threeten.bp.OffsetDateTime将其转换为另一个时区,并使用org.threeten.bp.ZoneId对其进行格式化(这基本上是@Ole V.V's comment建议的 - 只是为了表明它是多么简单是的,因为没有什么不同的事情):

org.threeten.bp.format.DateTimeFormatter

输出结果为:

  

2017-09-16 10:36:18

答案 1 :(得分:3)

试试这段代码:

   String serverdateFormat = "yyyy-MM-dd'T'HH:mm:ss'Z'";

  public String convertServerDateToUserTimeZone(String serverDate) {
    String ourdate;
    try {
        SimpleDateFormat formatter = new SimpleDateFormat(serverdateFormat, Locale.UK);
        formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
        Date value = formatter.parse(serverDate);
        TimeZone timeZone = TimeZone.getTimeZone("Asia/Kolkata");
        SimpleDateFormat dateFormatter = new SimpleDateFormat(serverdateFormat, Locale.UK); //this format changeable
        dateFormatter.setTimeZone(timeZone);
        ourdate = dateFormatter.format(value);

        //Log.d("OurDate", OurDate);
    } catch (Exception e) {
        ourdate = "0000-00-00 00:00:00";
    }
    return ourdate;
}

答案 2 :(得分:0)

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

simpleDateFormat.setTimeZone(TimeZone.getDefault());
String formattedDate = simpleDateFormat.format(myDate);