让我解释一下。通过了解日期的周数和年份:
Date curr = new Date();
Calendar cal = Calendar.getInstance();
cal.setTime(curr);
int nweek = cal.WEEK_OF_YEAR;
int year = cal.YEAR;
但是现在我不知道如何获取该周第一天的日期。我一直在寻找日历、日期、日期格式,但没有什么可能有用的......
有什么建议吗? (用Java工作)
这些字段不返回值。这些是 constants ,它标识
Calendar
对象中您可以获取/设置/添加的字段。为了实现你想要的,你首先需要得到一个Calendar
,清除它并设置已知值。它会自动将日期设置为该周的第一天。
// We know week number and year.
int week = 3;
int year = 2010;
// Get calendar, clear it and set week number and year.
Calendar calendar = Calendar.getInstance();
calendar.clear();
calendar.set(Calendar.WEEK_OF_YEAR, week);
calendar.set(Calendar.YEAR, year);
// Now get the first day of week.
Date date = calendar.getTime();
请学会阅读javadocs以了解如何使用类/方法/字段,并且不要尝试在 IDE 中随意查看;)
也就是说,
java.util.Date
和java.util.Calendar
是史诗般的失败。如果可以的话,请考虑切换到Joda Time。
试试这个:
public static Calendar setWeekStart(Calendar calendar) {
while (calendar.get(Calendar.DAY_OF_WEEK) != Calendar.MONDAY) {
calendar.add(Calendar.DATE, -1);
}
setDayStart(calendar); // method which sets H:M:S:ms to 0
return calendar;
}
java.util
日期时间 API 及其格式化 API SimpleDateFormat
已过时且容易出错。建议完全停止使用它们并切换到现代日期时间 API*。
另外,下面引用来自Joda-Time主页的通知:
请注意,从 Java SE 8 开始,用户被要求迁移到 java.time (JSR-310) - JDK 的核心部分,它将取代该项目。
使用现代日期时间 API
java.time
的解决方案:
import java.time.LocalDate;
import java.time.temporal.WeekFields;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
// Test
int weekNumber = 34;
int year = 2021;
System.out.println(getFirstDayOfWeek(year, weekNumber, Locale.UK));
System.out.println(getFirstDayOfWeek(year, weekNumber, Locale.US));
}
static LocalDate getFirstDayOfWeek(int year, int weekNumber, Locale locale) {
return LocalDate
.of(year, 2, 1)
.with(WeekFields.of(locale).getFirstDayOfWeek())
.with(WeekFields.of(locale).weekOfWeekBasedYear(), weekNumber);
}
}
输出:
2021-08-23
2021-08-15
请注意,一周的第一天取决于
Locale
,例如英国是星期一,美国是星期日。根据 ISO 8601 标准,今天是星期一。如需比较,请查看 美国日历 和 英国日历。
从 Trail:日期时间了解有关 现代日期时间 API *的更多信息。
* 出于任何原因,如果您必须坚持使用 Java 6 或 Java 7,则可以使用 ThreeTen-Backport,它将大部分 java.time 功能向后移植到 Java 6 和 7。正在为 Android 项目工作,并且您的 Android API 级别仍然不符合 Java-8,请检查 通过脱糖可用的 Java 8+ API 和 如何在 Android 项目中使用 ThreeTenABP。
我没有在java中做过太多日期的事情,但解决方案可能是:
cal.set(Calendar.DAY_OF_YEAR, cal.get(Calendar.DAY_OF_YEAR) - cal.get(Calendar.DAY_OF_WEEK));
逻辑:
获取星期几并从当前日期中减去它(可能需要 -1,具体取决于您需要星期一作为一周的第一天还是星期日)
还有另一种方式...
GregorianCalendar cal = new GregorianCalendar();
cal.clearTime();
Integer correction = 1-cal.get(GregorianCalendar.DAY_OF_WEEK)
cal.add(Calendar.DATE, correction);
cal 现在是一周的第一天
1-cal.get(GregorianCalendar.DAY_OF_WEEK)
周日(我的区域设置中一周的第一天)评估为 1-1,周一评估为 1-2,因此这将为您提供将时钟倒回到周日所需的修正
请谨慎对待这些,如果是 12 月底并且已经是明年结束的一周,则
calendar.get(Calendar.WEEK_OF_YEAR)
返回 1。
使用
// cal2.set(Calendar.WEEK_OF_YEAR, cal.get(Calendar.WEEK_OF_YEAR));
// cal2.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
将 cal2 日期设置为例如2009 年末于 2010 年 12 月 29 日!!
我用的是这个:
cal2.set(Calendar.DAY_OF_YEAR, cal.get(Calendar.DAY_OF_YEAR)); //to round at the start of day
cal2.set(Calendar.YEAR, cal.get(Calendar.YEAR));
cal2.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY); //to round at the start of week
我还确保我的日历中的几周,无论它们位于哪个区域,都从星期一开始:
cal.setFirstDayOfWeek(Calendar.MONDAY);
cal2.setFirstDayOfWeek(Calendar.MONDAY);
尝试公历算法:
public int getFirstDay(int m, int year)
{
int k=1;
int c, y, w, M=0;
if(m>2 && m<=12) M=m-2;
else if(m>0 && M<=2)
{
M=m+10;
year-=1;
}
c=year/100;
y=year%100;
w=(int)((k+(Math.floor(2.6*M - 0.2))-2*c+y+(Math.floor(y/4))+(Math.floor(c/4)))%7);//a fantastic formula
if(w<0) w+=7;
return w;//thus the day of the week is obtained!
}
这里有一些快速但肮脏的代码来做到这一点。此代码创建一个包含当前日期的日历对象,计算当前的星期几,并减去星期几,以便您处于第一天(星期日)。虽然我使用的是 DAY_OF_YEAR,但它跨年都很好(在 2010 年 1 月 2 日,它会返回 2009 年 12 月 27 日,这是正确的)。
import java.text.Format;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
public class DOW {
public static void main(String[] args) {
DOW dow = new DOW();
dow.doIt();
System.exit(0);
}
private void doIt() {
Date curr = new Date();
Calendar cal = Calendar.getInstance();
cal.setTime(curr);
int currentDOW = cal.get(Calendar.DAY_OF_WEEK);
cal.add(Calendar.DAY_OF_YEAR, (currentDOW * -1)+1);
Format formatter = new SimpleDateFormat("MM/dd/yy");
System.out.println("First day of week="+formatter.format(cal.getTime()));
}
}
我通过将答案代码包装在一个方法中来修改它,您可以轻松地将此代码合并到您的开发中:
public class 210945SOPost {
public static Date getFirstDayOfWeek(int week, int year) {
Calendar calendar = Calendar.getInstance();
calendar.clear();
calendar.set(Calendar.WEEK_OF_YEAR, week);
calendar.set(Calendar.YEAR, year);
return calendar.getTime();
}
}