在Android上使用Joda 1.6.2
下面的代码挂起了大约15秒。
DateTime dt = new DateTime();
我最初在Android Java - Joda Date is slow in Eclipse/Emulator -上发布了这篇文章
我又试了一次,还是没有好到哪里去。还有没有人有这个问题或者知道如何解决它?
发布于 2011-06-10 03:35:29
我也遇到了这个问题。Jon Skeet的怀疑是正确的,问题是时区的加载效率非常低,打开一个jar文件,然后读取清单来尝试获取此信息。
然而,仅仅调用DateTimeZone.setProvider([custom provider instance ...])
是不够的,因为出于一些我不理解的原因,DateTimeZone在调用getDefaultProvider()
的地方有一个静态初始化器。
为了完全安全,您可以在调用joda中的任何内容之前通过设置此系统属性来覆盖此默认值。
例如,在您的活动中添加以下内容:
@Override
public void onCreate(Bundle savedInstanceState) {
System.setProperty("org.joda.time.DateTimeZone.Provider",
"com.your.package.FastDateTimeZoneProvider");
}
然后你所要做的就是定义FastDateTimeZoneProvider
。我写了以下内容:
package com.your.package;
public class FastDateTimeZoneProvider implements Provider {
public static final Set<String> AVAILABLE_IDS = new HashSet<String>();
static {
AVAILABLE_IDS.addAll(Arrays.asList(TimeZone.getAvailableIDs()));
}
public DateTimeZone getZone(String id) {
if (id == null) {
return DateTimeZone.UTC;
}
TimeZone tz = TimeZone.getTimeZone(id);
if (tz == null) {
return DateTimeZone.UTC;
}
int rawOffset = tz.getRawOffset();
//sub-optimal. could be improved to only create a new Date every few minutes
if (tz.inDaylightTime(new Date())) {
rawOffset += tz.getDSTSavings();
}
return DateTimeZone.forOffsetMillis(rawOffset);
}
public Set getAvailableIDs() {
return AVAILABLE_IDS;
}
}
我已经测试过了,它似乎可以在带有joda 1.6.2版本的Android SDK 2.1+上工作。当然,它可以进一步优化,但在分析我的应用程序(mogwee)时,这将DateTimeZone初始化时间从~500ms减少到~18ms。
如果您使用proguard来构建您的应用程序,则必须将这一行添加到proguard.cfg中,因为Joda希望类名与您指定的完全相同:
-keep class com.your.package.FastDateTimeZoneProvider
发布于 2011-07-07 11:52:29
我只需要在我的应用程序中使用UTC。因此,按照unchek的建议,我使用了
System.setProperty("org.joda.time.DateTimeZone.Provider", "org.joda.time.tz.UTCProvider");
JodaTime实际上使用org.joda.time.tz.UTCProvider
作为辅助备份,所以我想为什么不使用它作为主要用途呢?到目前一切尚好。它加载得很快。
发布于 2014-03-09 21:33:01
如果你必须对你的日期进行精确的时区计算,plowman提供的最高答案是不可靠的。以下是可能发生的问题的示例:
假设您的DateTime
对象设置为凌晨4:00am,也就是夏令时开始后的一小时。当Joda在凌晨3:00之前(即夏令时之前)检查FastDateTimeZoneProvider
提供程序时,它将获得一个具有错误偏移量的DateTimeZone
对象,因为tz.inDaylightTime(new Date())
检查将返回false。
我的解决方案是采用最近发布的joda-time-android library。它使用Joda的核心,但确保仅在需要时才从原始文件夹加载时区。使用gradle设置起来很容易。在项目中,扩展Application
类并在其onCreate()
上添加以下内容
public class MyApp extends Application {
@Override
public void onCreate() {
super.onCreate();
JodaTimeAndroid.init(this);
}
}
作者去年在a blog post上写了关于它的文章。
https://stackoverflow.com/questions/5059663
复制相似问题