2017-06-03 138 views
1

我正在为Android制作日记应用程序,我希望允许用户选择他们所在的时区。时间对我来说一直是一个编程领域。在java/android和夏令时中处理日期/时间

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

我打算将日期/时间条目保存为UTC格式的long的sqlite,然后在Java中以编程方式处理偏移和DST以进行显示。

我实际上知道Java在日期/时间处理方面的局限性。

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在不同时区的不同日期生效。

问题2:Java的TimeZone类有类似〜800 ID的情况,如果用户必须滚动浏览〜800个选项才能找到适用于它们的选项,这会很烦人。是否有可用的短名单?我想有大约50个有用的时区。

+0

备案,这里的代码示例不起作用。它返回本地时间,只是在不调整时间的情况下更改时区信息。 – psycotik

回答

2

首先,我建议你不要使用Calendar类。已过时,已有lots of bugs and design issues。这种可怕的API被替换了更好的:

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

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

// 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

// 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到UTC的转换非常简单。

时区列表

你说你有50〜“有用”的时区的列表。我不知道你用什么标准来定义这个列表,但是如果一个用户在一个不在列表中的时区,会发生什么?

this linkhere中有时区选取用户界面的一些想法。你可以选择一个并适应你的应用程序。

我也建议使用(如果可能的话)的3个字母的时区缩写(如CSTPST),因为它们ambiguous and not standard。最好使用全名(如America/Sao_PauloEurope/London),因为它们是Java API所使用的名称(可以通过ZoneId.getAvailableZoneIds()获得完整列表),并且它们都配置了每个DST的每个更改区。

+0

我一直在寻找乔达时代,似乎是一个受欢迎的选择。你用过那个吗?你认为threeten更好吗? – psycotik

+2

Jodatime很好**,但**正在停止使用,并由新API取代。 Threeten更好,因为它是新的Java 8 API的后端(所以未来的迁移比使用jodatime更容易)。即使在乔达的网站上,它说*注意,乔达时间被认为是一个大部分“完成”的项目。计划没有重大改进。如果使用Java SE 8,请迁移到java.time(JSR-310)*。如果您使用java <= 7,请使用Threeten backport。所以我不建议用jodatime开始一个新项目。 – 2017-06-03 18:12:12

+1

我也添加了一些更多的答案的链接,希望它有帮助。 – 2017-06-03 18:25:03