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.domain.manga.model.Manga
import tachiyomi.source.local.isLocal import tachiyomi.source.local.isLocal
import java.lang.Long.max import java.lang.Long.max
import java.time.Instant
import java.time.ZonedDateTime import java.time.ZonedDateTime
import java.util.Date
import java.util.TreeSet import java.util.TreeSet
class SyncChaptersWithSource( 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 // Used to not set upload date of older chapters
// to a higher value than newer 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 tachiyomi.source.local.isLocal
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import java.time.Instant
import java.time.ZonedDateTime import java.time.ZonedDateTime
import java.util.Date
class UpdateManga( class UpdateManga(
private val mangaRepository: MangaRepository, private val mangaRepository: MangaRepository,
@ -56,14 +56,14 @@ class UpdateManga(
// Never refresh covers if the url is empty to avoid "losing" existing covers // Never refresh covers if the url is empty to avoid "losing" existing covers
remoteManga.thumbnail_url.isNullOrEmpty() -> null remoteManga.thumbnail_url.isNullOrEmpty() -> null
!manualFetch && localManga.thumbnailUrl == remoteManga.thumbnail_url -> null !manualFetch && localManga.thumbnailUrl == remoteManga.thumbnail_url -> null
localManga.isLocal() -> Date().time localManga.isLocal() -> Instant.now().toEpochMilli()
localManga.hasCustomCover(coverCache) -> { localManga.hasCustomCover(coverCache) -> {
coverCache.deleteFromCache(localManga, false) coverCache.deleteFromCache(localManga, false)
null null
} }
else -> { else -> {
coverCache.deleteFromCache(localManga, false) coverCache.deleteFromCache(localManga, false)
Date().time Instant.now().toEpochMilli()
} }
} }
@ -97,16 +97,16 @@ class UpdateManga(
} }
suspend fun awaitUpdateLastUpdate(mangaId: Long): Boolean { 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 { 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 { suspend fun awaitUpdateFavorite(mangaId: Long, favorite: Boolean): Boolean {
val dateAdded = when (favorite) { val dateAdded = when (favorite) {
true -> Date().time true -> Instant.now().toEpochMilli()
false -> 0 false -> 0
} }
return mangaRepository.update( return mangaRepository.update(

View File

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

View File

@ -7,7 +7,7 @@ import androidx.compose.runtime.ReadOnlyComposable
import tachiyomi.core.i18n.stringResource import tachiyomi.core.i18n.stringResource
import tachiyomi.i18n.MR import tachiyomi.i18n.MR
import tachiyomi.presentation.core.i18n.stringResource import tachiyomi.presentation.core.i18n.stringResource
import java.util.Date import java.time.Instant
import kotlin.time.Duration import kotlin.time.Duration
import kotlin.time.Duration.Companion.minutes import kotlin.time.Duration.Companion.minutes
@ -29,7 +29,7 @@ fun Duration.toDurationString(context: Context, fallback: String): String {
@Composable @Composable
@ReadOnlyComposable @ReadOnlyComposable
fun relativeTimeSpanString(epochMillis: Long): String { fun relativeTimeSpanString(epochMillis: Long): String {
val now = Date().time val now = Instant.now().toEpochMilli()
return when { return when {
epochMillis <= 0L -> stringResource(MR.strings.relative_time_span_never) epochMillis <= 0L -> stringResource(MR.strings.relative_time_span_never)
now - epochMillis < 1.minutes.inWholeMilliseconds -> stringResource( 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 tachiyomi.domain.storage.service.StorageManager
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import java.util.Date import java.time.Instant
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import kotlin.time.Duration.Companion.minutes import kotlin.time.Duration.Companion.minutes
import kotlin.time.toJavaDuration import kotlin.time.toJavaDuration
@ -52,7 +52,7 @@ class BackupCreateJob(private val context: Context, workerParams: WorkerParamete
return try { return try {
val location = BackupCreator(context).createBackup(uri, flags, isAutoBackup) val location = BackupCreator(context).createBackup(uri, flags, isAutoBackup)
if (isAutoBackup) { if (isAutoBackup) {
backupPreferences.lastAutoBackupTimestamp().set(Date().time) backupPreferences.lastAutoBackupTimestamp().set(Instant.now().toEpochMilli())
} else { } else {
notifier.showBackupComplete(UniFile.fromUri(context, location.toUri())!!) 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.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import java.io.File import java.io.File
import java.time.Instant
import java.time.ZonedDateTime import java.time.ZonedDateTime
import java.util.Date
import java.util.concurrent.CopyOnWriteArrayList import java.util.concurrent.CopyOnWriteArrayList
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import java.util.concurrent.atomic.AtomicBoolean 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 this is a chapter update, set the last update time to now
if (target == Target.CHAPTERS) { if (target == Target.CHAPTERS) {
libraryPreferences.lastUpdatedTimestamp().set(Date().time) libraryPreferences.lastUpdatedTimestamp().set(Instant.now().toEpochMilli())
} }
val categoryId = inputData.getLong(KEY_CATEGORY, -1L) val categoryId = inputData.getLong(KEY_CATEGORY, -1L)

View File

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

View File

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

View File

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

View File

@ -81,7 +81,7 @@ import tachiyomi.i18n.sy.SYMR
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import xyz.nulldev.ts.api.http.serializer.FilterSerializer 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 import eu.kanade.tachiyomi.source.model.Filter as SourceModelFilter
open class BrowseSourceScreenModel( open class BrowseSourceScreenModel(
@ -331,7 +331,7 @@ open class BrowseSourceScreenModel(
favorite = !manga.favorite, favorite = !manga.favorite,
dateAdded = when (manga.favorite) { dateAdded = when (manga.favorite) {
true -> 0 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 tachiyomi.source.local.isLocal
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import java.time.Instant
import java.util.Date import java.util.Date
/** /**
@ -715,7 +716,7 @@ class ReaderViewModel @JvmOverloads constructor(
} }
fun restartReadTimer() { fun restartReadTimer() {
chapterReadStartTime = Date().time chapterReadStartTime = Instant.now().toEpochMilli()
} }
fun flushReadTimer() { fun flushReadTimer() {

View File

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

View File

@ -12,7 +12,7 @@ import tachiyomi.source.local.isLocal
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import java.io.InputStream 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 * 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 { return when {
isLocal() -> { isLocal() -> {
this.copy(coverLastModified = Date().time) this.copy(coverLastModified = Instant.now().toEpochMilli())
} }
hasCustomCover(coverCache) -> { hasCustomCover(coverCache) -> {
coverCache.deleteFromCache(this, false) coverCache.deleteFromCache(this, false)
@ -36,7 +36,7 @@ fun Manga.prepUpdateCover(coverCache: CoverCache, remoteManga: SManga, refreshSa
} }
else -> { else -> {
coverCache.deleteFromCache(this, false) 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 { fun Manga.removeCovers(coverCache: CoverCache = Injekt.get()): Manga {
if (isLocal()) return this if (isLocal()) return this
return if (coverCache.deleteFromCache(this, true) > 0) { return if (coverCache.deleteFromCache(this, true) > 0) {
return copy(coverLastModified = Date().time) return copy(coverLastModified = Instant.now().toEpochMilli())
} else { } else {
this this
} }

View File

@ -8,6 +8,7 @@ import java.text.DateFormat
import java.time.Instant import java.time.Instant
import java.time.LocalDateTime import java.time.LocalDateTime
import java.time.ZoneId import java.time.ZoneId
import java.time.temporal.ChronoUnit
import java.util.Calendar import java.util.Calendar
import java.util.Date import java.util.Date
@ -38,13 +39,8 @@ fun Long.convertEpochMillisZone(
* @return date as time key * @return date as time key
*/ */
fun Long.toDateKey(): Date { fun Long.toDateKey(): Date {
val cal = Calendar.getInstance() val instant = Instant.ofEpochMilli(this)
cal.time = Date(this) return Date.from(instant.truncatedTo(ChronoUnit.DAYS))
cal[Calendar.HOUR_OF_DAY] = 0
cal[Calendar.MINUTE] = 0
cal[Calendar.SECOND] = 0
cal[Calendar.MILLISECOND] = 0
return cal.time
} }
private const val MILLISECONDS_IN_DAY = 86_400_000L 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 kotlinx.coroutines.flow.retry
import tachiyomi.domain.updates.model.UpdatesWithRelations import tachiyomi.domain.updates.model.UpdatesWithRelations
import tachiyomi.domain.updates.repository.UpdatesRepository import tachiyomi.domain.updates.repository.UpdatesRepository
import java.util.Calendar import java.time.Instant
import kotlin.time.Duration.Companion.seconds import kotlin.time.Duration.Companion.seconds
class GetUpdates( class GetUpdates(
@ -24,8 +24,8 @@ class GetUpdates(
// SY <-- // SY <--
} }
fun subscribe(calendar: Calendar): Flow<List<UpdatesWithRelations>> { fun subscribe(instant: Instant): Flow<List<UpdatesWithRelations>> {
return repository.subscribeAll(calendar.time.time, limit = 500) return repository.subscribeAll(instant.toEpochMilli(), limit = 500)
// SY --> // SY -->
.catchNPE() .catchNPE()
// SY <-- // SY <--

View File

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

View File

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