2
\$\begingroup\$
import org.joda.time.DateTime;
import org.joda.time.DateTimeConstants;
import org.joda.time.MutableDateTime;
import org.joda.time.ReadWritableDateTime;
import org.joda.time.Weeks;

import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;

public class WorkDateUtils {

    private static Context mContext;
    public WorkDateUtils(Context context) {
        mContext = context;
    }

    /**
     *  Get the date of the first work date of the first week of the year.
     *  Set it to 01/01 and count forward.
     *  setting DayOfWeek(FIRST_DAY_OF_WEEK) can get us into last year, and I want
     *  that to be -1 with the first whole week of the current year as 0.
     */
    public static DateTime getFirstWorkDateOfYear(int year, int first_day) {
        ReadWritableDateTime readWritableDateTime = new MutableDateTime(year, 1, 1, 0, 0, 0, 0);
        while (readWritableDateTime.getDayOfWeek() != first_day) {
            readWritableDateTime.addDays(1);
        }
        return readWritableDateTime.toDateTime();
    }
    /**
     * Get the date of the beginning of the week containing the current day.
     *
     */
    public static DateTime getStartOfWorkWeek(DateTime dateTime, int first_day) {
        ReadWritableDateTime readWritableDateTime = dateTime.toMutableDateTime();
        readWritableDateTime.setMillisOfDay(0);
        while (readWritableDateTime.getDayOfWeek() != first_day) {
            readWritableDateTime.addDays(-1);
        }

        // Make sure we have the right week.
        while (readWritableDateTime.isAfter(dateTime)) {
            readWritableDateTime.addWeeks(-1);
        }

        return readWritableDateTime.toDateTime();
    }

    public static Week workWeekNumber(DateTime workDate) {
        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(mContext);
        final Integer FIRST_DAY_OF_WEEK = preferences.getInt("workweek_start", DateTimeConstants.SUNDAY);

        Week workWeek = new Week();
        int week;

        DateTime firstWorkDate = getFirstWorkDateOfYear(workDate.getYear(), FIRST_DAY_OF_WEEK);

        DateTime firstOfWeek = getStartOfWorkWeek(workDate, FIRST_DAY_OF_WEEK);

        workWeek.setWeekStart(firstOfWeek.withTime(0, 0, 0, 0).toString());
        workWeek.setWeekEnd(firstOfWeek.plusDays(6).withTime(23, 59, 59, 999).toString());

        week = Weeks.weeksBetween(firstWorkDate, firstOfWeek).getWeeks();
        workWeek.setWeekNum(week);

        return workWeek;
    }
}

I've run this through tests for entire years and not seen any issues, but this will get called heavily, and hoping to optimize it as much as I can.

the Weeks class is just a holder to pass everything around.

\$\endgroup\$
  • \$\begingroup\$ as I know the jodatime library works not quickly on Android. Stackoverflow - Joda Date is slow \$\endgroup\$ – Leonid Semyonov Sep 22 '14 at 5:32
  • \$\begingroup\$ I tried with both calendar/date and Android's Time, neither worked too well, so I settled on joda in order to get working in the first place. \$\endgroup\$ – emaNoN Sep 23 '14 at 23:28
2
\$\begingroup\$

You really don't need to iterate, just do the (mod 7) math to get the correct date directly:

public static DateTime getFirstWorkDateOfYear(int year, int firstDay) {
    ReadWritableDateTime readWritableDateTime = new MutableDateTime(year, 1, 1, 0, 0, 0, 0);
    int doW = readWritableDateTime.getDayOfWeek();
    readWritableDateTime.addDays((7 + firstDay - doW) % 7);
    return readWritableDateTime.toDateTime();
}

public static DateTime getStartOfWorkWeek2(DateTime dateTime, int firstDay) {
    ReadWritableDateTime readWritableDateTime = dateTime.toMutableDateTime();
    readWritableDateTime.setMillisOfDay(0);
    int doW = readWritableDateTime.getDayOfWeek();
    readWritableDateTime.addDays(((firstDay - doW - 7) % 7));
    return readWritableDateTime.toDateTime();
}

The technique proposed is not particularly dependent on which date library you use; with minor variations it can be applied to normal Date or Calendar types. While I like joda, in general, I have no opinion on its performance on Android.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.