Migrate to some newer date/time APIs

(cherry picked from commit ab9a26f6bd2855d13ff663cf52dfe4ecb01fda1d)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateJob.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/migration/search/MigrateDialog.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourceScreenModel.kt
#	domain/src/main/java/tachiyomi/domain/updates/interactor/GetUpdates.kt
This commit is contained in:
arkon 2023-12-08 23:11:53 -05:00 committed by Jobobby04
parent 0aad7fc006
commit 364e4fe41b
17 changed files with 63 additions and 66 deletions

View File

@ -23,8 +23,8 @@ import tachiyomi.domain.chapter.service.ChapterRecognition
import tachiyomi.domain.manga.model.Manga
import tachiyomi.source.local.isLocal
import java.lang.Long.max
import java.time.Instant
import java.time.ZonedDateTime
import java.util.Date
import java.util.TreeSet
class SyncChaptersWithSource(
@ -84,7 +84,7 @@ class SyncChaptersWithSource(
}
}
val rightNow = Date().time
val rightNow = Instant.now().toEpochMilli()
// Used to not set upload date of older chapters
// to a higher value than newer chapters

View File

@ -11,8 +11,8 @@ import tachiyomi.domain.manga.repository.MangaRepository
import tachiyomi.source.local.isLocal
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import java.time.Instant
import java.time.ZonedDateTime
import java.util.Date
class UpdateManga(
private val mangaRepository: MangaRepository,
@ -56,14 +56,14 @@ class UpdateManga(
// Never refresh covers if the url is empty to avoid "losing" existing covers
remoteManga.thumbnail_url.isNullOrEmpty() -> null
!manualFetch && localManga.thumbnailUrl == remoteManga.thumbnail_url -> null
localManga.isLocal() -> Date().time
localManga.isLocal() -> Instant.now().toEpochMilli()
localManga.hasCustomCover(coverCache) -> {
coverCache.deleteFromCache(localManga, false)
null
}
else -> {
coverCache.deleteFromCache(localManga, false)
Date().time
Instant.now().toEpochMilli()
}
}
@ -97,16 +97,16 @@ class UpdateManga(
}
suspend fun awaitUpdateLastUpdate(mangaId: Long): Boolean {
return mangaRepository.update(MangaUpdate(id = mangaId, lastUpdate = Date().time))
return mangaRepository.update(MangaUpdate(id = mangaId, lastUpdate = Instant.now().toEpochMilli()))
}
suspend fun awaitUpdateCoverLastModified(mangaId: Long): Boolean {
return mangaRepository.update(MangaUpdate(id = mangaId, coverLastModified = Date().time))
return mangaRepository.update(MangaUpdate(id = mangaId, coverLastModified = Instant.now().toEpochMilli()))
}
suspend fun awaitUpdateFavorite(mangaId: Long, favorite: Boolean): Boolean {
val dateAdded = when (favorite) {
true -> Date().time
true -> Instant.now().toEpochMilli()
false -> 0
}
return mangaRepository.update(

View File

@ -34,7 +34,7 @@ import tachiyomi.presentation.core.i18n.stringResource
import tachiyomi.presentation.core.util.collectAsState
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import java.util.Date
import java.time.Instant
object SettingsAppearanceScreen : SearchableSettings {
@ -128,7 +128,7 @@ object SettingsAppearanceScreen : SearchableSettings {
var currentLanguage by remember {
mutableStateOf(AppCompatDelegate.getApplicationLocales().get(0)?.toLanguageTag() ?: "")
}
val now = remember { Date().time }
val now = remember { Instant.now().toEpochMilli() }
val dateFormat by uiPreferences.dateFormat().collectAsState()
val formattedNow = remember(dateFormat) {

View File

@ -7,7 +7,7 @@ import androidx.compose.runtime.ReadOnlyComposable
import tachiyomi.core.i18n.stringResource
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.i18n.stringResource
import java.util.Date
import java.time.Instant
import kotlin.time.Duration
import kotlin.time.Duration.Companion.minutes
@ -29,7 +29,7 @@ fun Duration.toDurationString(context: Context, fallback: String): String {
@Composable
@ReadOnlyComposable
fun relativeTimeSpanString(epochMillis: Long): String {
val now = Date().time
val now = Instant.now().toEpochMilli()
return when {
epochMillis <= 0L -> stringResource(MR.strings.relative_time_span_never)
now - epochMillis < 1.minutes.inWholeMilliseconds -> stringResource(

View File

@ -25,7 +25,7 @@ import tachiyomi.domain.backup.service.BackupPreferences
import tachiyomi.domain.storage.service.StorageManager
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import java.util.Date
import java.time.Instant
import java.util.concurrent.TimeUnit
import kotlin.time.Duration.Companion.minutes
import kotlin.time.toJavaDuration
@ -52,7 +52,7 @@ class BackupCreateJob(private val context: Context, workerParams: WorkerParamete
return try {
val location = BackupCreator(context).createBackup(uri, flags, isAutoBackup)
if (isAutoBackup) {
backupPreferences.lastAutoBackupTimestamp().set(Date().time)
backupPreferences.lastAutoBackupTimestamp().set(Instant.now().toEpochMilli())
} else {
notifier.showBackupComplete(UniFile.fromUri(context, location.toUri())!!)
}

View File

@ -94,8 +94,8 @@ import tachiyomi.i18n.MR
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import java.io.File
import java.time.Instant
import java.time.ZonedDateTime
import java.util.Date
import java.util.concurrent.CopyOnWriteArrayList
import java.util.concurrent.TimeUnit
import java.util.concurrent.atomic.AtomicBoolean
@ -151,7 +151,7 @@ class LibraryUpdateJob(private val context: Context, workerParams: WorkerParamet
// If this is a chapter update, set the last update time to now
if (target == Target.CHAPTERS) {
libraryPreferences.lastUpdatedTimestamp().set(Date().time)
libraryPreferences.lastUpdatedTimestamp().set(Instant.now().toEpochMilli())
}
val categoryId = inputData.getLong(KEY_CATEGORY, -1L)

View File

@ -23,7 +23,7 @@ import java.io.ByteArrayInputStream
import java.io.ByteArrayOutputStream
import java.io.File
import java.io.InputStream
import java.util.Date
import java.time.Instant
class ImageSaver(
val context: Context,
@ -79,7 +79,7 @@ class ImageSaver(
MediaStore.Images.Media.RELATIVE_PATH to relativePath,
MediaStore.Images.Media.DISPLAY_NAME to image.name,
MediaStore.Images.Media.MIME_TYPE to type.mime,
MediaStore.Images.Media.DATE_MODIFIED to Date().time * 1000,
MediaStore.Images.Media.DATE_MODIFIED to Instant.now().toEpochMilli(),
)
val picture = findUriOrDefault(relativePath, filename) {

View File

@ -26,7 +26,10 @@ import okhttp3.OkHttpClient
import okhttp3.RequestBody.Companion.toRequestBody
import tachiyomi.core.util.lang.withIOContext
import uy.kohesive.injekt.injectLazy
import java.util.Calendar
import java.time.Instant
import java.time.LocalDate
import java.time.ZoneId
import java.time.ZonedDateTime
import kotlin.time.Duration.Companion.minutes
class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
@ -328,13 +331,15 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
private fun parseDate(struct: JsonObject, dateKey: String): Long {
return try {
val date = Calendar.getInstance()
date.set(
return LocalDate
.of(
struct[dateKey]!!.jsonObject["year"]!!.jsonPrimitive.int,
struct[dateKey]!!.jsonObject["month"]!!.jsonPrimitive.int - 1,
struct[dateKey]!!.jsonObject["month"]!!.jsonPrimitive.int,
struct[dateKey]!!.jsonObject["day"]!!.jsonPrimitive.int,
)
date.timeInMillis
.atStartOfDay(ZoneId.systemDefault())
.toInstant()
.toEpochMilli()
} catch (_: Exception) {
0L
}
@ -349,12 +354,11 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
}
}
val calendar = Calendar.getInstance()
calendar.timeInMillis = dateValue
val dateTime = ZonedDateTime.ofInstant(Instant.ofEpochMilli(dateValue), ZoneId.systemDefault())
return buildJsonObject {
put("year", calendar.get(Calendar.YEAR))
put("month", calendar.get(Calendar.MONTH) + 1)
put("day", calendar.get(Calendar.DAY_OF_MONTH))
put("year", dateTime.year)
put("month", dateTime.monthValue)
put("day", dateTime.dayOfMonth)
}
}

View File

@ -20,7 +20,7 @@ import tachiyomi.core.util.lang.withIOContext
import tachiyomi.core.util.system.logcat
import tachiyomi.domain.UnsortedPreferences
import uy.kohesive.injekt.injectLazy
import java.util.Date
import java.time.Instant
import kotlin.time.Duration.Companion.days
internal class ExtensionGithubApi {
@ -95,14 +95,16 @@ internal class ExtensionGithubApi {
suspend fun checkForUpdates(context: Context, fromAvailableExtensionList: Boolean = false): List<Extension.Installed>? {
// Limit checks to once a day at most
if (!fromAvailableExtensionList && Date().time < lastExtCheck.get() + 1.days.inWholeMilliseconds) {
if (!fromAvailableExtensionList &&
Instant.now().toEpochMilli() < lastExtCheck.get() + 1.days.inWholeMilliseconds
) {
return null
}
val extensions = if (fromAvailableExtensionList) {
extensionManager.availableExtensionsFlow.value
} else {
findExtensions().also { lastExtCheck.set(Date().time) }
findExtensions().also { lastExtCheck.set(Instant.now().toEpochMilli()) }
}
// SY -->

View File

@ -81,7 +81,7 @@ import tachiyomi.i18n.sy.SYMR
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import xyz.nulldev.ts.api.http.serializer.FilterSerializer
import java.util.Date
import java.time.Instant
import eu.kanade.tachiyomi.source.model.Filter as SourceModelFilter
open class BrowseSourceScreenModel(
@ -331,7 +331,7 @@ open class BrowseSourceScreenModel(
favorite = !manga.favorite,
dateAdded = when (manga.favorite) {
true -> 0
false -> Date().time
false -> Instant.now().toEpochMilli()
},
)

View File

@ -97,6 +97,7 @@ import tachiyomi.domain.source.service.SourceManager
import tachiyomi.source.local.isLocal
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import java.time.Instant
import java.util.Date
/**
@ -715,7 +716,7 @@ class ReaderViewModel @JvmOverloads constructor(
}
fun restartReadTimer() {
chapterReadStartTime = Date().time
chapterReadStartTime = Instant.now().toEpochMilli()
}
fun flushReadTimer() {

View File

@ -52,7 +52,7 @@ import tachiyomi.domain.updates.interactor.GetUpdates
import tachiyomi.domain.updates.model.UpdatesWithRelations
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import java.util.Calendar
import java.time.ZonedDateTime
import java.util.Date
class UpdatesScreenModel(
@ -89,13 +89,10 @@ class UpdatesScreenModel(
init {
screenModelScope.launchIO {
// Set date limit for recent chapters
val calendar = Calendar.getInstance().apply {
time = Date()
add(Calendar.MONTH, -3)
}
val limit = ZonedDateTime.now().minusMonths(3).toInstant()
combine(
getUpdates.subscribe(calendar).distinctUntilChanged(),
getUpdates.subscribe(limit).distinctUntilChanged(),
downloadCache.changes,
downloadManager.queueState,
) { updates, _, _ -> updates }

View File

@ -12,7 +12,7 @@ import tachiyomi.source.local.isLocal
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import java.io.InputStream
import java.util.Date
import java.time.Instant
/**
* Call before updating [Manga.thumbnail_url] to ensure old cover can be cleared from cache
@ -28,7 +28,7 @@ fun Manga.prepUpdateCover(coverCache: CoverCache, remoteManga: SManga, refreshSa
return when {
isLocal() -> {
this.copy(coverLastModified = Date().time)
this.copy(coverLastModified = Instant.now().toEpochMilli())
}
hasCustomCover(coverCache) -> {
coverCache.deleteFromCache(this, false)
@ -36,7 +36,7 @@ fun Manga.prepUpdateCover(coverCache: CoverCache, remoteManga: SManga, refreshSa
}
else -> {
coverCache.deleteFromCache(this, false)
this.copy(coverLastModified = Date().time)
this.copy(coverLastModified = Instant.now().toEpochMilli())
}
}
}
@ -44,7 +44,7 @@ fun Manga.prepUpdateCover(coverCache: CoverCache, remoteManga: SManga, refreshSa
fun Manga.removeCovers(coverCache: CoverCache = Injekt.get()): Manga {
if (isLocal()) return this
return if (coverCache.deleteFromCache(this, true) > 0) {
return copy(coverLastModified = Date().time)
return copy(coverLastModified = Instant.now().toEpochMilli())
} else {
this
}

View File

@ -8,6 +8,7 @@ import java.text.DateFormat
import java.time.Instant
import java.time.LocalDateTime
import java.time.ZoneId
import java.time.temporal.ChronoUnit
import java.util.Calendar
import java.util.Date
@ -38,13 +39,8 @@ fun Long.convertEpochMillisZone(
* @return date as time key
*/
fun Long.toDateKey(): Date {
val cal = Calendar.getInstance()
cal.time = Date(this)
cal[Calendar.HOUR_OF_DAY] = 0
cal[Calendar.MINUTE] = 0
cal[Calendar.SECOND] = 0
cal[Calendar.MILLISECOND] = 0
return cal.time
val instant = Instant.ofEpochMilli(this)
return Date.from(instant.truncatedTo(ChronoUnit.DAYS))
}
private const val MILLISECONDS_IN_DAY = 86_400_000L

View File

@ -7,7 +7,7 @@ import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.retry
import tachiyomi.domain.updates.model.UpdatesWithRelations
import tachiyomi.domain.updates.repository.UpdatesRepository
import java.util.Calendar
import java.time.Instant
import kotlin.time.Duration.Companion.seconds
class GetUpdates(
@ -24,8 +24,8 @@ class GetUpdates(
// SY <--
}
fun subscribe(calendar: Calendar): Flow<List<UpdatesWithRelations>> {
return repository.subscribeAll(calendar.time.time, limit = 500)
fun subscribe(instant: Instant): Flow<List<UpdatesWithRelations>> {
return repository.subscribeAll(instant.toEpochMilli(), limit = 500)
// SY -->
.catchNPE()
// SY <--

View File

@ -45,8 +45,8 @@ import tachiyomi.presentation.widget.util.appWidgetBackgroundRadius
import tachiyomi.presentation.widget.util.calculateRowAndColumnCount
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import java.util.Calendar
import java.util.Date
import java.time.Instant
import java.time.ZonedDateTime
abstract class BaseUpdatesGridGlanceWidget(
private val context: Context = Injekt.get<Application>(),
@ -89,7 +89,7 @@ abstract class BaseUpdatesGridGlanceWidget(
val flow = remember {
getUpdates
.subscribe(false, DateLimit.timeInMillis)
.subscribe(false, DateLimit.toEpochMilli())
.map { rawData ->
rawData.prepareData(rowCount, columnCount)
}
@ -147,10 +147,7 @@ abstract class BaseUpdatesGridGlanceWidget(
}
companion object {
val DateLimit: Calendar
get() = Calendar.getInstance().apply {
time = Date()
add(Calendar.MONTH, -3)
}
val DateLimit: Instant
get() = ZonedDateTime.now().minusMonths(3).toInstant()
}
}

View File

@ -19,7 +19,7 @@ class WidgetManager(
fun Context.init(scope: LifecycleCoroutineScope) {
combine(
getUpdates.subscribe(read = false, after = BaseUpdatesGridGlanceWidget.DateLimit.timeInMillis),
getUpdates.subscribe(read = false, after = BaseUpdatesGridGlanceWidget.DateLimit.toEpochMilli()),
securityPreferences.useAuthenticator().changes(),
transform = { a, _ -> a },
)