首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >安卓java.util.Calendar -时差

安卓java.util.Calendar -时差
EN

Stack Overflow用户
提问于 2009-07-29 04:37:41
回答 3查看 12.6K关注 0票数 2

我的想法是:如果我可以计算从基准日期(在我的例子中,是1989-12-31)以来的周数,就很容易知道偏移量。

我的问题是:首先,我从基准日期得到毫秒值。我将毫秒设置为另一个日历对象。我期望从该对象获得相同的日期。但实际上是不同的日期。

代码语言:javascript
复制
mBaseDateInMillis = mBaseDate.getTimeInMillis();
mAnotherDate.setTimeInMillis(mBaseDateInMillis);
/* I expect mBaseDate == mAnotherDate.
 * but it was different.
 */ 

下面是我的代码:

代码语言:javascript
复制
public class CalendarCoordinate {
    public static final long ONEWEEK_IN_MILLISECONDS = 60 * 60 * 24 * 7 * 1000;
    public Calendar mBaseDate = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
    public long mBaseDateInMillis = 0;
    public Calendar mDate = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
    public int  mWeekHeight = 30;

    /**
     * CTOR
     */
    public CalendarCoordinate() {
        /* Base date is 1989-12-31 0, 0, 0
         * It was Sunday and offset 0 will be mapped onto this day.
         */
        mBaseDate.set(Calendar.MILLISECOND, 0);
        mBaseDate.set(1989, 12, 31, 0, 0, 0);
        mBaseDateInMillis = mBaseDate.getTimeInMillis();
        Log.v(TAG, "BaseDate:" + mBaseDate.toString());
    }

    /**
     * Compute DATE from Y-Offset
     * @param yOffset
     * @return
     */
     public Calendar dateFromYOffset(int yOffset) {
        long nthWeeks = yOffset / mWeekHeight;
        long millsSinceBaseDate = nthWeeks * ONEWEEK_IN_MILLISECONDS;
        mDate.clear();
        mDate.set(Calendar.MILLISECOND, 0);
        mDate.setTimeInMillis(mBaseDateInMillis + millsSinceBaseDate);

        /* We SHOULD call to update mDate internal data structure. 
         * Java is really strange for this thing
         **/
        mDate.getTimeInMillis();
        return mDate;
    }

    /**
     * Compute Y-Offset from DATE
     * @param date
     * @return
     */
    public long yOffsetFromDate(Calendar cal) {
        long mills = cal.getTimeInMillis();
        long nthWeeks = (mills - mBaseDateInMillis)/ONEWEEK_IN_MILLISECONDS;
        return nthWeeks * mWeekHeight;
    }
}

有人能帮我吗?我不是一个好的Java程序员。

EN

回答 3

Stack Overflow用户

发布于 2009-07-29 04:50:03

这句话让我很困惑:

代码语言:javascript
复制
/* I expect mBaseDate == mAnotherDate.
 * but it was different.
 */

你是否真的想通过比较来检查相等性: if (mBaseDate == mAnotherDate) {System.out.println(“他们是相同的”);}

如果是这样,您的问题是您误解了"==“运算符在Java语言中的工作方式。它比较引用,而不是比较底层对象数据,因为这些是永远为false的不同对象(具有相同的值)。有关更多详细信息,请参阅Java Notes on comparison operators

另外,在我看来,这几行代码非常可疑:

代码语言:javascript
复制
/* We SHOULD call to update mDate internal data structure. 
* Java is really strange for this thing
**/
mDate.getTimeInMillis();

如果Android有一个bug需要你这样做,我真的会很惊讶,但我想一切都是可能的。如果没有这个电话,你会遇到什么问题?

票数 5
EN

Stack Overflow用户

发布于 2009-07-29 04:51:55

这是因为您需要使用"equals“方法来比较不同的对象。使用运算符"==“将告诉您对象是否相同(它们是否位于完全相同的内存位置),而"equals”比较函数将告诉您两个对象在逻辑上是否相等。

票数 3
EN

Stack Overflow用户

发布于 2016-07-10 06:52:39

tl;dr

代码语言:javascript
复制
long weeks = ChronoUnit.WEEKS.between ( LocalDate.of ( 1989 , 12 , 31 ) , LocalDate.of ( 1990 , 1 , 14 ) ); // Results: 2

避免从纪元开始计数

不要在诸如毫秒这样的计时开始的模式下工作。令人困惑,掩盖错误,并忽略时区等问题。

让一个好的日期-时间库来完成这些计算中的繁重任务。

java.time

您正在使用麻烦的旧日期-时间类,如java.util.Calendar。这些设计不佳的类已经被Java8和更高版本中内置的java.time框架所取代。参见Oracle Tutorial。在ThreeTen-Backport中,java.time的大部分功能已经移植到Java6和7中,并在ThreeTenABP中进一步适用于安卓。

ChronoUnit

ChronoUnit类计算经过的时间,例如一对LocalDate (仅日期,没有时间,也没有时区)值之间的整周数。

代码语言:javascript
复制
    LocalDate start = LocalDate.of ( 2016 , 1 , 1 );
    LocalDate stop = start.plusDays ( 17 ); // Ex: 13 days = 1 week. 14 days = 2 weeks.

    long weeks = ChronoUnit.WEEKS.between ( start , stop );

转储到控制台。

代码语言:javascript
复制
    System.out.println ( "start: " + start + " | stop: " + stop + " | weeks: " + weeks );

开始时间: 2016-01-01 |停止时间: 2016-01-18 |周:2

如果您想要从1989-12-31开始的几周数,可以使用它作为上面看到的start对象。

代码语言:javascript
复制
LocalDate start = LocalDate.of( 1989 , 12 , 31 );

半开

但我注意到你的基准日期是一年的最后一天。提示:时间跨度通常最好用半开放方法处理,这种方法的开始是包容的,而结束是排他的。因此,您可能希望使用1990-01-01作为基准日期(我不知道您的业务逻辑,所以我只是猜测)。

所以你的前两周应该是这样的(1-15):

代码语言:javascript
复制
long firstTwoWeeks = ChronoUnit.WEEKS.between ( LocalDate.of ( 1990 , 1 , 1 ) , LocalDate.of ( 1990 , 1 , 15 ) );

…而不是这个(31-14):

代码语言:javascript
复制
long firstTwoWeeks = ChronoUnit.WEEKS.between ( LocalDate.of ( 1989 , 12 , 31 ) , LocalDate.of ( 1990 , 1 , 14 ) );
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1198068

复制
相关文章

相似问题

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