在Java / Android中处理日期/时间和夏令时 [英] Handling date/time in java/android and daylight savings

查看:309
本文介绍了在Java / Android中处理日期/时间和夏令时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为Android开发日记应用程序,我希望允许用户选择他们所在的时区。对于我而言,时间始终是我的困惑之所在。

I am making a diary application for Android and I want to allow the user to select the timezone they are in. Time has always been a area of confusion for me programatically.

我将为可用时区创建一个枚举。

I am going to create an enum for the available timezones.

我将日期/时间条目保存到长于的sqlite中 UTC格式,然后以编程方式在Java中处理偏移量和DST以用于显示。

I am going to save date/time entries to a sqlite in long UTC format, then handling offsets and DST programmatically in Java for display purposes.

实际上,我知道Java在日期/

I am actually aware of Java's limitations when it comes to date/time handling.

Calendar utc = Calendar.getInstance(TimeZone.getTimeZone("UTC")); //returns the current time in UTC format
Long utcLong = utc.getTimeInMillis(); //returns current utc time in long for database insertion

问题1:如何将偏移量应用于它并考虑何时应用任何其他DST偏移量?因为并非所有时区都观察到DST和DST在不同时区的不同日期生效。

Question 1: How would I apply an offset to it and account for when to apply any additional DST offsets? Because not all timezones observe DST and DST comes into effect at different dates for different timezones.

问题2:Java的 TimeZone 类有大约800个ID,用户不得不浏览〜800个选项以找到适用于它们的选项会很烦人。有简短的清单吗?我认为大约有50个有用的时区。

Question 2: Java's TimeZone class has something like ~800 ids, it would be annoying to the user to have to scroll through ~800 options to find the one that applys to them. Is there a short list available? I'm thinking there are around ~50 useful timezones.

推荐答案

首先,我建议您不要使用日历类。它已经过时,并有很多错误和设计问题。这个糟糕的API被更好的API所取代:

First of all, I recommend you to not use the Calendar class. It's outdated and has lots of bugs and design issues. This terrible API was replaced by much better ones:

  • for Java >= 8, use the new date-time API
  • for Java <= 7, use the ThreeTen Backport
  • for Android, you can also try ThreeTenABP

The下面的代码适用于所有人,唯一的区别是软件包名称(在Java 8中是 java.time ,在ThreeTen Backport中是 org.threeten.bp ),但类和方法名称相同。

The code below works for all, the only difference is the package names (in Java 8 is java.time and in ThreeTen Backport is org.threeten.bp), but the classes and methods names are the same.

要获取UTC当前日期/时间,最好的选择是使用即时类:

To get the UTC current date/time, the best choice is to use Instant class:

// current date/time in UTC - now() always returns the current instant in UTC
Instant instant = Instant.now();
System.out.println(instant); // 2017-06-03T18:03:55.976Z

// equivalent to calendar.getTimeInMillis(), it returns a long
System.out.println(instant.toEpochMilli()); // 1496513035976

要将此时刻转换为时区,可以使用 ZonedDateTime 的ZoneId

To convert this instant to a timezone, you can use the ZoneId with a ZonedDateTime:

// ZoneId accepts the same IDs used by TimeZone
ZoneId zone = ZoneId.of("America/Sao_Paulo");
// convert instant to timezone
ZonedDateTime z = instant.atZone(zone);
System.out.println(z); // 2017-06-03T15:03:55.976-03:00[America/Sao_Paulo]

// converts back to UTC (returns an Instant)
System.out.println(z.toInstant()); // 2017-06-03T18:03:55.976Z

上面的代码已经处理了DST更改,因此往返于UTC的转换非常简单。

The code above already takes care of DST changes, so the conversion from and to UTC is straightforward.

您说您有一个列表〜50个有用时区。我不知道您用来定义该列表的条件是什么,但是如果用户所在的时区不在列表中会发生什么呢?

You say that you have a list of ~50 "useful" timezones. I don't know what criteria you used to define that list, but what happens if an user is in a timezone that's not in the list?

有一些想法此链接中的时区挑选用户界面并此处。您可以选择一种并适应您的应用。

There are some ideas of timezone-picking user interfaces in this link and here. You can choose one and adapt to your app.

我还建议不要(如果可能)使用3个字母的时区缩写(例如 CST PST ),因为它们含糊且不标准。最好使用全名(例如 America / Sao_Paulo Europe / London ),因为它们是Java API所使用的名称(您可以使用<$获得完整的列表c $ c> ZoneId.getAvailableZoneIds()),并且为每个区域配置了所有DST更改。

I also suggest to not use (if possible) the 3-letter timezone abbreviations (like CST or PST) because they are ambiguous and not standard. It's better to use the full names (like America/Sao_Paulo or Europe/London) as they are the ones used by Java's APIs (you can get the full list with ZoneId.getAvailableZoneIds()) and they are configured with all DST changes for each zone.

这篇关于在Java / Android中处理日期/时间和夏令时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