简而言之
Instant instant = Instant.now();
List < String > names =
ZoneId
.getAvailableZoneIds()
.stream()
.filter(
( String name ) ->
ZoneId
.of( name )
.getRules()
.getOffset( instant )
.equals(
ZoneOffset.ofHours( 6 )
)
)
.collect( Collectors.toList() )
;
在Java 14.0.1中:
names = [亚洲/喀什, Etc/GMT-6, 亚洲/阿拉木图, 亚洲/达卡, 亚洲/鄂木斯克, 亚洲/达卡, 印度/查戈斯, 亚洲/科斯塔纳伊, 亚洲/比什凯克, 南极洲/沃斯托克, 亚洲/乌鲁木齐, 亚洲/廷布, 亚洲/廷布]
java.time
现代解决方案使用
java.time类,多年前替换了可怕的遗留日期时间类。具体而言,
TimeZone
被以下内容替换:
UTC偏移仅是格林威治本初子午线之前或之后的小时-分钟-秒数。时区则更为复杂。时区是某个特定地区居民过去、现在和未来偏移变化的历史。时区以
大陆/地区
格式命名。请参见
时区列表。
获取 JVM 的当前时区。
ZoneId z = ZoneId.systemDefault() ;
获取当前定义的所有
ZoneId
对象列表。请注意,时区经常被政治家更改。因此,这个列表和它们包含的规则将会发生变化。请保持您的
tzdata更新。
Set< String > zones = ZoneId.getAvailableZoneIds()
你提问:
我想知道如何从时区偏移量中获取时区名称。
在任何给定的时刻,许多时区可能巧合地共享相同的偏移量。在下面的代码中,我们循环所有已知的时区,询问每个时区的偏移量。
由于时区规则随时间改变(由政治家确定),您必须提供您想要每个区域使用的偏移量的时刻。这里我们在运行时使用当前时刻。
int milliseconds = 21_600_000;
int seconds = Math.toIntExact( TimeUnit.MILLISECONDS.toSeconds( milliseconds ) );
ZoneOffset targetOffset = ZoneOffset.ofTotalSeconds( seconds );
Instant now = Instant.now();
List < ZoneId > hits = new ArrayList <>();
Set < String > zoneNames = ZoneId.getAvailableZoneIds();
for ( String zoneName : zoneNames )
{
ZoneId zoneId = ZoneId.of( zoneName );
ZoneRules rules = zoneId.getRules();
ZoneOffset offset = rules.getOffset( now );
if ( offset.equals( targetOffset ) )
{
hits.add( zoneId );
}
}
将内容输出到控制台。请参考 IdeOne.com上的实时代码运行。
System.out.println( "java.version " + System.getProperty("java.version") ) ;
System.out.println( "java.vendor " + System.getProperty("java.vendor") ) ;
System.out.println() ;
System.out.println( "targetOffset = " + targetOffset );
System.out.println( "hits: " + hits );
在IdeOne.com上查看此代码的实时运行情况。
java.version 12.0.1
java.vendor Oracle Corporation
targetOffset = +06:00
命中次数:[Asia/Kashgar,Etc/GMT-6,Asia/Almaty,Asia/Dacca,Asia/Omsk,Asia/Dhaka,Indian/Chagos,Asia/Qyzylorda,Asia/Bishkek,Antarctica/Vostok,Asia/Urumqi,Asia/Thimbu,Asia/Thimphu]
关于 java.time
java.time 框架已经内置于 Java 8 及以上版本。这些类取代了老旧的 传统 日期时间类,如 java.util.Date
、Calendar
和 SimpleDateFormat
。
要了解更多,请参阅
Oracle教程。并在Stack Overflow上搜索许多示例和解释。规范是
JSR 310。
Joda-Time 项目现在处于
维护模式,建议迁移到
java.time 类。
你可以直接使用
java.time 对象与数据库进行交换。使用符合
JDBC 4.2 或更高版本的
JDBC 驱动程序。无需字符串,不需要
java.sql.*
类。Hibernate 5 和 JPA 2.2 支持
java.time。
如何获取
java.time 类?
TimeZone.getDefault()
?这段代码应该改为String[] ids = TimeZone.getAvailableIds(21600000L);
。避免像实例方法一样调用静态方法。 - Jon Skeet