0

I need to get this week startdate like 2023-02-20 and last week startdate and end date.

startdate will be monday.

so I create 4 variables like below.

private var thisWeekStart : Long = 0
    private var thisWeekEnd : Long = 0
    private var lastWeekStart : Long = 0
    private var lastWeekEnd : Long = 0

And I tried to assign something like below..

var cal = Calendar.getInstance()
        cal.time = Date()
        thisWeekEnd = cal.timeInMillis

        // 이번주 시작
        cal.get(Calendar.DAY_OF_WEEK)
        thisWeekStart = cal.timeInMillis

        cal.add(Calendar.DAY_OF_WEEK, -1)
        lastWeekStart = cal.timeInMillis

        cal.clear()
        cal.set(Calendar.DAY_OF_WEEK, -1)
        lastWeekStart = cal.timeInMillis

But it throws milliseconds not like yyyy-MM-dd format.

And I'm not sure is that correct way of keep clearing calendar like above.

Most of all, I can't get last week's end date with above way.

Is there any good way to get this weed and last week start, end date?

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
Hyejung
  • 902
  • 1
  • 8
  • 22
  • A good way? I recommend that you start by considering not using `Calendar`. It was a poorly designed class, cumbersome to work with, and fortunately it is long outdated. `Date` too. Use `LocalDate` from [java.time, the modern java date and time API](https://docs.oracle.com/javase/tutorial/datetime/index.html) (since 2014). You also want either `WeekFields` or `TemporalAdjusters`. – Ole V.V. Feb 26 '23 at 03:56
  • If you don’t want milliseconds, don’t ask for `cal.timeInMillis`. If you want `yyyy-MM-dd` format, you can’t hold it in a `Long`. A `Long` holds an integer only. – Ole V.V. Feb 26 '23 at 03:58
  • For example: Since the last day of week is a Sunday, get last week’s end day (inclusive) from `LocalDate .now(ZoneId.systemDefault()) .minusWeeks(1) .with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY))`. When run today (2023-02-26) it gave `2023-02-19`. – Ole V.V. Feb 26 '23 at 04:05
  • [Here is example Java code using `WeekFields`](https://rextester.com/TBJSR83875). – Ole V.V. Feb 26 '23 at 05:10

3 Answers3

1

tl;dr

Use java.time.

(In Java syntax rather than Kotlin.)

LocalDate                                    // Represent a date-only value.
.now( ZoneId.of( "Asia/Seoul" ) )            // Get the current date as seen in a particular time zone.
.with( 
    TemporalAdjusters.previousOrSame( DayOfWeek.MONDAY ) 
)                                            // Returns another LocalDate. 
.atStartOfDay( ZoneId.of( "Asia/Seoul" ) )   // Determine the first moment of the day on that date in that time zone.
.toInstant()                                 // Convert to UTC. Same moment, same point on the timeline.
.toEpochMilli()                              // Extract a count of milliseconds since 1970-01-01T00:00Z.

Avoid legacy classes

The legacy date-time classes are terrible, deeply flawed in their design. They were supplanted years ago by the modern java.time classes built into Java 8 and later.

An implementation is built into Android 26+. For earlier Android, the latest tooling makes most of the java.time functionality available via API desugaring.

java.time

LocalDate

need to get this week startdate like 2023-02-20

Use the LocalDate class to represent a date only without a time-of-day and without an offset or time zone.

Using Java syntax (I've not yet learned Kotlin):

LocalDate today = LocalDate.now() ;

Generally best to be explicit about the time zone used to determine the current date.

ZoneId zoneId = ZoneId.of( "Asia/Seoul" ) ; // Or ZoneId.systemDefault(). 
LocalDate today = LocalDate.now() ; 

TemporalAdjuster

Use a TemporalAdjuster to move to another day of week. Note the DayOfWeek enum, defining an object for each day of week.

LocalDate previousOrSameMonday = today.with( TemporalAdjusters.previousOrSame( DayOfWeek.MONDAY ) ) ;

To get the following Sunday, add 6 days.

LocalDate sameOrNextSunday = previousOrSameMonday.plusDays( 6 ) ;

But… A span of time is usually better defined using the Half-Open approach. In Half-Open, the beginning is inclusive while the ending is exclusive. So a week starts on a Monday, running up to, but not including, the following Monday.

LocalDate startNextWeek = previousOrSameMonday.plusWeeks( 1 ) ;

Count from epoch

Apparently you want a count of milliseconds from an epoch reference date. I will assume your epoch reference is the first moment of 1970 as seen in UTC, 1970-01-01T00:00Z.

ZonedDateTime

To do this, we need to get the first moment of the day on that date as seen in a particular time zone.

Do not assume the day starts at 00:00. Some days on some dates in some zones start at another time-of-day such as 01:00. Let java.time determine the first moment of the day.

ZonedDateTime zdtStart = previousOrSameMonday.atStartOfDay( zoneId ) ;

Instant

Extract an Instant, the same moment but as seen with an offset from UTC of zero hours-minutes-seconds.

Instant instant = zdtStart.toInstant() ;

From the Instant extract a count from epoch.

long start = instant.toEpochMilli() ;
long end = startNextWeek.atStartOfDay( zoneId ).toInstant().toEpochMilli() ;

Compare

See if a moment lies within that week.

long now = Instant.now().toMilli() ;
if ( 
   ( ! now < start )
    &&
   ( now < end )
) { … }
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
0
fun getStartAndEndDayByToday(today: Calendar): ArrayList<String> {
    val startAndEndDayArray = ArrayList<String>()
    // Get the day of this week today
    val todayWeekDay = today.get(Calendar.DAY_OF_WEEK)
    // Below you can get the start day of week; it would be changeable according to local time zone
    today.add(Calendar.DAY_OF_MONTH, 1 - todayWeekDay)
    val calStartDayOfWeek = today.time
    // Below you can get the end day of week; it would be changeable according to local time zone
    today.add(Calendar.DAY_OF_MONTH, 6)
    val calEndDayOfWeek = today.time
    // Here you can set the date format by using SimpleDateFormat
    val sdfStartDayOfWeek = SimpleDateFormat("yyyy-MM-dd")
    val sdfEndDayOfWeek = SimpleDateFormat("yyyy-MM-dd")
    // Make the array with start date and end date
    startAndEndDayArray.add(sdfStartDayOfWeek.format(calStartDayOfWeek))
    startAndEndDayArray.add(sdfEndDayOfWeek.format(calEndDayOfWeek))
    return startAndEndDayArray
}

Hope this would help!

0

At first, we define our desired output format. In this case we will use yyyy-MM-dd. In the next step we save the current date in a variable. In the third line we define timezone in which we are working (I used Europe/Berlin for testing purposes, bacause I'm in germany).

In the next steps we create Calendar instance for each desired date and manipulate the date to our needs.

Important: You have to add the line firstDayOfWeek = Calendar.MONDAY only if your week starts at another date than Sunday.

val dateFormat = SimpleDateFormat("yyyy-MM-dd")
val today = Calendar.getInstance()
val timeZone = TimeZone.getTimeZone("Europe/Berlin")

val startOfWeek = Calendar.getInstance(timeZone).apply {
    firstDayOfWeek = Calendar.MONDAY
    set(Calendar.DAY_OF_WEEK, Calendar.MONDAY)
}.time

val endOfWeek = Calendar.getInstance(timeZone).apply {
    firstDayOfWeek = Calendar.MONDAY
    set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY)
}.time

val startOfLastWeek = Calendar.getInstance(timeZone).apply {
    firstDayOfWeek = Calendar.MONDAY
    set(Calendar.WEEK_OF_YEAR, today.get(Calendar.WEEK_OF_YEAR) - 1)
    set(Calendar.DAY_OF_WEEK, Calendar.MONDAY)
}.time

val endOfLastWeek = Calendar.getInstance(timeZone).apply {
    firstDayOfWeek = Calendar.MONDAY
    set(Calendar.WEEK_OF_YEAR, today.get(Calendar.WEEK_OF_YEAR) - 1)
    set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY)
}.time

val startOfWeekAsString = dateFormat.format(startOfWeek)
val endOfWeekAsString = dateFormat.format(endOfWeek)
val startOfLastWeekAsString = dateFormat.format(startOfLastWeek)
val endOfLastWeekAsString = dateFormat.format(endOfLastWeek)

println("Start of week: $startOfWeekAsString")
println("End of week: $endOfWeekAsString")
println("Start of last week: $startOfLastWeekAsString")
println("End of last week: $endOfLastWeekAsString")

Expected output:

Start of week: 2023-02-13
End of week: 2023-02-19
Start of last week: 2023-02-06
End of last week: 2023-02-12
Daniel
  • 380
  • 2
  • 14
  • 1
    These terrible date-time classes were years ago supplanted by the modern *java.time* classes defined in JSR 310. – Basil Bourque Feb 26 '23 at 03:09
  • Consider not using the notoriously troublesome and long outdated `SimpleDateFormat` class and its equally outdated friends `Calendar` and `TimeZone`. java.time, the modern Java date ad time API, is so much nicer to work with. If for older Android, you can use it through [desugaring](https://developer.android.com/studio/write/java8-support). – Ole V.V. Feb 26 '23 at 08:17
  • Thanks for your Feedback, haven't been woeking with Date and Time so often. – Daniel Feb 27 '23 at 06:06