使用 Joda-Time 的区域设置的一周开始时间

问题描述 投票:0回答:9

如何使用 Joda-Time 根据给定的 Locale 确定一周中的哪一天被视为“开始”?

要点:大多数国家/地区使用国际标准星期一作为一周的第一天(!)。其他一些人则使用周日(尤其是美国)。其他人显然是星期六。有些显然是星期三?!

维基百科“七天周”#Week_number

java date calendar jodatime weekday
9个回答
46
投票

Joda-Time 使用 ISO 标准周一至周日周。

它无法获取一周的第一天,也无法根据标准星期一以外的任何一天返回星期几索引。最后,周始终根据 ISO 规则计算。


16
投票

您没有理由不能使用 JDK 至少找到给定区域设置的“习惯的一周开始时间”。唯一棘手的部分是翻译工作日常量,两者都是 1 到 7,但 java.util.Calendar 移动了 1,Calendar.MONDAY = 2 与 DateTimeConstants.MONDAY = 1。

无论如何,使用这个功能:

/**
 * Gets the first day of the week, in the default locale.
 *
 * @return a value in the range of {@link DateTimeConstants#MONDAY} to
 *         {@link DateTimeConstants#SUNDAY}.
 */
private static final int getFirstDayOfWeek() {
  return ((Calendar.getInstance().getFirstDayOfWeek() + 5) % 7) + 1;
}

将区域设置添加到 Calendar.getInstance() 以获取除默认区域设置之外的某些区域设置的结果。


7
投票

以下是如何在 Joda 时间附近获取美国一周的第一天:

DateTime getFirstDayOfWeek(DateTime other) {
  if(other.dayOfWeek.get == 7)
    return other;
  else
    return other.minusWeeks(1).withDayOfWeek(7);
}

或者在 Scala 中

def getFirstDayOfWeek(other: DateTime) = other.dayOfWeek.get match {
    case 7 => other
    case _ => other.minusWeeks(1).withDayOfWeek(7)
}

2
投票

看起来你运气不好,看起来所有提供的Chronologies都继承了baseChronology的实现,它只支持ISO定义, 即星期一=1 ...星期日=7。

您必须定义自己的 LocaleChronology,可能以 StrictChronology 或 LenientChronology 为模型,添加一个工厂方法:

public static LocaleChronology getInstance(Chronology base, Locale locale)

并覆盖

的实现
public final DateTimeField dayOfWeek()

重新实现 java.util.Calendar.setWeekCountData(LocaledesiredLocale),它依赖于 sun.util.resources.LocaleData..getCalendarData(desiredLocale)。


0
投票

这就是我想出来的。

startOfWeek
始终是星期日的开始,
endOfweek
始终是星期六的结束(从星期一开始)。

DateTime startOfWeek;
DateTime endOfWeek;
// make sure Sunday is the first day of the week, not Monday
if (dateTime.getDayOfWeek() == 7) {
    startOfWeek = dateTime.plusDays(1).weekOfWeekyear().roundFloorCopy().minusDays(1);
    endOfWeek = dateTime.plusDays(1).weekOfWeekyear().roundCeilingCopy().minusDays(1);
} else {
    startOfWeek = dateTime.weekOfWeekyear().roundFloorCopy().minusDays(1);
    endOfWeek = dateTime.weekOfWeekyear().roundCeilingCopy().minusDays(1);
}

0
投票

这是动态获取一周开始和结束日期的 Scala 代码。

注意:- 确保开始和结束按顺序,例如当开始日是

Sunday
时,
Monday
是一周的结束日

def shiftWeeksBy(startDayOfWeek: Int, currentWeekDay: Int) : Int = (startDayOfWeek, currentWeekDay) match {
  case (s, c) if s <= c  | s == 1 => 0 //start day of week is Monday -OR- start day of week <= current week day
  case _ => 1
}

