首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >任意分配Java.Util.Calendar值

任意分配Java.Util.Calendar值
EN

Stack Overflow用户
提问于 2018-03-13 17:32:59
回答 2查看 97关注 0票数 2

我目前正在与Java.Util.Calendar作斗争。

我有一个方法可以创建一个Calendar,其中包含年、月和日的随机值。

代码语言:javascript
复制
public Calendar getRandomGeburtstag() {
        int year = 1999 - (int) (Math.random() * 80);
        int month = (int) (Math.random() * 12) + 1;
        int monthLength = 28;
        int day = (int) (Math.random() * monthLength) + 1;      
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.set(year, month, day);
        return calendar;
} 

我将这个日历存储在一个"Person“类中,该类有一个简单的getter方法。

然后,我在两个不同的场合请求该日历。在此期间,对象不会改变。打印日历会产生两种不同的输出:

代码语言:javascript
复制
java.util.GregorianCalendar[areAllFieldsSet=false,ERA=?,WEEK_OF_YEAR=?,WEEK_OF_MONTH=?,DAY_OF_YEAR=?,DAY_OF_WEEK=?,DAY_OF_WEEK_IN_MONTH=?,AM_PM=?,HOUR=?,HOUR_OF_DAY=?,MINUTE=?,SECOND=?,MILLISECOND=?,ZONE_OFFSET=?,DST_OFFSET=?]  

代码语言:javascript
复制
java.util.GregorianCalendar[areAllFieldsSet=true,ERA=1,WEEK_OF_YEAR=52,WEEK_OF_MONTH=5,DAY_OF_YEAR=362,DAY_OF_WEEK=4,DAY_OF_WEEK_IN_MONTH=4,AM_PM=0,HOUR=0,HOUR_OF_DAY=0,MINUTE=0,SECOND=0,MILLISECOND=0,ZONE_OFFSET=3600000,DST_OFFSET=0]

(我省略了保持不变的字段,它们都是在两个打印输出中设置的)

正如您所看到的,之前未设置的所有字段都在两个请求之间的某个位置获得了默认值或计算值。在请求之间不使用被拒绝的对象,所以它可能是JVM。

问题是,字段ZONE_OFFSET被我无法访问的方法使用。仅当给定ZONE_OFFSET=?时,才会打印所需的输出。

有什么方法可以停止自动分配这些值吗?

EN

回答 2

Stack Overflow用户

发布于 2018-03-13 17:48:27

这可能不是您正在寻找的答案,但使用java.time包编写会容易得多

代码语言:javascript
复制
public LocalDate getRandomGeburtstag() {
  LocalDate min = LocalDate.of(1919, 1, 1);
  LocalDate max = LocalDate.of(1999, 12, 31);
  long diff = max.toEpochDay() - min.toEpochDay();
  return LocalDate.ofEpochDay(min.toEpochDay() + (long) (Math.random() * diff));
} 

您当前的方法不会生成所有可能的天数,例如29、30、31。我假设这是一种变通方法,但当您在epoch millis上操作时不需要它。

票数 2
EN

Stack Overflow用户

发布于 2018-03-14 00:14:46

也许你可以在这些答案中找到更多关于Calendar怪异行为的信息:

基本上,当您调用set时,所有这些内部字段都不会自动重新计算,并且内部重新计算是任意的,您无法控制何时完成以及重新计算哪些字段。

最好的替代方案是使用ThreeTen后端,就像评论中建议的那样,这样你就可以使用LocalDate和java.time API的所有其他功能--它不会有这么大的Calendar混乱。

但是如果您坚持使用旧的API,那么还有一个(丑陋的)替代方案:

代码语言:javascript
复制
SimpleDateFormat sdf = new SimpleDateFormat("d-M-yyyy");
Date date = sdf.parse(day + "-" + month + "-" + year);

Calendar calendar = Calendar.getInstance();
calendar.setTime(date);

Date将时间字段设置为零,Calendar将设置所有字段(打印时不设置? )。

只需提醒一下,上面的月份值是从1到12,而在calendar.set方法中,接受的值是从0到11 (这是这个糟糕的API的另一个恼人的行为)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49252607

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档