stolsvik
stolsvik

Reputation: 5341

Start of week for locale

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

Answers (9)

Arvind Kumar Avinash
Arvind Kumar Avinash

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.

Solution using java.time API

  1. Obtain an instance of WeekFields based on the Locale using WeekFields#of.
  2. From this WeekFields, get the TemporalField using the WeekFields#dayOfWeek
  3. Use 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).
  4. In the final step, get the 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
रविवार

Try it on Ideone

Learn more about the modern Date-Time API from Trail: Date Time.

Upvotes: 2

Puneeth Reddy V
Puneeth Reddy V

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

Fan Jin
Fan Jin

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

y2k-shubham
y2k-shubham

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

Cory Klein
Cory Klein

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

Mark Renouf
Mark Renouf

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

JodaStephen
JodaStephen

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

crowne
crowne

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

Tim B&#252;the
Tim B&#252;the

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

Related Questions