处理java/android和夏令时中的日期/时间

gle*_*end 4 java datetime android date

我正在为Android制作日记应用程序,我想让用户选择他们所在的时区.时间一直是我编程的混乱区域.

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

我将以longUTC格式将日期/时间条目保存到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
Run Code Online (Sandbox Code Playgroud)

问题1:我如何应用偏移量并说明何时应用任何额外的DST偏移量?因为并非所有时区都观察到DST,并且DST在不同时区对不同时区生效.

问题2:Java的TimeZone类有大约800个ID,用户必须滚动~800个选项才能找到适用于它们的选项.有短名单吗?我在想大约有50个有用的时区.

小智 6

首先,我建议你不要使用这Calendar门课.它已经过时,并且存在许多错误和设计问题.这个可怕的API被更好的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
Run Code Online (Sandbox Code Playgroud)

这个瞬间转换成时区,你可以使用ZoneId一个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
Run Code Online (Sandbox Code Playgroud)

上面的代码已经处理了DST更改,因此从UTC转换到UTC很简单.

时区列表

你说你有一个约50个"有用"时区的列表.我不知道您用于定义该列表的标准,但如果用户位于列表中不在的时区,会发生什么?

这个链接这里有一些时区选择用户界面的想法.您可以选择一个并适应您的应用程序.

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

  • @psycotik java.time框架是Joda-Time的官方继承者.这两个项目都由同一个人Stephen Colebourne领导. (3认同)
  • Jodatime很好**但它已被停产并被新的API取代.Threeten更好,因为它是新java 8 API的后端(所以未来的迁移将比使用jodatime更容易).即使在joda的网站上它也说*注意Joda-Time被认为是一个很大程度上"完成"的项目.没有计划重大改进.如果使用Java SE 8,请迁移到java.time(JSR-310)*.如果你使用java <= 7,请使用Threeten backport.所以我不建议用jodatime开始一个新项目. (2认同)