日期选择对话框错误地强制要求最小日期为1970年1月1日。

9
我们收到一位会员的报告,他无法在我们的DatePickerDialog中设置1970年1月1日之前的日期。我们无法重现此问题。
我已经知道DatePickerDialog没有公开其底层DatePicker的setMinDate/setMaxDate函数,因此似乎某些手机制造商特定的修改影响了minDate/maxDate。
该用户报告称他正在运行Verizon上的Droid x2,运行2.2 Froyo。虽然我们相信他对设备型号的描述是正确的,但许多用户对操作系统版本感到困惑,所以他可能正在运行2.3。
我尝试通过将此主题添加到我的Activity来解决此问题:
<style name="profile_editor_theme">     
    <item name="android:endYear">2025</item>
    <item name="android:startYear">1910</item>
</style>

虽然我的活动主题在我的测试设备上(Galaxy Tab和原始Motorola Droid)限制了DatePickerDialog,但对用户显然没有影响。

我们的用户每次都会遇到这个问题,但我们自己的设备上却可以正常工作。

有人能解释一下可能是什么原因导致这种情况,以及我们如何修复它吗?

我已经在此事上向Google 报告了这个错误

谢谢!


我们的一些用户(包括一个Droid x2用户)报告了相同的问题,但我们在内部无法重现。 - greg7gkb
同时在摩托罗拉Razr上也有这个问题。 - HannahMitt
有人对此有更新吗?我们仍然在现场收到报告...不幸的是没有Razr的访问权限 :( - greg7gkb
我有一部运行Android 4.1.1系统的索尼Xperia手机,但它的日期选择器不支持1980年之前的日期。 - jrg
4个回答

2

你好,我找到了解决办法。你可以在setMinDate()方法中设置负值,这对我很有效。

dp.setMinDate(-1576800000000L);

2

Android设备的起始日期是从1970年1月1日开始计算的。也许这也适用于你的情况。Android将时间计算为自1970年1月1日以来经过的毫秒数。

我找到了一种针对你情况的解决方案。在这里,我动态创建了一个日期选择器:

     DatePicker dp = new DatePicker(this);
     dp.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
     v.addView(dp);

在清单文件中,我声明了一个自定义主题用于我的应用程序 - 我希望应用程序使用相同的主题。顺便说一下,您也可以为活动执行相同操作。
 <application
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name" 
    android:theme="@style/CustomTheme">
    <activity
        android:name=".HelloDatePickerActivity"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

在 styles.xml 文件中,我这样做:
<style name="CustomTheme" parent="android:Theme.Light">
    <item name="android:startYear">1890</item>
</style>

在我的情况下,默认的开始日期是1900年。因此,对我来说,这种方法是可行的。

希望这能帮到你!


3
仅供参考,这就是所谓的“Unix纪元”或“Unix时间”,这也是我尽可能避免使用它的原因之一。更多相关内容请见:http://en.wikipedia.org/wiki/Unix_time - Telmo Marques
虽然Unix时间戳通常是设备上表示时间的方法,特别是对于“当前”日期(例如文件修改时间),但对于DatePicker来说并非如此,它有自己的内部表示方式,正如这个来源所指出的:http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.2_r1.1/android/widget/DatePicker.java#DatePicker。 - esilver
我们现在采用了这个解决方案,看看市场的反应如何 :) - greg7gkb

2

我意识到这个问题有点老了,而且这个答案不适用于旧设备,但我最近在一个新设备(Huawei Mediapad 7 Youth)上发现了这个问题,所以我想更新一下这个问题的信息:

从API 11开始,必要的方法已经被公开。请记住,虽然Calendar可能使用Unix Epoch作为零,但Java(至少直到~JRE 8?)使用带符号的数字,因此负数是完全可以接受的。幸运的是,你不需要完全了解这一点,因为这段代码可以正常运行:

// This is API 11!
try {
    // Hack to (try to) force minDate to 1888 instead of 1970.
    DatePicker dp = dialog.getDatePicker();
    Calendar minCal = Calendar.getInstance();
    minCal.set(1888, Calendar.JANUARY, 1, 0, 0, 0);
    dp.setMinDate(minCal.getTimeInMillis());

    if (maxDate > 0)
        dp.setMaxDate(maxDate);
} catch (NoSuchMethodError e) {
    Log.w(TAG, "Can't set min/max dates: device/Android version is too old.");
}

我使用了1888这个数字,以便任何声称最低值是这个的报告都能清楚地表明代码已被执行而不是被忽略/覆盖。我应该注意到我还没有收到关于这是否适用于报告设备的回复。

编辑:这是一个旧帖子。我认为我确实得到了确认,但我现在记不起来了。此外,与其使用try-catch,更好的做法是检查API版本。自从这篇帖子写出以来,我学到了很多东西。:)


在我的情况下,我让它变得简单: val minDate = Calendar.getInstance().apply { this.set(Calendar.YEAR, 1900) }.timeInMillis datePicker.minDate = minDate - Aleksandr A

0

我看到你已经尝试了类似的东西,但你是否尝试设置以下内容:

android:startYear="1900"

可以直接在DatePicker的XML文件中实现吗?

像这样:

<DatePicker
          android:startYear="1900"
          android:endYear="2100"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
></DatePicker>

参考链接: http://kevsaidwhat.blogspot.com/2011/10/fun-with-android-datepicker-and-1970.html


我们没有任何DatePicker XML。DatePickerDialog是动态构建的。DatePicker本身由DatePickerDialog根据此源代码分配:http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.2_r1.1/android/app/DatePickerDialog.java?av=f - esilver
很抱歉,我在文档中找不到以编程方式设置“startDate”参数的方法。 - Telmo Marques
根据DatePicker源代码中的这些行:private static final int DEFAULT_START_YEAR = 1900;我不应该需要通过编程来设置它,而Droid x2能够这样做表明存在某些问题... - esilver

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接