Using Joda-Time to get UTC offset for a given date and timezone
我的日期格式为20Jan2013,08Aug2012等,具有自己的特定时区。例如,20Jan2013可能具有澳大利亚/墨尔本的时区ID,而08Aug2012可能具有欧洲/伦敦的ID。我想要做的是,根据这些时区和日期,计算给定日期该时区的UTC偏移量。到目前为止我已经想出了这个:
1 2 3 4 5 6 7 8 | DateTimeFormatter dtf = DateTimeFormat.forPattern("ZZ"); DateTimeFormatter dtf1 = DateTimeFormat.forPattern("ddMMMYYYY"); DateTimeZone zone = DateTimeZone.forID("Australia/Melbourne"); DateTime thisDate = dtf1.parseDateTime("30Jul2013"); System.out.println(" Zone:" + thisDate.withZone(zone)); |
这给了我输出:
1 | Zone: 2013-07-30T00:00:00.000+10:00 |
这是正确的,但我想从中提取UTC偏移量,在这种情况下为+10:00。我已经找到了办法,但找不到任何东西。有什么方法可以做到这一点吗?我看到的唯一选择是将输出转换为String并使用substring方法获取UTC偏移量。
上面的代码确实考虑了夏令时(夏令时)。例如,如果我有:
DateTime thisDate = dtf1.parseDateTime("30Jan2013"??);
输出将是:2013-01-30T00:00:00.000 + 11:00
(+11:00而不是+10:00)
所以基本上我需要做的是找到一种从2013-07-30T00:00:00.000 + 11:00提取+11:00的方法。请帮忙!
获取时区名称和偏移量的简单方法
1 2 3 4 5 6 7 8 9 10 11 12 13 | public static String getCurrentTimeZoneOffset() { DateTimeZone tz = DateTimeZone.getDefault(); Long instant = DateTime.now().getMillis(); String name = tz.getName(instant); long offsetInMilliseconds = tz.getOffset(instant); long hours = TimeUnit.MILLISECONDS.toHours( offsetInMilliseconds ); String offset = Long.toString( hours ); return name +" (" + offset +" Hours)"; // Example:"Mountain Standard Time (-7 Hours)" } |
情侣警告:
-
这从JodaTime获取默认的
DateTimeZone 。您可以修改它以接受传递给方法的特定DateTimeZone。 - 这将以"山地标准时间(-7小时)"等格式返回,但您可以根据需要轻松地对其进行格式化。
希望有所帮助。
J.P
为了让Joda给出正确的偏移量,你必须提供一个日期时间瞬间。没有日期时刻,由于我们有不同的偏移(夏令时),所以无法计算偏移量。这就是我如何使用Joda来获得+ HH:mm格式的偏移量:
1 2 3 4 |
如果您只需要时区偏移量,请使用
您需要立即计算到UTC的偏移量可能看起来很奇怪,但这需要考虑夏令时以及时区的变化。是的,各国偶尔改变他们的时区:
Why does timezone data change?
Timezone settings are adopted locally, and there is no world timezone authority.
编辑这为您提供了正确的结果:
1 2 3 4 5 6 7 | DateTimeFormatter dtf1 = DateTimeFormat.forPattern("ddMMMYYYY"); DateTimeZone zone = DateTimeZone.forID("Australia/Melbourne"); DateTime thisDate = dtf1.parseDateTime("30Jul2013").withZone(zone); assertEquals( 10 * CommonConstants.MILLISECONDS_PER_HOUR, zone.getOffset( thisDate ) ); |
thisDate.get
Java 8引入了更好的日期和时间处理,以解决该领域中某些语言以前的局限性。我的一些项目已经开始使用它而不是Joda。
使用java.time包:
1 2 3 4 5 6 | ZonedDateTime dateTime = LocalDate.of(2013 , 1 , 20).atStartOfDay( ZoneId.of("Australia/Melbourne")); ZoneOffset zo = dateTime.getOffset(); int offset = zo.getTotalSeconds(); long hours = TimeUnit.SECONDS.toHours(offset); long minutes = TimeUnit.SECONDS.toMinutes(offset % 3600); |
hours变量设置为11,分钟设置为0。
它还计算了部分小时数的分钟偏移量,例如加拿大东部的纽芬兰和拉布拉多:
1 | ZonedDateTime dateTime = LocalDate.of(2013, 1, 20).atStartOfDay( ZoneId.of("Canada/Newfoundland")); |
在这种情况下,偏移量
对于String表示,而不是整数小时和分钟,请使用ZoneOffset的toString()方法。因此,对于上面的示例,请使用:
1 |
当您知道偏移量和时间戳时,为了获得当前时间,您可以使用
1 2 3 | public static String formatMonthDayMinuteByGivenUtcOffset(long timestamp, int offset) { return JODA_FORMATTER.print(createDateTime(timestamp, offset)); } |