DatePickerDialog 错误地强制要求最短日期为 1970 年 1 月 1 日

Posted

技术标签:

【中文标题】DatePickerDialog 错误地强制要求最短日期为 1970 年 1 月 1 日【英文标题】:DatePickerDialog incorrectly enforcing a minimum date of Jan 1, 1970 【发布时间】:2012-01-27 02:13:11 【问题描述】:

我们有一个成员报告说他无法在我们的 DatePickerDialog 上设置 1970 年 1 月 1 日之前的日期。我们无法重现此问题。

我已经知道 DatePickerDialog 不公开底层 DatePicker 的 setMinDate/setMaxDate 函数,因此似乎某种手机制造商特定的修改正在影响 minDate/maxDate。

该用户报告说他在运行 2.2 Froyo 的 Verizon 上运行 Droid x2。虽然我们认为他对设备型号的描述是正确的,但许多用户对操作系统版本感到困惑,因此他可能运行的是 2.3。

我试图通过将这个主题添加到我的活动来解决这个问题:

<style name="profile_editor_theme">     
    <item name="android:endYear">2025</item>
    <item name="android:startYear">1910</item>
</style>

虽然我活动的这个主题具有在我的测试设备(Galaxy 选项卡和原始摩托罗拉 Droid)上限制 DatePickerDialog 的预期效果,但它显然对用户没有影响。

此问题 100% 为我们的用户重现,但在我们自己的设备上正常运行。

谁能解释这可能是什么原因以及我们如何解决它?

关于这件事我有filed this bug against Google。

谢谢!

【问题讨论】:

我们的一些用户(包括 Droid x2 用户)报告了同样的问题,我们也无法在内部进行重现。 在摩托罗拉 Razr 上也可以复制 有人有这方面的更新吗?我们仍在现场收到有关它的报告……不幸的是,无法使用 Razr :( 我有一部运行 Android 4.1.1 的 Sony Xperia 手机,它的日期选择器中不提供 1980 年之前的日期。 【参考方案1】:

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

我为您的案例找到了一种技巧。 这里我动态创建datePicker:

     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 年。因此,对我来说,这种方法有效。

希望对您有所帮助!

【讨论】:

仅供参考,这就是所谓的“Unix Epoch”或“Unix Time”,这也是我尽量避免使用它的原因之一。更多关于这里的主题:en.wikipedia.org/wiki/Unix_time 虽然是的,但 unixtime 通常是设备上时间表示的方法,尤其是对于“当前”日期(如文件修改时间),而 DatePicker 则不是这种情况,它有自己的内部表示,根据这里的来源:grepcode.com/file/repository.grepcode.com/java/ext/… 我们目前已经采用了这个解决方案,将看看市场的反应:)【参考方案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,因此任何声明这是最低要求的报告都会清楚地表明代码已执行且未被忽略/覆盖。我应该注意我还没有收到回复,这是否适用于报告的设备。

【讨论】:

【参考方案3】:

您好,我找到了解决方案。您可以在 setMinDate() 方法中设置 -ve 值,它对我有用。

dp.setMinDate(-1576800000000L);

【讨论】:

【参考方案4】:

我看到您已经尝试过类似的操作,但您是否尝试过设置以下内容:

android:startYear="1900"

直接在DatePicker XML 上?

像这样:

<DatePicker
          android:startYear="1900"
          android:endYear="2100"
          android:layout_
          android:layout_
></DatePicker>

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

【讨论】:

我们没有任何 DatePicker XML。 DatePickerDialog 是动态构造的。 DatePicker 本身由 DatePickerDialog 根据此来源分配:grepcode.com/file/repository.grepcode.com/java/ext/… 我似乎无法在文档中找到以编程方式设置 startDate 参数的方法,抱歉... 根据 DatePicker 源代码中的这些行: private static final int DEFAULT_START_YEAR = 1900;我不应该以编程方式设置它,而 Droid x2 能够这样做的事实表明某处存在错误....

以上是关于DatePickerDialog 错误地强制要求最短日期为 1970 年 1 月 1 日的主要内容,如果未能解决你的问题,请参考以下文章

Material UI:如何在 DatePicker 之外使用 DatePickerDialog?

强制大摇大摆地要求使用 springfox 进行基本的 http 身份验证

Android - 在 datepickerdialog 中隐藏日期字段

DatePickerDialog 结果返回到 Fragment?

如何修复 C# 中的“指定强制转换无效”错误?

Tomcat 8(和 9)强制行为,空字符串被错误地设置为空字符串