Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add necessary methods for the schedule send feature #259

Merged
merged 9 commits into from
Jan 23, 2025
228 changes: 152 additions & 76 deletions Legacy/src/main/java/com/infomaniak/lib/core/utils/DateUtils.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* Infomaniak Core - Android
* Copyright (C) 2022-2024 Infomaniak Network SA
* Copyright (C) 2022-2025 Infomaniak Network SA
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -28,17 +28,29 @@ import java.util.Date
import java.util.Locale

const val FORMAT_DATE_CLEAR_MONTH = "dd MMM yyyy"
const val FORMAT_DATE_CLEAR_FULL_MONTH = "EEEE d MMMM yyyy"
const val FORMAT_DATE_DAY_MONTH = "EEE d MMM"
const val FORMAT_DATE_DAY_MONTH_YEAR = "EEE d MMM yyyy"
const val FORMAT_DATE_DAY_FULL_MONTH_WITH_TIME = "EEEE d MMMM HH:mm"
const val FORMAT_DATE_DAY_FULL_MONTH_YEAR_WITH_TIME = "EEEE d MMMM yyyy HH:mm"
const val FORMAT_DATE_CLEAR_MONTH_DAY_ONE_CHAR = "d MMM yyyy"
const val FORMAT_DATE_DEFAULT = "dd.MM.yy"
const val FORMAT_DATE_HOUR_MINUTE = "HH:mm"
const val FORMAT_DATE_SHORT_DAY_ONE_CHAR = "d MMM"
const val FORMAT_SCHEDULE_MAIL = "yyyy-MM-dd'T'HH:mm:ssXXX"
const val FORMAT_DATE_WITH_TIMEZONE = "yyyy-MM-dd'T'HH:mm:ssZ"
const val FORMAT_EVENT_DATE = "dd/MM/yyyy HH:mm"
const val FORMAT_FULL_DATE = "EEEE dd MMMM yyyy"
const val FORMAT_FULL_DATE_WITH_HOUR = "EEEE MMM d yyyy HH:mm:ss"
const val FORMAT_NEW_FILE = "yyyyMMdd_HHmmss"

//region Format Dates
enum class FormatData {
DATE,
HOUR,
BOTH,
}

