Reputation: 5341
How do you determine which day of the week is considered the “start” according to a given Locale using Joda-Time?
Point: Most countries use the international standard Monday as first day of week (!). A bunch others use Sunday (notably USA). Others apparently Saturday. Some apparently Wednesday?!
Wikipedia "Seven-day week"#Week_number
Upvotes: 59
Views: 36730
Reputation: 79075
java.time
Shown below is a notice on the Joda-Time Home Page:
Note that from Java SE 8 onwards, users are asked to migrate to
java.time
(JSR-310) - a core part of the JDK which replaces this project.
java.time
APIWeekFields
based on the Locale
using
WeekFields#of
.WeekFields
, get the TemporalField
using the WeekFields#dayOfWeek
LocalDate with(TemporalField)
on an instance of LocalDate
to get a copy of this date with the TemporalField
set to 1 (i.e. first day).DayOfWeek
enum value of the obtained LocalDate
using LocalDate#getDayOfWeek
. Optionally, you can get the textual representation of this DayOfWeek
using DayOfWeek#getDisplayName
.Demo:
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);
}
}
Output from a sample run:
Sunday
Monday
Sunday
रविवार
Learn more about the modern Date-Time API from Trail: Date Time.
Upvotes: 2
Reputation: 1568
Here is the Scala code to get start and end day of week dynamically.
Note:- Make sure start and end are in order for example when start day is Sunday
then Monday
is end day of week
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)))
}
Output:- For 5th Jan 2021
start day of week is Thursday
and end day of week is Wednesday
then week begins with 2020-12-31
and end with 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))
Upvotes: 0
Reputation: 2460
This is what I came up with. The startOfWeek
will always be the start of a Sunday and the endOfweek
will always be an end of a Saturday(Start a of Monday).
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);
}
Upvotes: 0
Reputation: 11607
I used the following stub in Scala
to obtain first and last days of the week from 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)
Note: The minusDays(1)
is only meant to make the week span from Sunday to Saturday (instead of the default Monday to Sunday known to Joda
). For US (and other similar) locales, you can ignore this part
Upvotes: -1
Reputation: 55670
Here is how one might work around Joda time to get the U.S. first day of the week:
DateTime getFirstDayOfWeek(DateTime other) {
if(other.dayOfWeek.get == 7)
return other;
else
return other.minusWeeks(1).withDayOfWeek(7);
}
Or in Scala
def getFirstDayOfWeek(other: DateTime) = other.dayOfWeek.get match {
case 7 => other
case _ => other.minusWeeks(1).withDayOfWeek(7)
}
Upvotes: 7
Reputation: 30990
There's no reason you can't make use of the JDK at least to find the "customary start of the week" for the given Locale. The only tricky part is translating constants for weekdays, where both are 1 through 7, but java.util.Calendar is shifted by one, with Calendar.MONDAY = 2 vs. DateTimeConstants.MONDAY = 1.
Anyway, use this function:
/**
* 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;
}
Add a Locale to Calendar.getInstance() to get a result for some Locale other than the default.
Upvotes: 16
Reputation: 63385
Joda-Time uses the ISO standard Monday to Sunday week.
It does not have the ability to obtain the first day of week, nor to return the day of week index based on any day other than the standard Monday. Finally, weeks are always calculated wrt ISO rules.
Upvotes: 46
Reputation: 8534
Seems like you're out of luck, it looks like all of the provided Chronologies inherit the implementation from baseChronology, which supports only ISO definitions, i.e. Monday=1 ... Sunday=7.
You would have to define your own LocaleChronology, possibly modeled on StrictChronology or LenientChronology, add a factory method:
public static LocaleChronology getInstance(Chronology base, Locale locale)
and override the implementation of
public final DateTimeField dayOfWeek()
with a re-implementation of java.util.Calendar.setWeekCountData(Locale desiredLocale) which relies on sun.util.resources.LocaleData..getCalendarData(desiredLocale).
Upvotes: 2
Reputation: 63734
So your question is, how to get the DayOfWeek from a Joda DateTime object? What about this:
DateTime dt = new DateTime().withYear(2009).plusDays(111);
dt.toGregorianCalendar().getFirstDayOfWeek();
Upvotes: -1