java 检索上周一和周五的日期的最佳方法是什么
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12661203/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is the best way to retrieve the dates for last Monday and Friday
提问by ziggy
I need to get the dates for Monday and Friday last week. To do this, i am getting the date of Monday this week and subtracting 7 days. This gives me the date for Monday last week.
我需要获取上周星期一和星期五的日期。为此,我将获得本周星期一的日期并减去 7 天。这给了我上周星期一的日期。
To get the date for Friday i have to add 4. This confused me a bit because for some reason the first day of the week is Sunday as opposed to Monday here in the UK.
要获得星期五的日期,我必须添加 4。这让我有点困惑,因为出于某种原因,一周的第一天是星期天,而不是英国的星期一。
Anyway, here is how i am getting the dates.
无论如何,这是我获取日期的方式。
// Get the dates for last MON & FRI
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
cal.add(Calendar.DAY_OF_WEEK, -7);
cal.set(Calendar.HOUR_OF_DAY,0);
cal.set(Calendar.MINUTE,0);
cal.set(Calendar.SECOND,0);
cal.set(Calendar.MILLISECOND,0);
// Get the date on Friday
cal.add(Calendar.DAY_OF_WEEK, 4);
cal.set(Calendar.HOUR_OF_DAY,23);
cal.set(Calendar.MINUTE,59);
cal.set(Calendar.SECOND,59);
cal.set(Calendar.MILLISECOND,0);
The above works but i am interested if there is anything wrong with the logic. I.e. will it work for Februarys, leap years etc.
以上有效,但我很感兴趣,如果逻辑有任何问题。即它是否适用于二月、闰年等。
Feel free to suggest a better solution/approach.
随意提出更好的解决方案/方法。
Thanks
谢谢
回答by Basil Bourque
tl;dr
tl;博士
get the dates for Monday and Friday last week
获取上周星期一和星期五的日期
LocalDate // Represent a date only, without a time-of-day, and without a time zone or offset.
.now // Capture the current date as seen through the wall-clock time used by the people of a certain region (a time zone).
(
ZoneId.of( "America/Montreal" )
) // Returns a `LocalDate` object.
.with // Move to another date.
(
TemporalAdjusters.previous( DayOfWeek.MONDAY ) // Returns an implementation of the `TemporalAdjuster` interface.
) // Returns another `LocalDate` object, separate and distinct from our original `LocalDate` object. Per the immutable objects design pattern.
Avoid legacy date-time classes
避免遗留的日期时间类
The other Answers use the troublesome old legacy date-time classes now supplanted by the java.time questions.
其他答案使用麻烦的旧日期时间类,现在已被 java.time 问题取代。
LocalDate
LocalDate
The LocalDate
class represents a date-only value without time-of-day and without time zone.
该LocalDate
级表示没有时间一天和不同时区的日期,唯一的价值。
A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris Franceis a new day while still “yesterday” in Montréal Québec.
时区对于确定日期至关重要。对于任何给定时刻,日期因地区而异。例如,在法国巴黎午夜过后几分钟是新的一天,而在魁北克蒙特利尔仍然是“昨天” 。
ZoneId z = ZoneId.of( “America/Montreal” );
LocalDate today = LocalDate.now( z );
TemporalAdjuster
TemporalAdjuster
The TemporalAdjuster
interface provides for adjustments to move from one date-time value to another. Find handy implementations in the TemporalAdjusters
class (note the plural 's'). The previous
adjuster finds any specified object from the DayOfWeek
enum.
该TemporalAdjuster
界面提供了从一个日期时间值移动到另一个日期时间值的调整。在TemporalAdjusters
类中找到方便的实现(注意复数“s”)。所述previous
调整器发现从任何指定的对象DayOfWeek
的枚举。
The Question does not exactly define “last week”. Last seven days? Standard Monday-Sunday period? Localized week, such as Sunday-Saturday in the United States? The week prior to today's week or including today's partial week?
该问题并未准确定义“上周”。过去 7 天?标准的周一至周日时段?本地化的一周,例如美国的周日至周六?是今天周的前一周还是包括今天的部分周?
I will assume the prior seven days were intended.
我假设前 7 天是有意的。
LocalDate previousMonday = today.with( TemporalAdjusters.previous( DayOfWeek.MONDAY ) ) ;
LocalDate previousFriday = today.with( TemporalAdjusters.previous( DayOfWeek.FRIDAY ) ) ;
By the way, if you want to consider the initial date if it happens to already be the desired day-of-week, use alternate TemporalAdjuster
implementations: previousOrSame
or nextOrSame
.
顺便说一句,如果您想考虑初始日期,如果它恰好已经是所需的星期几,请使用替代TemporalAdjuster
实现:previousOrSame
或nextOrSame
。
About java.time
关于java.time
The java.timeframework is built into Java 8 and later. These classes supplant the troublesome old legacydate-time classes such as java.util.Date
, Calendar
, & SimpleDateFormat
.
该java.time框架是建立在Java 8和更高版本。这些类取代了麻烦的旧的遗留日期时间类,例如java.util.Date
, Calendar
, & SimpleDateFormat
。
The Joda-Timeproject, now in maintenance mode, advises migration to the java.timeclasses.
现在处于维护模式的Joda-Time项目建议迁移到java.time类。
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
要了解更多信息,请参阅Oracle 教程。并在 Stack Overflow 上搜索许多示例和解释。规范是JSR 310。
You may exchange java.timeobjects directly with your database. Use a JDBC drivercompliant with JDBC 4.2or later. No need for strings, no need for java.sql.*
classes.
您可以直接与数据库交换java.time对象。使用符合JDBC 4.2或更高版本的JDBC 驱动程序。不需要字符串,不需要类。java.sql.*
Where to obtain the java.time classes?
从哪里获得 java.time 类?
- Java SE 8, Java SE 9, and later
- Built-in.
- Part of the standard Java API with a bundled implementation.
- Java 9 adds some minor features and fixes.
- Java SE 6and Java SE 7
- Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
- Android
- Later versions of Android bundle implementations of the java.time classes.
- For earlier Android (<26), the ThreeTenABPproject adapts ThreeTen-Backport(mentioned above). See How to use ThreeTenABP….
- Java SE 8、Java SE 9及更高版本
- 内置。
- 具有捆绑实现的标准 Java API 的一部分。
- Java 9 添加了一些小功能和修复。
- Java SE 6和Java SE 7
- 多的java.time功能后移植到Java 6和7在ThreeTen-反向移植。
- 安卓
- 更高版本的 Android 捆绑实现 java.time 类。
- 对于早期的 Android(<26),ThreeTenABP项目采用了ThreeTen-Backport(上面提到过)。请参阅如何使用ThreeTenABP ...。
The ThreeTen-Extraproject extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval
, YearWeek
, YearQuarter
, and more.
该ThreeTen-额外项目与其他类扩展java.time。该项目是未来可能添加到 java.time 的试验场。你可能在这里找到一些有用的类,比如Interval
,YearWeek
,YearQuarter
,和更多。
回答by Modus Tollens
Note:For Java 8 and above please take a look at Basil Bourque's answer (link).
Java 8 introduced a new time/date API which offers most of Joda-Time's functionality.
注意:对于 Java 8 及更高版本,请查看Basil Bourque的回答(链接)。
Java 8 引入了一个新的时间/日期 API,它提供了 Joda-Time 的大部分功能。
Joda-Timeoffers really nice methods for problems like that.
Joda-Time为此类问题提供了非常好的方法。
Getting the dates for Monday and Friday last week would look something like this using Joda Time:
使用 Joda Time 获取上周星期一和星期五的日期看起来像这样:
DateTime today = DateTime.now();
DateTime sameDayLastWeek = today.minusWeeks(1);
DateTime mondayLastWeek = sameDayLastWeek.withDayOfWeek(DateTimeConstants.MONDAY);
DateTime fridayLastWeek = sameDayLastWeek.withDayOfWeek(DateTimeConstants.FRIDAY);
You can create DateTime
objects from java.util.Date
objects and vice versa so it is easy to use with Java dates.
您可以DateTime
从java.util.Date
对象创建对象,反之亦然,因此它很容易与 Java 日期一起使用。
Using the above code with the date
使用上面的代码和日期
DateTime today = new DateTime("2012-09-30");
results in "2012-09-17" for Monday and "2012-09-21" for Friday, setting the date to
结果为星期一的“2012-09-17”和星期五的“2012-09-21”,将日期设置为
DateTime tomorrow = new DateTime("2012-10-01");
results in "2012-09-24" for Monday and "2012-09-28" for Friday.
结果为“2012-09-24”星期一和“2012-09-28”星期五。
回答by Joachim Isaksson
You still have start of week set to sunday, which means that Calendar.MONDAY
on a saturday is the monday before, while Calendar.MONDAY
on a sunday is the next day.
您仍然将一周的开始设置为星期日,这意味着Calendar.MONDAY
星期六是前Calendar.MONDAY
一个星期一,而星期日是第二天。
What you need to do is (according to how you want it according to your comment above), to set the start of week to monday.
您需要做的是(根据您上面的评论,根据您想要的方式)将一周的开始设置为星期一。
Calendar cal = Calendar.getInstance();
cal.setFirstDayOfWeek(Calendar.MONDAY);
cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
cal.add(Calendar.DAY_OF_WEEK, -7);
...
Beyond that, and that the last second of friday isn't included in the range, your logic seems sound, and shouldn't have trouble with leap years/DST shifts etc.
除此之外,星期五的最后一秒不包括在范围内,您的逻辑似乎是合理的,并且应该不会遇到闰年/夏令时变化等问题。
回答by Marko Topolnik
The only thing I see wrong is that you are in fact testing the rangeMo-Fr, and not, as stated, retrieving two specific days. It would be safer to test range Mo-Sa with exclusive upper bound.
我认为唯一错误的是您实际上是在测试范围Mo-Fr,而不是如上所述,检索两个特定的日期。使用唯一的上限测试范围 Mo-Sa 会更安全。