java 使用java指向前一个工作日
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5907921/
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
pointing to previous working day using java
提问by crazypaladin
I am new with using java.calendar.api. I want to point to the previous working day for a given day using java. BUT the conditions goes on increasing when i am using calendar.api to manipulate dates since I had to consider the usual weekends and the pointing to the previous month and also i had to consider the regional holidays in my region......
我是使用 java.calendar.api 的新手。我想使用 java 指向给定日期的前一个工作日。但是当我使用 calendar.api 来操作日期时,条件会继续增加,因为我必须考虑通常的周末和指向上个月的时间,而且我还必须考虑我所在地区的区域性假期......
for ex:say i had to consider the U.S holidays and point to the day before that.
例如:说我必须考虑美国假期并指向前一天。
Is there any way i can define my own calendarand use it so that date manipulation senses all those usual changes?
有什么方法可以定义我自己的日历并使用它,以便日期操作能够感知所有这些常见的变化?
回答by WhiteFang34
While you should consider using the Joda Timelibrary, here's a start with the Java Calendar API:
虽然您应该考虑使用Joda Time库,但这里先从 Java Calendar API 开始:
public Date getPreviousWorkingDay(Date date) {
Calendar cal = Calendar.getInstance();
cal.setTime(date);
int dayOfWeek;
do {
cal.add(Calendar.DAY_OF_MONTH, -1);
dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
} while (dayOfWeek == Calendar.SATURDAY || dayOfWeek == Calendar.SUNDAY);
return cal.getTime();
}
This only considers weekends. You'll have to add additional checks to handle days you consider holidays. For instance you could add || isHoliday(cal)
to the while
condition. Then implement that method, something like:
这仅考虑周末。您必须添加额外的检查来处理您认为是假期的日子。例如,您可以添加|| isHoliday(cal)
到while
条件。然后实现该方法,例如:
public boolean isHoliday(Calendar cal) {
int year = cal.get(Calendar.YEAR);
int month = cal.get(Calendar.MONTH) + 1;
int dayOfMonth = cal.get(Calendar.DAY_OF_MONTH);
if (month == 12 && dayOfMonth == 25) {
return true;
}
// more checks
return false;
}
回答by Basil Bourque
tl;dr
tl;博士
LocalDate.now ( ZoneId.of ( "America/Montreal" ) )
.with ( org.threeten.extra.Temporals.previousWorkingDay () )
java.time
时间
Java 8 and later has the java.time framework built-in. Inspired by Joda-Time, defined by JSR 310, and extended by the ThreeTen-Extraproject.
Java 8 及更高版本内置了 java.time 框架。受Joda-Time 的启发,由 JSR 310 定义,并由ThreeTen-Extra项目扩展。
These new classes replace the notoriously troublesome old date-time classes bundled with the earliest versions of Java, java.util.Date/.Calendar. Avoid the old classes where possible. When you must interface look for newly added conversion methods to switch into java.time for most of your work. Also, the makers of Joda-Time have told us to move to java.time as soon as is convenient.
这些新类取代了与 Java 最早版本 java.util.Date/.Calendar 捆绑在一起的臭名昭著的旧日期时间类。尽可能避免使用旧类。当您必须在界面上寻找新添加的转换方法以切换到 java.time 以完成您的大部分工作。另外,Joda-Time 的开发者告诉我们,在方便的时候尽快迁移到 java.time。
Basics of java.time… An Instant
is a moment on the timeline in UTC. Apply a time zone (ZoneId
) to get a ZonedDateTime
. For a date-only value without a time-of-day nor a time zone, use LocalDate
.
java.time 的基础... AnInstant
是 UTC 时间线上的一个时刻。应用时区 ( ZoneId
) 以获取ZonedDateTime
. 对于没有时间或时区的仅日期值,请使用LocalDate
.
First we get "today" as an example date value. Note how a time zone is required in order to determine the current date even though a LocalDate
does notcontain a time zone. The date is not simultaneously the same around the globe, as a new day dawns earlier in the east.
首先,我们将“今天”作为示例日期值。需要注意的时区是如何以确定即使当前日期要求LocalDate
并没有包含一个时区。全球各地的日期并不同时相同,因为东部新的一天更早出现。
LocalDate today = LocalDate.now ( ZoneId.of ( "America/Los_Angeles" ) );
Adjustors
调节器
The ThreeTen-Extra project extends java.time with additional or experimental features. These features may or may not eventually be folded into java.time proper. This project provides a Temporals
class which provides implementations of adjustors including a couple for nextWorkingDay
and previousWorkingDay
. Easy to use as seen here.
ThreeTen-Extra 项目通过附加或实验性功能扩展了 java.time。这些特性最终可能会也可能不会并入 java.time 中。该项目提供了一个Temporals
类,该类提供了包括一对 fornextWorkingDay
和的调节器的实现previousWorkingDay
。如此处所示,易于使用。
// The 'Temporals' class is from the ThreeTen-Extra library, not built into Java.
LocalDate previousWorkingDay = today.with ( Temporals.previousWorkingDay () );
LocalDate nextWorkingDay = today.with ( Temporals.nextWorkingDay () );
When Run
运行时
Dump to console. Notice how today is a Friday, so the previous working day is -1 (yesterday, Thursday) and the next working day is +3 (Monday).
转储到控制台。注意今天是星期五,所以前一个工作日是-1(昨天,星期四),下一个工作日是+3(星期一)。
System.out.println ( "today: " + today + " | previousWorkingDay: " + previousWorkingDay + " | nextWorkingDay: " + nextWorkingDay );
today: 2016-01-22 | previousWorkingDay: 2016-01-21 | nextWorkingDay: 2016-01-25
今天:2016-01-22 | 上一个工作日:2016-01-21 | 下一个工作日:2016-01-25
Saturday & Sunday
星期六星期天
This pair of adjustors simply skips over every Saturday and Sunday. It knows nothing of holidays. Nor does it know about other definitions of the working week and weekend. The class documentation suggests writing your own java.time.temporal.TemporalAdjusteris easy if you want to handle other definitions.
这对调节器只是在每个周六和周日跳过。它对假期一无所知。它也不知道工作周和周末的其他定义。如果您想处理其他定义,类文档建议编写您自己的java.time.temporal.TemporalAdjuster很容易。
回答by Thorbj?rn Ravn Andersen
回答by James Jithin
You may define a class as below:
你可以定义一个类如下:
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
*
* @author j.james
*/
public class MyCalendar {
private static Map<String, String> holidays = null;
private static MyCalendar myCalendar = null;
private static final int WEEKEND_1 = Calendar.SATURDAY;
private static final int WEEKEND_2 = Calendar.SUNDAY;
private MyCalendar() {
holidays = new HashMap<String, String>();
holidays.put("7,4", "Independence Day");
holidays.put("12,25", "Christmas");
//holidays.putAll(DBUtils.readAnyDynamicHolidaysFromDB());
}
public static Date getPreviousWorkingDay(Date date) {
Date previousWorkingDate = null;
try {
if (myCalendar == null) {
myCalendar = new MyCalendar();
}
if(date != null) {
Calendar calInstance = Calendar.getInstance();
calInstance.setTime(date);
int weekDay = 0;
do {
calInstance.add(Calendar.DATE, -1);
weekDay = calInstance.get(Calendar.DAY_OF_WEEK);
} while(weekDay == WEEKEND_1 || weekDay == WEEKEND_2 ||
holidays.get((calInstance.get(Calendar.MONTH) + 1)
+ "," + calInstance.get(Calendar.DATE)) != null);
previousWorkingDate = calInstance.getTime();
}
} catch (Exception e) {
e.printStackTrace();
}
return previousWorkingDate;
}
}
You can make a call as
您可以拨打电话
public static void main(String[] args) {
System.out.println(MyCalendar.getPreviousWorkingDay(new Date(2011-1900,6,5))); //July 5, 2011 which returns July 1 as the working day because July 4th 2011 is Monday
}