fun Date.format(pattern: String = FORMAT_DATE_DEFAULT): String {
val simpleDateFormat = SimpleDateFormat(pattern, Locale.getDefault())
return simpleDateFormat.format(this)
Expand All @@ -54,97 +66,152 @@ fun Date.formatWithLocal(formatData: FormatData, formatStyle: FormatStyle, forma

return toInstant().atZone(ZoneId.systemDefault()).format(formatter)
}
//endregion

//region Get a new Date relatively to a given Date
fun Date.startOfTheDay(): Date = Calendar.getInstance().apply {
time = this@startOfTheDay
set(Calendar.HOUR_OF_DAY, 0)
set(Calendar.MINUTE, 0)
set(Calendar.SECOND, 0)
}.time

enum class FormatData {
DATE,
HOUR,
BOTH,
}

fun Date.startOfTheDay(): Date =
Calendar.getInstance().apply {
time = this@startOfTheDay
set(Calendar.HOUR_OF_DAY, 0)
set(Calendar.MINUTE, 0)
set(Calendar.SECOND, 0)
}.time

fun Date.endOfTheDay(): Date =
Calendar.getInstance().apply {
time = this@endOfTheDay
set(Calendar.HOUR_OF_DAY, 23)
set(Calendar.MINUTE, 59)
set(Calendar.SECOND, 59)
}.time
fun Date.endOfTheDay(): Date = Calendar.getInstance().apply {
time = this@endOfTheDay
set(Calendar.HOUR_OF_DAY, 23)
set(Calendar.MINUTE, 59)
set(Calendar.SECOND, 59)
}.time

fun Date.startOfTomorrow(): Date =
Calendar.getInstance().apply {
time = this@startOfTomorrow
add(Calendar.DATE, 1)
}.time.startOfTheDay()

fun Date.endOfTomorrow(): Date =
Calendar.getInstance().apply {
time = this@endOfTomorrow
add(Calendar.DATE, 1)
}.time.endOfTheDay()

fun Date.startOfTheWeek(): Date =
Calendar.getInstance().apply {
time = this@startOfTheWeek
set(Calendar.DAY_OF_WEEK, firstDayOfWeek)
}.time.startOfTheDay()

fun Date.endOfTheWeek(): Date =
Calendar.getInstance().apply {
time = this@endOfTheWeek
set(Calendar.DAY_OF_WEEK, (firstDayOfWeek - 1 + 6) % 7 + 1)
}.time.endOfTheDay()

fun Date.monthsAgo(value: Int): Date =
Calendar.getInstance().apply {
time = this@monthsAgo
add(Calendar.MONTH, -value)
}.time
fun Date.tomorrow(): Date = Calendar.getInstance().apply {
time = this@tomorrow
add(Calendar.DATE, 1)
}.time

fun Date.year(): Int =
Calendar.getInstance().apply {
time = this@year
}.get(Calendar.YEAR)
fun Date.startOfTomorrow(): Date = tomorrow().startOfTheDay()

fun Date.month(): Int =
Calendar.getInstance().apply {
time = this@month
}.get(Calendar.MONTH)
fun Date.endOfTomorrow(): Date = tomorrow().endOfTheDay()

fun Date.day(): Int =
Calendar.getInstance().apply {
time = this@day
}.get(Calendar.DAY_OF_MONTH)
fun Date.startOfTheWeek(): Date = Calendar.getInstance().apply {
time = this@startOfTheWeek
set(Calendar.DAY_OF_WEEK, firstDayOfWeek)
}.time.startOfTheDay()

fun Date.hours(): Int =
Calendar.getInstance().apply {
time = this@hours
}.get(Calendar.HOUR_OF_DAY)
fun Date.endOfTheWeek(): Date = Calendar.getInstance().apply {
time = this@endOfTheWeek
set(Calendar.DAY_OF_WEEK, (firstDayOfWeek - 1 + 6) % 7 + 1)
}.time.endOfTheDay()

fun Date.minutes(): Int =
Calendar.getInstance().apply {
time = this@minutes
}.get(Calendar.MINUTE)
fun Date.monthsAgo(value: Int): Date = Calendar.getInstance().apply {
time = this@monthsAgo
add(Calendar.MONTH, -value)
}.time

fun Date.isSameDayAs(targetDate: Date): Boolean {
return year() == targetDate.year() &&
month() == targetDate.month() &&
day() == targetDate.day()
}
fun Date.addYears(years: Int): Date = Calendar.getInstance().apply {
time = this@addYears
add(Calendar.YEAR, years)
}.time

fun Date.addDays(amount: Int): Date = Calendar.getInstance().apply {
time = this@addDays
add(Calendar.DATE, amount)
}.time

fun Date.setDay(day: Int): Date = Calendar.getInstance().apply {
time = this@setDay
set(Calendar.DAY_OF_MONTH, day)
}.time

fun Date.setHour(hour: Int): Date = Calendar.getInstance().apply {
time = this@setHour
set(Calendar.HOUR_OF_DAY, hour)
}.time

fun Date.setMinute(minute: Int): Date = Calendar.getInstance().apply {
time = this@setMinute
set(Calendar.MINUTE, minute)
}.time

fun Date.roundUpToNextTenMinutes(): Date = Calendar.getInstance().apply {
time = this@roundUpToNextTenMinutes

val currentMinute = get(Calendar.MINUTE)
val minutesToAdd = when {
currentMinute % 5 == 0 -> 10
else -> 5 - (currentMinute % 5) + 10
}

add(Calendar.MINUTE, minutesToAdd)
set(Calendar.SECOND, 0)
}.time

fun Date.getTimeAtHour(hour: Int): Date = Calendar.getInstance().apply {
time = this@getTimeAtHour

set(Calendar.HOUR_OF_DAY, hour)
set(Calendar.MINUTE, 0)
set(Calendar.SECOND, 0)
set(Calendar.MILLISECOND, 0)
}.time

fun Date.getMorning(): Date = this.getTimeAtHour(8)

fun Date.getAfternoon(): Date = this.getTimeAtHour(14)

fun Date.getEvening(): Date = this.getTimeAtHour(18)

fun Date.getNextMonday(): Date = Calendar.getInstance().apply {
time = this@getNextMonday

val daysToAdd = (Calendar.MONDAY - get(Calendar.DAY_OF_WEEK) + 7) % 7
if (daysToAdd == 0) {
add(Calendar.DAY_OF_YEAR, 7)
} else {
add(Calendar.DAY_OF_YEAR, daysToAdd)
}
}.time
//endregion

//region Get specific data about a given Date
fun Date.year(): Int = Calendar.getInstance().apply {
time = this@year
}.get(Calendar.YEAR)

fun Date.month(): Int = Calendar.getInstance().apply {
time = this@month
}.get(Calendar.MONTH)

fun Date.day(): Int = Calendar.getInstance().apply {
time = this@day
}.get(Calendar.DAY_OF_MONTH)

fun Date.hours(): Int = Calendar.getInstance().apply {
time = this@hours
}.get(Calendar.HOUR_OF_DAY)

fun Date.minutes(): Int = Calendar.getInstance().apply {
time = this@minutes
}.get(Calendar.MINUTE)
//endregion

//region Various checks about a given Date
fun Date.isInTheFuture(): Boolean = after(Date())

fun Date.isAtLeastXMinutesInTheFuture(minutes: Int): Boolean {
val dateTenMinutesLater = Calendar.getInstance().apply {
time = Date()
add(Calendar.MINUTE, minutes)
}.time

return after(dateTenMinutesLater)
}

fun Date.isSameDayAs(targetDate: Date): Boolean {
return year() == targetDate.year() &&
month() == targetDate.month() &&
day() == targetDate.day()
}

fun Date.isToday(): Boolean = isSameDayAs(Date())

fun Date.isYesterday(): Boolean {
Expand All @@ -157,6 +224,15 @@ fun Date.isThisWeek(): Boolean {
return this in now.startOfTheWeek()..now.endOfTheWeek()
}

fun Date.isWeekend(): Boolean {
val calendar = Calendar.getInstance().apply {
time = this@isWeekend
}
val day = calendar.get(Calendar.DAY_OF_WEEK)
return day == 1 || day == 7
}

fun Date.isThisMonth(): Boolean = Date().let { now -> year() == now.year() && month() == now.month() }

fun Date.isThisYear(): Boolean = Date().let { now -> year() == now.year() }
//endregion
Loading