设置DAY_OF_WEEK返回意外结果 [英] Setting DAY_OF_WEEK returns unexpected result

查看:45
本文介绍了设置DAY_OF_WEEK返回意外结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将给定日历实例的时间戳设置为一周的开始时间(星期一),而是返回一个看起来完全无关的时间戳-除非我在访问日历之前未访问任何字段。我在下面提供了一个示例,也请在 Ideone 中看到此可运行的示例。

I want to set a given calendar instance's timestamp to the beginning of the week (Monday) and instead it returns a seemingly completely unrelated timestamp - unless I access any of the calendar's fields before doing so. I include a sample below, please also see this runnable example in Ideone.

这是预期的行为吗?这背后的逻辑是什么?是的,我听说过乔达时间。

Is this expected behavior? What's the logic behind this? And yes, I've heard of Joda Time.

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Locale;
import java.util.TimeZone;


class MyTest {

private static Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("CET"), Locale.FRANCE);
private static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");

public static void main(String[] args) {

    // Set to any date.
    calendar.set(2013, 10, 3);
    System.out.println(dateFormat.format(calendar.getTime()));

    // Set to another day.
    calendar.set(2014, 0, 15);
    // --- THE WTF STARTS HERE ---
    // Uncommenting the line below returns the correct date in the end.
    // calendar.getTime();

    // Set to monday of current week.
    calendar.set(Calendar.DAY_OF_WEEK, calendar.getFirstDayOfWeek());

    // Expected outdate is 20140113
    System.out.println(dateFormat.format(calendar.getTime()));

}

}


推荐答案

文档中的字段操作一章对此进行了清楚的说明。

Field Manipulation chapter in the docs explains it clearly. It just works weird though.

http://docs.oracle.com/javase/6/docs/api/java/util/Calendar.html

示例:考虑一个最初设置为1999年8月31日的GregorianCalendar。调用
set(Calendar.MONTH,Calendar.SEPTEMBER)将日期设置为1999年9月31日。
这是一个临时内部表示形式,如果随后调用
getTime(),则解析为1999年10月1日。但是,在
调用getTime()之前调用set(Calendar.DAY_OF_MONTH,30)将日期设置为1999年9月30日,因为set()本身之后
不会重新计算。

Example: Consider a GregorianCalendar originally set to August 31, 1999. Calling set(Calendar.MONTH, Calendar.SEPTEMBER) sets the date to September 31, 1999. This is a temporary internal representation that resolves to October 1, 1999 if getTime()is then called. However, a call to set(Calendar.DAY_OF_MONTH, 30) before the call to getTime() sets the date to September 30, 1999, since no recomputation occurs after set() itself.

编辑

从日历字段解析部分相同的文档

From the Calendar Fields Resolution part of the same doc

If there is any conflict in calendar field values, Calendar gives priorities to 
calendar fields that have been set more recently. The following are the default 
combinations of the calendar fields. The most recent combination, as determined 
by the most recently set single field, will be used.

For the date fields:

 YEAR + MONTH + DAY_OF_MONTH
 YEAR + MONTH + WEEK_OF_MONTH + DAY_OF_WEEK
 YEAR + MONTH + DAY_OF_WEEK_IN_MONTH + DAY_OF_WEEK
 YEAR + DAY_OF_YEAR
 YEAR + DAY_OF_WEEK + WEEK_OF_YEAR

我认为MONTH和DAY_OF_WEEK是这个。如果在最后一条语句中设置MONTH,则它将与YEAR + MONTH + DAY_OF_MONTH匹配,并覆盖所有这些。如果您将DAY_OF_WEEK设置为YEAR + DAY_OF_WEEK + WEEK_OF_YEAR,则不会覆盖月份值。或类似的东西。老实说,我越看越破碎。这根本没有意义。最好继续使用JodaTime

I think the difference between MONTH and DAY_OF_WEEK is this. If you set MONTH at the last statement it matches with YEAR+MONTH+DAY_OF_MONTH and overrides all of them. If you set DAY_OF_WEEK it matches with YEAR+DAY_OF_WEEK+WEEK_OF_YEAR so doesn't override the month value. Or something like that. To be honest, the more I look the more broken it seems. It doesn't make sense at all. Better keep using JodaTime

这篇关于设置DAY_OF_WEEK返回意外结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