使用Zeller方法的一周中的某一天& Java的

时间:2017-10-15 19:17:57

标签: java date calendar dayofweek

我无法获得Zeller方法代码的正确输出,这可能是输出给定日期的星期几。

声明int f后,如果数字小于零,我不知道如何修复if语句。这是我的一大块代码:

if (month == 1 || month == 2) 
{
    month += 12;
    year--;
} else {
    month-=2;
}

scan.close();        

int m = month;
int d = year % 100; 
int c = (year / 100); 
int k = day;         
int f = (k + (int)((13 * m - 1) / 5.0) + d + (int)(d / 4.0) + (int)(c / 4.0) + (2 * c));        

if (f<=0) 
{
    f= f % 7;
    else
}  

/*   
if (f>0)
{   
    //?
}   
*/

String last = ("Day of the week: ");
System.out.println(f);

1 个答案:

答案 0 :(得分:2)

我正在使用wikipedia中所述的公式。有些细节与您的代码不同:

  • 月值为3 = March, 4 = April, 5 = May, ..., 14 = February。因此,您的else { month-=2; }不需要:只有1月和2月必须调整为13和14,所有其他月份必须保持不变。
  • 我更改了变量名称以匹配维基百科的公式:
    • h是星期几(0 = Saturday, 1 = Sunday, 2 = Monday, ..., 6 = Friday
    • q是该月的某一天
    • m是月份(3 = March, 4 = April, 5 = May, ..., 14 = February
    • K世纪年
    • J是零基础世纪

另一个细节(也是explained in the same article),模数实现可能因负数而异:

  

... -2 mod 7等于正5.不幸的是,大多数计算机语言实现余数函数的方式,-2 mod 7返回-2的结果。

在Java中(我使用的是JDK 1.8.0_144),这种情况也会发生(-2 % 7等于-2),一种解决方法就是add 7 to the final result 。所以代码将是这样的:

// adjust January to 13 and February to 14
if (month == 1 || month == 2) {
    month += 12;
    year--;
}

int j = year / 100;
int k = year % 100;
int q = day;

// using temporary variables to make code cleaner (IMO)
int tmp1 = (13 * (month + 1)) / 5;
int tmp2 = k / 4;
int tmp3 = j / 4;
int h = (q + tmp1 + k + tmp2 + tmp3 - (2 * j)) % 7;
// if result is negative, fix
if (h < 0) {
    h += 7;
}

因此,h星期六为0,星期日为1,依此类推。我已经测试了1900年到2100年的日期,它运行良好。

在维基百科的文章中,还有另一种避免否定结果的公式:只需更改- 2J的{​​{1}}:

+ 5J

这会得到相同的结果,但// change "- (2 * j)" to "+ (5 * j)" int h = (q + tmp1 + k + tmp2 + tmp3 + (5 * j)) % 7; 将始终为正(因此不需要h)。

Java新日期/时间API

如果您为了学习目的而制作此代码,那就没问题了。但对于商业应用程序,最好使用正确的日期/时间API。

如果您使用 Java 8 ,请考虑使用new java.time API。它更容易,less bugged and less error-prone than the old APIs

如果您使用 Java 6或7 ,则可以使用ThreeTen Backport,这是Java 8新日期/时间类的绝佳后端。对于 Android ,您还需要ThreeTenABP(更多关于如何使用它here)。

以下代码适用于两者。 唯一的区别是包名称(在Java 8中为if (h < 0)而在ThreeTen Backport(或Android的ThreeTenABP中)为java.time),但类和方法名称是一样的。

从特定日期获取星期几的简单方法是使用org.threeten.bp课程,然后从中获取LocalDate

DayOfWeek

唯一的区别是LocalDate dt = LocalDate.of(year, month, day); DayOfWeek dayOfWeek = dt.getDayOfWeek(); // getValue() returns values from 1 (Monday) to 7 (Sunday) int value = dayOfWeek.getValue(); 方法根据ISO定义返回值,从1(星期一)到7(星期日)。但是,如果您需要Zeller方法返回的相同值,则可以执行以下操作:

getValue()