def getStartAndEndDays(initialTime: DateTime, startDayOfWeek: Int, endDayOfWeek: Int): (Option[DateTime], Option[DateTime]) = {
   val currentDateWeekDay = initialTime.dayOfWeek.get
   (Some(initialTime.minusWeeks(shiftWeeksBy(startDayOfWeek, currentDateWeekDay)).withDayOfWeek(startDayOfWeek).withTimeAtStartOfDay()),
       Some(initialTime.plusWeeks(shiftWeeksBy(currentDateWeekDay, endDayOfWeek)).withDayOfWeek(endDayOfWeek)))
}

输出:- 对于

5th Jan 2021
,一周的开始日为
Thursday
,一周的结束日为
Wednesday
,则一周以
2020-12-31
开始,以
2021-01-06
结束。

scala> getStartAndEndDays(new DateTime("2021-01-05T00:00:00.000"), 4, 3)
res5: (Option[org.joda.time.DateTime], Option[org.joda.time.DateTime]) = (Some(2020-12-31T00:00:00.000+05:30),Some(2021-01-06T00:00:00.000+05:30))

0
投票

java.time

以下为Joda-Time主页上的通知:

请注意,从 Java SE 8 开始,用户被要求迁移到

java.time
(JSR-310) - JDK 的核心部分,它取代了这个 项目。

使用
java.time
API 的解决方案

  1. 根据
    WeekFields
    获取
    Locale
    的实例,使用
    WeekFields#of
    .
  2. 从此
    WeekFields
    ,使用
    TemporalField
     获取 
    WeekFields#dayOfWeek
  3. LocalDate with(TemporalField)
     的实例上使用 
    LocalDate
     来获取此日期的副本,并将 
    TemporalField
    设置为 1(即第一天)。
  4. 最后一步,使用
    DayOfWeek
    获取获得的LocalDate
    LocalDate#getDayOfWeek
    枚举值。或者,您可以使用
    DayOfWeek
     获取此 
    DayOfWeek#getDisplayName
    的文本表示。

演示

class Main {
    public static void main(String[] args) {
        // First day of the week in the US
        System.out.println(getFirstDayOfWeek(Locale.US));

        // First day of the week in the UK
        System.out.println(getFirstDayOfWeek(Locale.UK));

        // First day of the week in India in English language
        System.out.println(getFirstDayOfWeek(Locale.forLanguageTag("en-IN")));

        // First day of the week in India in Hindi language
        System.out.println(getFirstDayOfWeek(Locale.forLanguageTag("hi")));
    }

    private static String getFirstDayOfWeek(Locale locale) {
        LocalDate now = LocalDate.now();
        return now.with(WeekFields.of(locale).dayOfWeek(), 1)
                .getDayOfWeek()
                .getDisplayName(TextStyle.FULL, locale);
    }
}

示例运行的输出

Sunday
Monday
Sunday
रविवार

在 Ideone 上尝试一下

Trail:日期时间了解有关现代日期时间 API 的更多信息。


-1
投票

所以你的问题是,如何从 Joda DateTime 对象获取 DayOfWeek ?这个怎么样:

DateTime dt = new DateTime().withYear(2009).plusDays(111);
dt.toGregorianCalendar().getFirstDayOfWeek();

-1
投票

我在Scala中使用了以下

存根
Joda
DateTime

获取一周的第一天和最后一天
val today: DateTime = new DateTime()
val dayOfWeek: DateTime.Property = today.dayOfWeek()

val firstDayOfWeek: DateTime = dayOfWeek.withMinimumValue().minusDays(1)
val lastDayOfWeek: DateTime = dayOfWeek.withMaximumValue().minusDays(1)

注意

minusDays(1)
仅用于使周跨度从星期日到星期六(而不是
Joda
已知的默认星期一到星期日)。对于美国(和其他类似)语言环境,您可以忽略这部分

© www.soinside.com 2019 - 2024. All rights reserved.