【问题标题】:DAY_OF_WEEK always returns 7 in Java GregorianCalendarDAY_OF_WEEK 在 Java GregorianCalendar 中总是返回 7
【发布时间】:2014-10-17 13:30:22
【问题描述】:

所以我想用 Java GregorianCalendar 做一些事情,这似乎比它应该做的要困难得多。我想从月份和日期中获取星期几。但它不会那样做。我知道人们经常得到错误的答案,因为他们不知道月份从 0 开始编号,而 DAY_OF_WEEK 从 1 开始编号(例如 herehere)。但这不是我的问题。我的问题是 DAY_OF_WEEK 总是返回 7,无论我将日期设置为什么。当我将 GregorianCalendar 转换为字符串时,DAY_OF_WEEK 显示为?,即使我设置了年、月和日。

发生这种情况的代码:

GregorianCalendar theDate;

public ObservableDate(int year, int month, int dayOfMonth, int hourOfDay, int minute, int second)
{
    theDate = new GregorianCalendar(year, month, dayOfMonth, hourOfDay, minute, second);
    theDate.setFirstDayOfWeek(GregorianCalendar.SUNDAY);
    System.out.println("DAY_OF_WEEK = "+theDate.DAY_OF_WEEK);
    System.out.println(theDate.toString());
}

调用它的代码:

    ObservableDate theDate = new ObservableDate(2001, 3, 24, 9, 00, 00);

输出:

DAY_OF_WEEK = 7
java.util.GregorianCalendar[time=?,areFieldsSet=false,areAllFieldsSet=false,lenient=true,zone=sun.util.calendar.ZoneInfo[id="America/New_York",offset=-18000000,dstSavings=3600000,useDaylight=true,transitions=235,lastRule=java.util.SimpleTimeZone[id=America/New_York,offset=-18000000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=3,startMonth=2,startDay=8,startDayOfWeek=1,startTime=7200000,startTimeMode=0,endMode=3,endMonth=10,endDay=1,endDayOfWeek=1,endTime=7200000,endTimeMode=0]],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=?,YEAR=2001,MONTH=3,WEEK_OF_YEAR=?,WEEK_OF_MONTH=?,DAY_OF_MONTH=24,DAY_OF_YEAR=?,DAY_OF_WEEK=?,DAY_OF_WEEK_IN_MONTH=?,AM_PM=0,HOUR=9,HOUR_OF_DAY=9,MINUTE=0,SECOND=0,MILLISECOND=?,ZONE_OFFSET=?,DST_OFFSET=?]

知道为什么会这样吗?

【问题讨论】:

标签: java calendar dayofweek gregorian-calendar


【解决方案1】:

您正在访问字段常量而不是获取其值。我相信你想使用类似的东西,

System.out.println("DAY_OF_WEEK = " + theDate.get(Calendar.DAY_OF_WEEK));

【讨论】:

  • 啊,所以它就像一个枚举。
  • 啊。是的,做到了,谢谢! (稍作修改,我需要使用 GregorianCalendar 而不是 Calendar。)
  • 你如何使用它?无论如何,您的解决方案是给我 7 号。
【解决方案2】:

您的问题是您正在访问 Calendar 类 (Calendar.DAY_OF_WEEK) 中的常量 DAY_OF_WEEK

要正确获取星期几,请使用theDate 变量的.get() 方法,如下所示:

theDate.get(Calendar.DAY_OF_WEEK);

【讨论】:

    【解决方案3】:

    tl;博士

    对于智能 DayOfWeek 枚举对象。

    ZonedDateTime.of( 2001 , 3 , 24 , 9 , 0 , 0 , 0 , ZoneId.of( "Pacific/Auckland" ) )  // Moment as seen by people in a certain region (time zone).
                 .getDayOfWeek()                                                         // Extract a `DayOfWeek` enum object to represent that day-of-week of that moment.
    

    对于周一至周日的整数 1-7。

    ZonedDateTime.of( 2001 , 3 , 24 , 9 , 0 , 0 , 0 , ZoneId.of( "Pacific/Auckland" ) )
                 .getDayOfWeek()
                 .getValue()                                                             // Translate that `DayOfWeek` object into a mere integer 1-7 for Monday-Sunday.
    

    java.time

    现代方法使用 java.time 类来取代麻烦的旧旧日期时间类。 Calendar 替换为 ZonedDateTime

    ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
    ZonedDateTime zdt = ZonedDateTime.of( 2001 , 3 , 24 , 9 , 0 , 0 , 0 , z );
    

    DayOfWeek 枚举为一周中的每一天定义了七个对象。

    DayOfWeek dow = zdt.getDayOfWeek() ;  // Get `DayOfWeek` enum object representing this moment’s day-of-week.
    

    您可以ask the DayOfWeek 本地化当天的名称。

    我建议在您的代码库中使用这些 DayOfWeek 对象,而不仅仅是整数。但如果你坚持,你可以得到一个号码。与GregorianCalendar 不同,这些数字具有固定含义,不会因地区而异。根据ISO 8601 标准,周一至周日的含义是1-7。

    int dowNumber = zdt.getDayOfWeek().getValue() ;  // 1-7 for Monday-Sunday per ISO 8601.
    

    不可变对象

    注意 java.time 使用immutable objects。不是更改对象上的成员变量(“mutate”),而是调用调整值生成一个新对象,而原始对象保持不变。

    ZonedDateTime zdtTomorrow = zdt.now( z ).plusDays( 1 ) ;  // Alterations result in a new object, leaving original intact. Known as *immutable objects*.
    

    时区

    您未能在构造函数的参数和传递给new GregorianCalendar 的参数中指定时区。在这种情况下,JVM 的当前默认时区是隐式分配的。该默认值可能因机器而异,甚至可以在运行时期间随时更改。最好指定您想要/预期的时区。

    continent/region 的格式指定proper time zone name,例如America/MontrealAfrica/CasablancaPacific/Auckland。切勿使用 3-4 个字母的缩写,例如 ESTIST,因为它们不是真正的时区,没有标准化,甚至不是唯一的 (!)。

    ZoneId z = ZoneId.of( "America/Montreal" ) ;  
    

    八进制数

    注意您的 00 文字值。前导零表示octal base-8 number,而不是 Java 源代码中的十进制数字。你很幸运,因为八进制零也是十进制零。


    关于java.time

    java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.DateCalendarSimpleDateFormat

    Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。

    要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310

    从哪里获得 java.time 类?

    ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如IntervalYearWeekYearQuartermore

    【讨论】:

      猜你喜欢
      • 2013-03-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-01
      • 2015-09-14
      • 1970-01-01
      • 2021-06-05
      • 2011-12-13
      相关资源
      最近更新 更多