【发布时间】:2010-10-15 11:17:07
【问题描述】:
我知道一年中的第几周,一周从星期日开始,然后是星期一、星期二...、星期六。
既然我知道周数,那么使用 Java 代码获取特定周日期的有效方法是什么??
【问题讨论】:
-
你的意思是,鉴于现在是 2010 年的第 22 周,那一周的第一天是哪一天(一周的第一天是星期日)
标签: java
我知道一年中的第几周,一周从星期日开始,然后是星期一、星期二...、星期六。
既然我知道周数,那么使用 Java 代码获取特定周日期的有效方法是什么??
【问题讨论】:
标签: java
如果您不需要外部库,只需使用日历即可。
SimpleDateFormat sdf = new SimpleDateFormat("MM dd yyyy");
Calendar cal = Calendar.getInstance();
cal.set(Calendar.WEEK_OF_YEAR, 23);
cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
System.out.println(sdf.format(cal.getTime()));
【讨论】:
java.util.Date、java.util.Calendar 和 java.text.SimpleDateFormat 等非常麻烦的日期时间类现在是 legacy,被 Java 8 及更高版本中内置的 java.time 类所取代.见Tutorial by Oracle。
基于this:
final long calendarWeek = 34;
LocalDate desiredDate = LocalDate.now()
.with(IsoFields.WEEK_OF_WEEK_BASED_YEAR, calendarWeek)
.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
【讨论】:
LocalDate.ofYearDay(year, 50)而不是LocalDate.now()。 DayOfYear(在我的情况下为50)可以是随机的,但不应早于该年第一天的编号DayOfWeek.MONDAY。
您可以使用joda time 库
int weekNumber = 10;
DateTime weekStartDate = new DateTime().withWeekOfWeekyear(weekNumber);
DateTime weekEndDate = new DateTime().withWeekOfWeekyear(weekNumber + 1);
【讨论】:
java.util 日期时间 API 及其格式化 API SimpleDateFormat 已过时且容易出错。建议完全停止使用,改用modern Date-Time API*。
另外,下面引用的是来自home page of Joda-Time的通知:
请注意,从 Java SE 8 开始,用户被要求迁移到 java.time (JSR-310) - JDK 的核心部分,它取代了这个项目。
解决方案:
第一步是找到一周的第一天,作为第二步,我们只需要从这个日期开始迭代所有 7 天。
请注意,一周的第一天是 Locale-dependent 例如英国是星期一,美国是星期日。根据ISO 8601 标准,现在是星期一。为了比较,请检查US calendar 和UK calendar。
第一步演示:
import java.time.LocalDate;
import java.time.Year;
import java.time.temporal.WeekFields;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
// Test
int weekNumber = 34;
System.out.println(getFirstDayOfWeek(weekNumber, Locale.UK));
System.out.println(getFirstDayOfWeek(weekNumber, Locale.US));
}
static LocalDate getFirstDayOfWeek(int weekNumber, Locale locale) {
return LocalDate
.of(Year.now().getValue(), 2, 1)
.with(WeekFields.of(locale).getFirstDayOfWeek())
.with(WeekFields.of(locale).weekOfWeekBasedYear(), weekNumber);
}
}
输出:
2021-08-23
2021-08-15
第二步演示:
import java.time.LocalDate;
import java.time.Year;
import java.time.temporal.WeekFields;
import java.util.List;
import java.util.Locale;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class Main {
public static void main(String[] args) {
// Test
getAllDaysOfTheWeek(34, Locale.US).forEach(System.out::println);
}
static LocalDate getFirstDayOfWeek(int weekNumber, Locale locale) {
return LocalDate
.of(Year.now().getValue(), 2, 1)
.with(WeekFields.of(locale).getFirstDayOfWeek())
.with(WeekFields.of(locale).weekOfWeekBasedYear(), weekNumber);
}
static List<LocalDate> getAllDaysOfTheWeek(int weekNumber, Locale locale) {
LocalDate firstDayOfWeek = getFirstDayOfWeek(weekNumber, locale);
return IntStream
.rangeClosed(0, 6)
.mapToObj(i -> firstDayOfWeek.plusDays(i))
.collect(Collectors.toList());
}
}
输出:
2021-08-15
2021-08-16
2021-08-17
2021-08-18
2021-08-19
2021-08-20
2021-08-21
通过 Trail: Date Time 了解有关 modern Date-Time API* 的更多信息。
* 出于任何原因,如果您必须坚持使用 Java 6 或 Java 7,您可以使用 ThreeTen-Backport,它将大部分 java.time 功能向后移植到 Java 6 和 7 . 如果您正在为一个 Android 项目工作并且您的 Android API 级别仍然不符合 Java-8,请检查 Java 8+ APIs available through desugaring 和 How to use ThreeTenABP in Android Project。
【讨论】:
你没有提到你到底需要什么返回类型,但这段代码应该对你有用。 sysouts 和 formatter 只是为了显示结果。
Calendar cal = Calendar.getInstance();
cal.setTime(new Date());
cal.set(Calendar.WEEK_OF_YEAR, 30);
SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
cal.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
System.out.println(formatter.format(cal.getTime()));
cal.add(Calendar.DAY_OF_WEEK, 6);
System.out.println(formatter.format(cal.getTime()));
【讨论】:
这个答案与其他答案几乎相同。但是,它是这样的:
int year = 2018;
int week = 27;
int day = 1; //assuming week starts from sunday
Calendar calendar = Calendar.getInstance();
calendar.setWeekDate(year, week, day);
System.out.println(calendar.getTime());
【讨论】:
for(int i=1; i<=7; i++) {
if(i <= 3) {
LocalDate desiredDate = LocalDate.now()
.with(IsoFields.WEEK_OF_WEEK_BASED_YEAR, 26)
.with(TemporalAdjusters.previousOrSame(DayOfWeek.of(i)));
System.out.println(desiredDate.format(DateTimeFormatter.ofPattern("dd/MM/yyyy")));
} else {
LocalDate desiredDate = LocalDate.now()
.with(IsoFields.WEEK_OF_WEEK_BASED_YEAR, 26)
.with(TemporalAdjusters.nextOrSame(DayOfWeek.of(i)));
System.out.println(desiredDate.format(DateTimeFormatter.ofPattern("dd/MM/yyyy")));
}
}
这个 sn-p 根据给定的周数提供从星期一到星期日的日期 输出:
【讨论】: