gle*_*end 4 java datetime android date
我正在为Android制作日记应用程序,我想让用户选择他们所在的时区.时间一直是我编程的混乱区域.
我将为可用的时区创建一个枚举.
我将以long
UTC格式将日期/时间条目保存到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个字母的时区缩写(如CST或PST),因为它们含糊不清而且不标准.最好使用全名(如America/Sao_Paulo或Europe/London),因为它们是Java的API使用的(您可以获得完整列表ZoneId.getAvailableZoneIds()
),并且它们配置了每个区域的所有DST更改.