- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
例如:
2016 年 2 月 5 日
- 第一周,2016 年 2 月 12 日
- 第二周,2016 年 2 月 28 日
- 上周最佳答案
嗯,您不太清楚如何定义一个月中的星期几。对于下面的讨论,我假设您谈论的是从星期一开始的几周(例如 ISO-8601 标准和大多数欧洲国家/地区)。
在统计周数时如何处理月的开始和结束,有两种可能的定义方式。
由于星期一的一周开始不一定与一个月的第一天相同,一周可以从上个月开始,也可以属于下个月。
JDK 类 SimpleDateFormat
及其字段模式符号 w(以及新的 JSR-310 字段 WeekFields.weekOfMonth())使用以下策略:
If the first day of month is falling on Monday to Thursday then the associated week has at least 4 days in current month and will be counted as week 1 otherwise as week 0 (zero). Consistently the last day of month will always use an incrementing number even if it belongs to first week of next month.
与该定义相反,CLDR 日期-时间-模式规范和 ISO-8601 几乎没有提及月中周上下文中的细节。然而,这些标准并没有对他们描述另一种策略的一年中的哪一周保持沉默。和 CLDR explicitly says about week-of-month (第 8.4 节):
8.4 Week of Year
Values calculated for the Week of Year field range from 1 to 53 for the Gregorian calendar (they may have different ranges for other calendars). Week 1 for a year is the first week that contains at least the specified minimum number of days from that year. Weeks between week 1 of one year and week 1 of the following year are numbered sequentially from 2 to 52 or 53 (if needed). For example, January 1, 1998 was a Thursday. If the first day of the week is MONDAY and the minimum days in a week is 4 (these are the values reflecting ISO 8601 and many national standards), then week 1 of 1998 starts on December 29, 1997, and ends on January 4, 1998. However, if the first day of the week is SUNDAY, then week 1 of 1998 starts on January 4, 1998, and ends on January 10, 1998. The first three days of 1998 are then part of week 53 of 1997.
Values are similarly calculated for the Week of Month.
在 2016 年 2 月 29 日应用的两种策略之间的差异将是:
现在我提出一个Joda-Time 的解决方案。
public static void main(String[] args) throws Throwable {
System.out.println(getWeekOfMonth(false)); // CLDR/ISO-spec
// 1 for today=2016-02-05
// 2 for today=2016-02-12
// 4 for today=2016-02-28
// 1 for today=2016-02-29
System.out.println(getWeekOfMonth(true)); // JDK-behaviour
// 1 for today=2016-02-05
// 2 for today=2016-02-12
// 4 for today=2016-02-28
// 5 for today=2016-02-29
}
private static int getWeekOfMonth(boolean bounded) {
int weekOfMonth;
LocalDate today = LocalDate.now();
LocalDate first = today.dayOfMonth().withMinimumValue();
int dowFirst = first.getDayOfWeek();
if (dowFirst <= DateTimeConstants.THURSDAY) {
// we are in week 1 and go to Monday as start of week
first = first.minusDays(dowFirst - DateTimeConstants.MONDAY);
// first try: we determine the week of current month
weekOfMonth = Days.daysBetween(first, today).getDays() / 7 + 1;
if (!bounded) {
// edge case: are we in first week of next month?
LocalDate next = first.plusMonths(1);
int dowNext = next.getDayOfWeek();
if (dowNext <= DateTimeConstants.THURSDAY) {
next = next.minusDays(dowNext - DateTimeConstants.MONDAY);
if (!next.isAfter(today)) {
weekOfMonth = 1;
}
}
}
} else if (bounded) {
weekOfMonth = 0;
} else {
// we are in last week of previous month so let's check the start of previous month
LocalDate previous = first.minusMonths(1);
int dowPrevious = previous.getDayOfWeek();
if (dowPrevious <= DateTimeConstants.THURSDAY) {
previous = previous.minusDays(dowPrevious - DateTimeConstants.MONDAY);
} else {
previous = previous.plusDays(DateTimeConstants.MONDAY - dowPrevious + 7);
}
weekOfMonth = Days.daysBetween(previous, today).getDays() / 7 + 1;
}
return weekOfMonth;
}
我希望这对您来说不会太复杂。
顺便说一下,如果您对适用于早于 Java-8 的平台的简单替代方案看起来像什么感兴趣:
Time4J (我的图书馆)
private static int time4j(boolean bounded) { // supports both definitions
PlainDate today = SystemClock.inLocalView().today(); // using system timezone
return today.get(
(bounded ? Weekmodel.ISO.boundedWeekOfMonth() : Weekmodel.ISO.weekOfMonth()));
}
Threeten-BP (backport of Java-8):
private static int threeten() { // only JDK-definition (code similar to Java-8)
org.threeten.bp.LocalDate today = org.threeten.bp.LocalDate.now();
return today.get(WeekFields.ISO.weekOfMonth());
}
private static int oldJDK() { // only JDK-definition
GregorianCalendar gcal = new GregorianCalendar();
gcal.setMinimalDaysInFirstWeek(4);
gcal.setFirstDayOfWeek(Calendar.MONDAY);
return gcal.get(Calendar.WEEK_OF_MONTH);
}
如您所见,使用这些替代方案可以很容易地将基础周模型更改为非 ISO 案例(如美国周)。如果您希望在 Joda-Time 中实现这一点,那么我将重写所提供的 Joda 解决方案的任务留给您。
由于以下关于主题的评论而更新:
所以整个事情都是关于每月的星期几。 Joda-Time 也不支持开箱即用的这个元素/字段。对不起。但是你也许可以研究 necessary algorithm对于其他库中使用的此类字段。
Time4J 中的一个演示示例,用于对评论中提到的 rfc2445 规则进行建模:
PlainDate dtStart = PlainDate.of(2016, Month.FEBRUARY, 4);
int count = 5;
Weekday byday = Weekday.FRIDAY; // first
int interval = 1;
CalendarUnit frequency = CalendarUnit.MONTHS;
List<PlainDate> sequence = new ArrayList<>(count);
PlainDate wim = dtStart;
for (int i = 0; i < count; i++) {
wim = wim.with(PlainDate.WEEKDAY_IN_MONTH.setToFirst(byday));
sequence.add(wim);
wim = wim.with(PlainDate.DAY_OF_MONTH, 1).plus(interval, frequency);
}
if (!sequence.isEmpty() && !sequence.get(0).equals(dtStart)) {
sequence.remove(0); // Not quite sure - do you need another condition?
}
System.out.println(sequence); // [2016-03-04, 2016-04-01, 2016-05-06, 2016-06-03]
在 Java-8 中,也有通过 specialized adjuster 的支持。因此您可以使用 java.time.LocalDate
轻松地将给定的演示示例转移到 Java-8。
关于java - 我如何检查 joda-time 是给定日期的第一周,第二周,......还是一个月的最后一周?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35212472/
我是 grails 的新手。我正在使用 joda 插件来获取日期和时间。所以我在单独的列中显示日期和时间。现在我想使用条件搜索日期。 我在 gsp 页面中使用以下代码来搜索日期。
我试图在执行更多计算之前简单地将 TimeZone 信息添加回 LocalDate。 LocalDate 来自使用 ObjectLab LocalDateCalculator 将天数添加到现有 Dat
所以我在使用 JodaTime 年表 IslamicChronology 解析日期时遇到问题,因此编写了一个小示例来演示我的问题。 代码如下: import org.joda.time.Chronol
当我启动我的应用程序时,virgo 会抛出这样的异常: [2015-09-05 11:27:53.254] TCP Connection(2)-127.0.0.1 Installation of
我使用 Spring 从 Web API rest API 检索 JSON 数据,使用 Jackson Joda 模块反序列化 ISO 日期,并将其转换为 Joda DateTime。 Spring
在 Android 设备 (7.0) 上,出现此崩溃: Fatal Exception: org.joda.time.IllegalInstantException: Illegal instant
我需要将 GMT 转换为亚利桑那时间。亚利桑那州目前有 MST(夏令时关闭)。 但是在 Joda Time DateTimeZone 代码中,MST 已映射到 America/Denver: map.
大家早上好。 我想帮助您了解如何使用 1.2.1.1 版本的 Joda Time 完成 org.joda.time.DateTime 到 java.util.Date 的转换。 为什么选择 Joda
试试这个: @Type(type = "org.jadira.usertype.moneyandcurrency.joda.PersistentMoneyAmountAndCurrency") pri
尝试使用 Joda 将包含日期字符串的 JSON 字符串反序列化为 POJO 时遇到异常。 我将 Jackson2 与 Spring 和 Robospice 一起使用。 我遇到以下异常: Could
我有一个招摇的OpenAPI YAML文件,我想使用gradle-swagger-generator-plugin生成Java 这是我的config.json { "useRxJava2": tr
我想使用以下 MDX 语句: with member [x] as now()->plusMonths(1)->withDayOfMonth(1)->minusDay(1) select [x] on
System.out.println( PeriodFormat.getDefault().print(Period.hours(1).plusMinutes(30).plusSeconds(60))
我正在使用 Joda-Time Duration 来获取两个 DateTime 之间的持续时间: DateTime startTimeDate = new DateTime(startTimeDate
当我运行以下代码片段时: import org.joda.time.DateTime; import org.joda.time.DateTimeZone; import java.sql.Times
我正在尝试在 Joda DateTime 中转换毫秒。米利斯是 1338501600000我使用了在线转换器和其他库,所有结果都是 1338501600000 millis 是 Fri Jun 01
我尝试使用以下代码,但收到错误格式无效:“12/11/2013”: String dFrom = ps.utils.gv(request, "dFrom"); String dTo = ps.ut
我正在尝试使用 Joda-Time 的持续时间类来计算两天之间的确切天数差异。这意味着我希望结果是 25.48 天,而不是仅仅 25 天。现在我有: private static final doub
有没有隐藏的方法来获得 Joda-Time以分钟为单位的时间段(或任何其他) 现在我做的是: (period.getHours()*60 + period.getMinutes() + roundTw
有谁知道如何解析日期,例如:Mon Aug 04 16:07:00 CEST 2014使用 Joda 的 DateTime 格式化程序转换为 dd/MM/YYYY HH:MM:SS。我已经尝试过了:
我是一名优秀的程序员,十分优秀!