mirror of https://github.com/readrops/Readrops.git
Replace joda.time by java.time
This commit is contained in:
parent
3af1220666
commit
7abec11b55
|
@ -47,5 +47,4 @@ dependencies {
|
|||
|
||||
implementation(libs.moshi)
|
||||
implementation(libs.jsoup)
|
||||
implementation(libs.jodatime)
|
||||
}
|
||||
|
|
|
@ -4,13 +4,13 @@ import com.gitlab.mvysny.konsumexml.Konsumer
|
|||
import com.gitlab.mvysny.konsumexml.Names
|
||||
import com.gitlab.mvysny.konsumexml.allChildrenAutoIgnore
|
||||
import com.readrops.api.localfeed.XmlAdapter
|
||||
import com.readrops.api.utils.DateUtils
|
||||
import com.readrops.api.utils.exceptions.ParseException
|
||||
import com.readrops.api.utils.extensions.nonNullText
|
||||
import com.readrops.api.utils.extensions.nullableText
|
||||
import com.readrops.api.utils.extensions.nullableTextRecursively
|
||||
import com.readrops.db.entities.Item
|
||||
import org.joda.time.LocalDateTime
|
||||
import com.readrops.db.util.DateUtils
|
||||
import java.time.LocalDateTime
|
||||
|
||||
class ATOMItemAdapter : XmlAdapter<Item> {
|
||||
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
package com.readrops.api.localfeed.json
|
||||
|
||||
import com.readrops.api.localfeed.XmlAdapter.Companion.AUTHORS_MAX
|
||||
import com.readrops.api.utils.DateUtils
|
||||
import com.readrops.api.utils.exceptions.ParseException
|
||||
import com.readrops.api.utils.extensions.nextNonEmptyString
|
||||
import com.readrops.api.utils.extensions.nextNullableString
|
||||
import com.readrops.db.entities.Item
|
||||
import com.readrops.db.util.DateUtils
|
||||
import com.squareup.moshi.JsonAdapter
|
||||
import com.squareup.moshi.JsonReader
|
||||
import com.squareup.moshi.JsonWriter
|
||||
import org.joda.time.LocalDateTime
|
||||
import java.time.LocalDateTime
|
||||
|
||||
class JSONItemsAdapter : JsonAdapter<List<Item>>() {
|
||||
|
||||
|
|
|
@ -5,13 +5,13 @@ import com.gitlab.mvysny.konsumexml.Names
|
|||
import com.gitlab.mvysny.konsumexml.allChildrenAutoIgnore
|
||||
import com.readrops.api.localfeed.XmlAdapter
|
||||
import com.readrops.api.localfeed.XmlAdapter.Companion.AUTHORS_MAX
|
||||
import com.readrops.api.utils.DateUtils
|
||||
import com.readrops.api.utils.exceptions.ParseException
|
||||
import com.readrops.api.utils.extensions.nonNullText
|
||||
import com.readrops.api.utils.extensions.nullableText
|
||||
import com.readrops.api.utils.extensions.nullableTextRecursively
|
||||
import com.readrops.db.entities.Item
|
||||
import org.joda.time.LocalDateTime
|
||||
import com.readrops.db.util.DateUtils
|
||||
import java.time.LocalDateTime
|
||||
|
||||
class RSS1ItemAdapter : XmlAdapter<Item> {
|
||||
|
||||
|
|
|
@ -7,13 +7,13 @@ import com.gitlab.mvysny.konsumexml.allChildrenAutoIgnore
|
|||
import com.readrops.api.localfeed.XmlAdapter
|
||||
import com.readrops.api.localfeed.XmlAdapter.Companion.AUTHORS_MAX
|
||||
import com.readrops.api.utils.ApiUtils
|
||||
import com.readrops.api.utils.DateUtils
|
||||
import com.readrops.api.utils.exceptions.ParseException
|
||||
import com.readrops.api.utils.extensions.nonNullText
|
||||
import com.readrops.api.utils.extensions.nullableText
|
||||
import com.readrops.api.utils.extensions.nullableTextRecursively
|
||||
import com.readrops.db.entities.Item
|
||||
import org.joda.time.LocalDateTime
|
||||
import com.readrops.db.util.DateUtils
|
||||
import java.time.LocalDateTime
|
||||
|
||||
class RSS2ItemAdapter : XmlAdapter<Item> {
|
||||
|
||||
|
|
|
@ -6,11 +6,10 @@ import com.readrops.api.utils.exceptions.ParseException
|
|||
import com.readrops.api.utils.extensions.nextNonEmptyString
|
||||
import com.readrops.api.utils.extensions.nextNullableString
|
||||
import com.readrops.db.entities.Item
|
||||
import com.readrops.db.util.DateUtils
|
||||
import com.squareup.moshi.JsonAdapter
|
||||
import com.squareup.moshi.JsonReader
|
||||
import com.squareup.moshi.JsonWriter
|
||||
import org.joda.time.DateTimeZone
|
||||
import org.joda.time.LocalDateTime
|
||||
|
||||
class FreshRSSItemsAdapter : JsonAdapter<List<Item>>() {
|
||||
|
||||
|
@ -46,8 +45,7 @@ class FreshRSSItemsAdapter : JsonAdapter<List<Item>>() {
|
|||
with(item) {
|
||||
when (reader.selectName(NAMES)) {
|
||||
0 -> remoteId = reader.nextNonEmptyString()
|
||||
1 -> pubDate = LocalDateTime(reader.nextLong() * 1000L,
|
||||
DateTimeZone.getDefault())
|
||||
1 -> pubDate = DateUtils.fromEpochSeconds(reader.nextLong())
|
||||
2 -> title = reader.nextNonEmptyString()
|
||||
3 -> content = getContent(reader)
|
||||
4 -> link = getLink(reader)
|
||||
|
|
|
@ -6,11 +6,10 @@ import com.readrops.api.utils.exceptions.ParseException
|
|||
import com.readrops.api.utils.extensions.nextNonEmptyString
|
||||
import com.readrops.api.utils.extensions.nextNullableString
|
||||
import com.readrops.db.entities.Item
|
||||
import com.readrops.db.util.DateUtils
|
||||
import com.squareup.moshi.JsonAdapter
|
||||
import com.squareup.moshi.JsonReader
|
||||
import com.squareup.moshi.JsonWriter
|
||||
import org.joda.time.DateTimeZone
|
||||
import org.joda.time.LocalDateTime
|
||||
|
||||
class NextcloudNewsItemsAdapter : JsonAdapter<List<Item>>() {
|
||||
|
||||
|
@ -42,7 +41,7 @@ class NextcloudNewsItemsAdapter : JsonAdapter<List<Item>>() {
|
|||
1 -> link = reader.nextNullableString()
|
||||
2 -> title = reader.nextNonEmptyString()
|
||||
3 -> author = reader.nextNullableString()
|
||||
4 -> pubDate = LocalDateTime(reader.nextLong() * 1000L, DateTimeZone.getDefault())
|
||||
4 -> pubDate = DateUtils.fromEpochSeconds(reader.nextLong())
|
||||
5 -> content = reader.nextNullableString()
|
||||
6 -> enclosureMime = reader.nextNullableString()
|
||||
7 -> enclosureLink = reader.nextNullableString()
|
||||
|
|
|
@ -1,79 +0,0 @@
|
|||
package com.readrops.api.utils
|
||||
|
||||
import org.joda.time.LocalDateTime
|
||||
import org.joda.time.format.DateTimeFormat
|
||||
import org.joda.time.format.DateTimeFormatterBuilder
|
||||
import java.util.Locale
|
||||
|
||||
object DateUtils {
|
||||
|
||||
private val TAG = DateUtils::class.java.simpleName
|
||||
|
||||
/**
|
||||
* Base of common RSS 2 date formats.
|
||||
* Examples :
|
||||
* Fri, 04 Jan 2019 22:21:46 GMT
|
||||
* Fri, 04 Jan 2019 22:21:46 +0000
|
||||
*/
|
||||
private const val RSS_2_BASE_PATTERN = "EEE, dd MMM yyyy HH:mm:ss"
|
||||
|
||||
private const val GMT_PATTERN = "ZZZ"
|
||||
|
||||
private const val OFFSET_PATTERN = "Z"
|
||||
|
||||
private const val ISO_PATTERN = ".SSSZZ"
|
||||
|
||||
private const val EDT_PATTERN = "zzz"
|
||||
|
||||
/**
|
||||
* Date pattern for format : 2019-01-04T22:21:46+00:00
|
||||
*/
|
||||
private const val ATOM_JSON_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss"
|
||||
|
||||
@JvmStatic
|
||||
fun parse(value: String?): LocalDateTime? = if (value == null) {
|
||||
null
|
||||
} else try {
|
||||
val formatter = DateTimeFormatterBuilder()
|
||||
.appendOptional(DateTimeFormat.forPattern("$RSS_2_BASE_PATTERN ").parser) // with timezone
|
||||
.appendOptional(DateTimeFormat.forPattern(RSS_2_BASE_PATTERN).parser) // no timezone, important order here
|
||||
.appendOptional(DateTimeFormat.forPattern(ATOM_JSON_DATE_FORMAT).parser)
|
||||
.appendOptional(DateTimeFormat.forPattern(GMT_PATTERN).parser)
|
||||
.appendOptional(DateTimeFormat.forPattern(OFFSET_PATTERN).parser)
|
||||
.appendOptional(DateTimeFormat.forPattern(ISO_PATTERN).parser)
|
||||
.appendOptional(DateTimeFormat.forPattern(EDT_PATTERN).parser)
|
||||
.toFormatter()
|
||||
.withLocale(Locale.ENGLISH)
|
||||
.withOffsetParsed()
|
||||
|
||||
formatter.parseLocalDateTime(value)
|
||||
} catch (e: Exception) {
|
||||
null
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun formattedDateByLocal(dateTime: LocalDateTime): String {
|
||||
return DateTimeFormat.mediumDate()
|
||||
.withLocale(Locale.getDefault())
|
||||
.print(dateTime)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun formattedDateTimeByLocal(dateTime: LocalDateTime): String {
|
||||
return DateTimeFormat.forPattern("dd MMM yyyy · HH:mm")
|
||||
.withLocale(Locale.getDefault())
|
||||
.print(dateTime)
|
||||
}
|
||||
|
||||
fun formattedDate(dateTime: LocalDateTime): String {
|
||||
val pattern = if (dateTime.year != LocalDateTime.now().year) {
|
||||
"dd MMMM yyyy"
|
||||
} else {
|
||||
"dd MMMM"
|
||||
}
|
||||
|
||||
return DateTimeFormat.forPattern(pattern)
|
||||
.withLocale(Locale.getDefault())
|
||||
.print(dateTime)
|
||||
}
|
||||
}
|
|
@ -2,8 +2,8 @@ package com.readrops.api.localfeed.atom
|
|||
|
||||
import com.gitlab.mvysny.konsumexml.konsumeXml
|
||||
import com.readrops.api.TestUtils
|
||||
import com.readrops.api.utils.DateUtils
|
||||
import com.readrops.api.utils.exceptions.ParseException
|
||||
import com.readrops.db.util.DateUtils
|
||||
import junit.framework.TestCase
|
||||
import junit.framework.TestCase.assertEquals
|
||||
import org.junit.Assert.assertThrows
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
package com.readrops.api.localfeed.json
|
||||
|
||||
import com.readrops.api.TestUtils
|
||||
import com.readrops.api.utils.DateUtils
|
||||
import com.readrops.api.utils.exceptions.ParseException
|
||||
import com.readrops.db.entities.Feed
|
||||
import com.readrops.db.entities.Item
|
||||
import com.readrops.db.util.DateUtils
|
||||
import com.squareup.moshi.Moshi
|
||||
import com.squareup.moshi.Types
|
||||
import junit.framework.TestCase
|
||||
|
|
|
@ -2,8 +2,8 @@ package com.readrops.api.localfeed.rss1
|
|||
|
||||
import com.gitlab.mvysny.konsumexml.konsumeXml
|
||||
import com.readrops.api.TestUtils
|
||||
import com.readrops.api.utils.DateUtils
|
||||
import com.readrops.api.utils.exceptions.ParseException
|
||||
import com.readrops.db.util.DateUtils
|
||||
import junit.framework.Assert.assertEquals
|
||||
import junit.framework.Assert.assertNotNull
|
||||
import junit.framework.TestCase
|
||||
|
|
|
@ -2,8 +2,8 @@ package com.readrops.api.localfeed.rss2
|
|||
|
||||
import com.gitlab.mvysny.konsumexml.konsumeXml
|
||||
import com.readrops.api.TestUtils
|
||||
import com.readrops.api.utils.DateUtils
|
||||
import com.readrops.api.utils.exceptions.ParseException
|
||||
import com.readrops.db.util.DateUtils
|
||||
import junit.framework.TestCase
|
||||
import junit.framework.TestCase.assertEquals
|
||||
import junit.framework.TestCase.assertTrue
|
||||
|
|
|
@ -2,12 +2,12 @@ package com.readrops.api.services.freshrss.adapters
|
|||
|
||||
import com.readrops.api.TestUtils
|
||||
import com.readrops.db.entities.Item
|
||||
import com.readrops.db.util.DateUtils
|
||||
import com.squareup.moshi.Moshi
|
||||
import com.squareup.moshi.Types
|
||||
import junit.framework.TestCase.assertEquals
|
||||
import junit.framework.TestCase.assertNotNull
|
||||
import okio.Buffer
|
||||
import org.joda.time.LocalDateTime
|
||||
import org.junit.Test
|
||||
|
||||
class FreshRSSItemsAdapterTest {
|
||||
|
@ -29,7 +29,7 @@ class FreshRSSItemsAdapterTest {
|
|||
assertNotNull(content)
|
||||
assertEquals(link, "http://feedproxy.google.com/~r/d0od/~3/4Zk-fncSuek/adwaita-borderless-theme-in-development-gnome-41")
|
||||
assertEquals(author, "Joey Sneddon")
|
||||
assertEquals(pubDate, LocalDateTime(1625234040 * 1000L))
|
||||
assertEquals(pubDate, DateUtils.fromEpochSeconds(1625234040))
|
||||
assertEquals(isRead, false)
|
||||
assertEquals(isStarred, false)
|
||||
}
|
||||
|
|
|
@ -2,11 +2,11 @@ package com.readrops.api.services.nextcloudnews.adapters
|
|||
|
||||
import com.readrops.api.TestUtils
|
||||
import com.readrops.db.entities.Item
|
||||
import com.readrops.db.util.DateUtils
|
||||
import com.squareup.moshi.Moshi
|
||||
import com.squareup.moshi.Types
|
||||
import junit.framework.TestCase.assertEquals
|
||||
import okio.Buffer
|
||||
import org.joda.time.LocalDateTime
|
||||
import org.junit.Test
|
||||
|
||||
class NextcloudNewsItemsAdapterTest {
|
||||
|
@ -32,7 +32,7 @@ class NextcloudNewsItemsAdapterTest {
|
|||
assertEquals(feedRemoteId, "67")
|
||||
assertEquals(isRead, false)
|
||||
assertEquals(isStarred, false)
|
||||
assertEquals(pubDate, LocalDateTime(1367270544000))
|
||||
assertEquals(pubDate, DateUtils.fromEpochSeconds(1367270544))
|
||||
assertEquals(imageLink, null)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,58 +0,0 @@
|
|||
package com.readrops.api.utils;
|
||||
|
||||
import org.joda.time.LocalDateTime;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class DateUtilsTest {
|
||||
|
||||
@Test
|
||||
public void rssDateTest() {
|
||||
LocalDateTime dateTime = new LocalDateTime(2019, 1, 4, 22, 21, 46);
|
||||
|
||||
assertEquals(0, dateTime.compareTo(DateUtils.parse("Fri, 04 Jan 2019 22:21:46 GMT")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void rssDate2Test() {
|
||||
LocalDateTime dateTime = new LocalDateTime(2019, 1, 4, 22, 21, 46);
|
||||
|
||||
assertEquals(0, dateTime.compareTo(DateUtils.parse("Fri, 04 Jan 2019 22:21:46 +0000")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void rssDate3Test() {
|
||||
LocalDateTime dateTime = new LocalDateTime(2019, 1, 4, 22, 21, 46);
|
||||
|
||||
assertEquals(0, dateTime.compareTo(DateUtils.parse("Fri, 04 Jan 2019 22:21:46")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void atomJsonDateTest() {
|
||||
LocalDateTime dateTime = new LocalDateTime(2019, 1, 4, 22, 21, 46);
|
||||
|
||||
assertEquals(0, dateTime.compareTo(DateUtils.parse("2019-01-04T22:21:46+00:00")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void atomJsonDate2Test() {
|
||||
LocalDateTime dateTime = new LocalDateTime(2019, 1, 4, 22, 21, 46);
|
||||
|
||||
assertEquals(0, dateTime.compareTo(DateUtils.parse("2019-01-04T22:21:46-0000")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isoPatternTest() {
|
||||
LocalDateTime dateTime = new LocalDateTime(2020, 6, 30, 11, 39, 37, 206);
|
||||
|
||||
assertEquals(0, dateTime.compareTo(DateUtils.parse("2020-06-30T11:39:37.206-07:00")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void edtPatternTest() {
|
||||
LocalDateTime dateTime = new LocalDateTime(2020, 7, 17, 16, 30, 0);
|
||||
|
||||
assertEquals(0, dateTime.compareTo(DateUtils.parse("Fri, 17 Jul 2020 16:30:00 EDT")));
|
||||
}
|
||||
}
|
|
@ -61,7 +61,6 @@ dependencies {
|
|||
implementation(libs.browser)
|
||||
|
||||
implementation(libs.jsoup)
|
||||
implementation(libs.jodatime)
|
||||
|
||||
testImplementation(libs.junit4)
|
||||
androidTestImplementation(libs.bundles.test)
|
||||
|
|
|
@ -13,7 +13,7 @@ import com.readrops.db.entities.account.AccountType
|
|||
import com.readrops.db.filters.MainFilter
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.joda.time.LocalDateTime
|
||||
import java.time.LocalDateTime
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import kotlin.test.assertTrue
|
||||
|
|
|
@ -12,7 +12,7 @@ import com.readrops.db.entities.Item
|
|||
import com.readrops.db.entities.account.Account
|
||||
import com.readrops.db.entities.account.AccountType
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.joda.time.LocalDateTime
|
||||
import java.time.LocalDateTime
|
||||
import org.junit.After
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertTrue
|
||||
|
|
|
@ -52,7 +52,6 @@ import androidx.core.view.children
|
|||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import cafe.adriel.voyager.koin.getScreenModel
|
||||
import coil.compose.AsyncImage
|
||||
import com.readrops.api.utils.DateUtils
|
||||
import com.readrops.app.R
|
||||
import com.readrops.app.item.view.ItemNestedScrollView
|
||||
import com.readrops.app.item.view.ItemWebView
|
||||
|
@ -63,6 +62,7 @@ import com.readrops.app.util.theme.MediumSpacer
|
|||
import com.readrops.app.util.theme.ShortSpacer
|
||||
import com.readrops.app.util.theme.spacing
|
||||
import com.readrops.db.pojo.ItemWithFeed
|
||||
import com.readrops.db.util.DateUtils
|
||||
import org.koin.core.parameter.parametersOf
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
|
|
|
@ -12,7 +12,6 @@ import com.readrops.db.entities.Folder
|
|||
import com.readrops.db.entities.Item
|
||||
import com.readrops.db.entities.ItemState
|
||||
import com.readrops.db.entities.account.Account
|
||||
import org.joda.time.DateTime
|
||||
import org.koin.core.component.KoinComponent
|
||||
|
||||
class FreshRSSRepository(
|
||||
|
@ -63,7 +62,7 @@ class FreshRSSRepository(
|
|||
syncType = SyncType.INITIAL_SYNC
|
||||
}
|
||||
|
||||
val newLastModified = DateTime.now().millis / 1000L
|
||||
val newLastModified = System.currentTimeMillis() / 1000L
|
||||
|
||||
return dataSource.synchronize(syncType, syncData, account.writeToken!!).run {
|
||||
insertFolders(folders)
|
||||
|
|
|
@ -16,7 +16,6 @@ import kotlinx.coroutines.Dispatchers
|
|||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.awaitAll
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.joda.time.DateTime
|
||||
import org.koin.core.component.KoinComponent
|
||||
import org.koin.core.component.get
|
||||
|
||||
|
@ -63,7 +62,7 @@ class NextcloudNewsRepository(
|
|||
SyncType.INITIAL_SYNC
|
||||
}
|
||||
|
||||
val newLastModified = DateTime.now().millis / 1000L
|
||||
val newLastModified = System.currentTimeMillis() / 1000L
|
||||
|
||||
return dataSource.synchronize(syncType, syncData).run {
|
||||
insertFolders(folders)
|
||||
|
@ -163,7 +162,6 @@ class NextcloudNewsRepository(
|
|||
itemsFeedsIds[item.feedRemoteId] = feedId
|
||||
}
|
||||
|
||||
// TODO itemExists request isn't the right one for this case
|
||||
if (!initialSync && feedId > 0 && database.itemDao().itemExists(item.remoteId!!, feedId)) {
|
||||
database.itemDao()
|
||||
.updateReadAndStarState(item.remoteId!!, item.isRead, item.isStarred)
|
||||
|
|
|
@ -6,7 +6,7 @@ import com.readrops.app.util.DefaultPreview
|
|||
import com.readrops.app.util.theme.ReadropsTheme
|
||||
import com.readrops.db.entities.Folder
|
||||
import com.readrops.db.pojo.ItemWithFeed
|
||||
import org.joda.time.LocalDateTime
|
||||
import java.time.LocalDateTime
|
||||
|
||||
enum class TimelineItemSize {
|
||||
COMPACT,
|
||||
|
|
|
@ -34,13 +34,13 @@ import androidx.compose.ui.text.style.TextOverflow
|
|||
import androidx.compose.ui.unit.dp
|
||||
import coil.compose.AsyncImage
|
||||
import coil.request.ImageRequest
|
||||
import com.readrops.api.utils.DateUtils
|
||||
import com.readrops.app.R
|
||||
import com.readrops.app.util.components.FeedIcon
|
||||
import com.readrops.app.util.theme.ShortSpacer
|
||||
import com.readrops.app.util.theme.spacing
|
||||
import com.readrops.db.pojo.ItemWithFeed
|
||||
import org.joda.time.LocalDateTime
|
||||
import com.readrops.db.util.DateUtils
|
||||
import java.time.LocalDateTime
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
@Composable
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
package com.readrops.app
|
||||
|
||||
import com.readrops.db.util.DateUtils
|
||||
import junit.framework.TestCase.assertEquals
|
||||
import org.junit.Test
|
||||
import java.time.LocalDateTime
|
||||
|
||||
class DateUtilsTest {
|
||||
|
||||
@Test
|
||||
fun rssDateTest() {
|
||||
val dateTime = LocalDateTime.of(2019, 1, 4, 22, 21, 46)
|
||||
assertEquals(0, dateTime.compareTo(DateUtils.parse("Fri, 04 Jan 2019 22:21:46 GMT")))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun rssDate2Test() {
|
||||
val dateTime = LocalDateTime.of(2019, 1, 4, 22, 21, 46)
|
||||
assertEquals(0, dateTime.compareTo(DateUtils.parse("Fri, 04 Jan 2019 22:21:46 +0000")))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun rssDate3Test() {
|
||||
val dateTime = LocalDateTime.of(2019, 1, 4, 22, 21, 46)
|
||||
assertEquals(0, dateTime.compareTo(DateUtils.parse("Fri, 04 Jan 2019 22:21:46")))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun edtPatternTest() {
|
||||
val dateTime = LocalDateTime.of(2020, 7, 17, 16, 30, 0)
|
||||
assertEquals(0, dateTime.compareTo(DateUtils.parse("Fri, 17 Jul 2020 16:30:00 EDT")))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun atomJsonDateTest() {
|
||||
val dateTime = LocalDateTime.of(2019, 1, 4, 22, 21, 46)
|
||||
assertEquals(0, dateTime.compareTo(DateUtils.parse("2019-01-04T22:21:46+00:00")))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun atomJsonDate2Test() {
|
||||
val dateTime = LocalDateTime.of(2019, 1, 4, 22, 21, 46)
|
||||
assertEquals(0, dateTime.compareTo(DateUtils.parse("2019-01-04T22:21:46-0000")))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isoPatternTest() {
|
||||
val dateTime = LocalDateTime.of(2020, 6, 30, 11, 39, 37, 206000000)
|
||||
assertEquals(0, dateTime.compareTo(DateUtils.parse("2020-06-30T11:39:37.206-07:00")))
|
||||
}
|
||||
}
|
|
@ -42,8 +42,6 @@ dependencies {
|
|||
|
||||
implementation(libs.bundles.paging)
|
||||
|
||||
implementation(libs.jodatime)
|
||||
|
||||
implementation(libs.bundles.koin)
|
||||
testImplementation(libs.bundles.kointest)
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ import com.readrops.db.entities.Item
|
|||
import com.readrops.db.entities.ItemState
|
||||
import com.readrops.db.entities.ItemStateChange
|
||||
import com.readrops.db.entities.account.Account
|
||||
import com.readrops.db.util.Converters
|
||||
|
||||
@Database(
|
||||
entities = [Feed::class, Item::class, Folder::class, Account::class,
|
||||
|
|
|
@ -5,7 +5,7 @@ import androidx.room.Entity
|
|||
import androidx.room.ForeignKey
|
||||
import androidx.room.Ignore
|
||||
import androidx.room.PrimaryKey
|
||||
import org.joda.time.LocalDateTime
|
||||
import java.time.LocalDateTime
|
||||
|
||||
@Entity(
|
||||
foreignKeys = [
|
||||
|
|
|
@ -1,24 +1,24 @@
|
|||
package com.readrops.db
|
||||
package com.readrops.db.util
|
||||
|
||||
import androidx.room.TypeConverter
|
||||
import com.readrops.db.entities.account.AccountType
|
||||
import org.joda.time.LocalDateTime
|
||||
import java.time.LocalDateTime
|
||||
|
||||
class Converters {
|
||||
|
||||
@TypeConverter
|
||||
fun fromTimeStamp(value: Long): LocalDateTime {
|
||||
return LocalDateTime(value)
|
||||
return DateUtils.fromEpochSeconds(value / 1000L)
|
||||
}
|
||||
|
||||
@TypeConverter
|
||||
fun fromLocalDateTime(localDateTime: LocalDateTime): Long {
|
||||
return localDateTime.toDateTime().millis
|
||||
return localDateTime.toInstant(DateUtils.defaultOffset).toEpochMilli()
|
||||
}
|
||||
|
||||
@TypeConverter
|
||||
fun fromAccountTypeCode(ordinal: Int): AccountType {
|
||||
return AccountType.values()[ordinal]
|
||||
return AccountType.entries[ordinal]
|
||||
}
|
||||
|
||||
@TypeConverter
|
|
@ -0,0 +1,102 @@
|
|||
package com.readrops.db.util
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.util.Log
|
||||
import java.time.LocalDateTime
|
||||
import java.time.OffsetDateTime
|
||||
import java.time.ZoneOffset
|
||||
import java.time.format.DateTimeFormatter
|
||||
import java.time.format.DateTimeFormatterBuilder
|
||||
import java.time.format.FormatStyle
|
||||
import java.util.Locale
|
||||
import java.util.TimeZone
|
||||
|
||||
object DateUtils {
|
||||
|
||||
private val TAG = DateUtils::class.java.simpleName
|
||||
|
||||
/**
|
||||
* Base of common RSS 2 date formats.
|
||||
* Examples :
|
||||
* Fri, 04 Jan 2019 22:21:46 GMT
|
||||
* Fri, 04 Jan 2019 22:21:46 +0000
|
||||
*/
|
||||
private const val RSS_2_BASE_PATTERN = "EEE, dd MMM yyyy HH:mm:ss"
|
||||
|
||||
private const val GMT_PATTERN = "ZZZ"
|
||||
|
||||
private const val OFFSET_PATTERN = "Z"
|
||||
|
||||
private const val ISO_PATTERN = ".SSSZZ"
|
||||
|
||||
private const val EDT_PATTERN = "zzz"
|
||||
|
||||
private const val ZONE_OFFSET_PATTERN = ".SSSxxx"
|
||||
|
||||
/**
|
||||
* Date pattern for format : 2019-01-04T22:21:46+00:00
|
||||
*/
|
||||
private const val ATOM_JSON_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss"
|
||||
|
||||
val defaultOffset: ZoneOffset
|
||||
get() = OffsetDateTime.now(TimeZone.getDefault().toZoneId())
|
||||
.offset
|
||||
|
||||
/**
|
||||
* Attempts to parse a date string representation.
|
||||
* If the provided value is null or the parsing fails, [LocalDateTime.now] is returned.
|
||||
* @return parsed date or [LocalDateTime.now]
|
||||
*/
|
||||
@SuppressLint("NewApi") // works with API 21+ so the lint might be buggy
|
||||
@JvmStatic
|
||||
fun parse(value: String?): LocalDateTime {
|
||||
return if (value == null) {
|
||||
LocalDateTime.now()
|
||||
} else try {
|
||||
val formatter = DateTimeFormatterBuilder()
|
||||
.appendOptional(DateTimeFormatter.ofPattern("$RSS_2_BASE_PATTERN ")) // with timezone
|
||||
.appendOptional(DateTimeFormatter.ofPattern(RSS_2_BASE_PATTERN)) // no timezone, important order here
|
||||
.appendOptional(DateTimeFormatter.ofPattern(ATOM_JSON_DATE_FORMAT))
|
||||
.appendOptional(DateTimeFormatter.ofPattern(EDT_PATTERN))
|
||||
.appendOptional(DateTimeFormatter.ofPattern(ZONE_OFFSET_PATTERN))
|
||||
.appendOptional(DateTimeFormatter.ofPattern(GMT_PATTERN))
|
||||
.appendOptional(DateTimeFormatter.ofPattern(OFFSET_PATTERN))
|
||||
.appendOptional(DateTimeFormatter.ofPattern(ISO_PATTERN))
|
||||
.toFormatter()
|
||||
.withLocale(Locale.ENGLISH)
|
||||
|
||||
LocalDateTime.from(formatter.parse(value))
|
||||
} catch (e: Exception) {
|
||||
Log.d(TAG, "Unable to parse $value: ${e.message}")
|
||||
LocalDateTime.now()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Be aware of giving a second epoch value and not a millisecond one!
|
||||
*/
|
||||
fun fromEpochSeconds(epoch: Long): LocalDateTime {
|
||||
return LocalDateTime.ofEpochSecond(
|
||||
epoch,
|
||||
0,
|
||||
defaultOffset
|
||||
)
|
||||
}
|
||||
|
||||
fun formattedDateByLocal(dateTime: LocalDateTime): String {
|
||||
return DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM)
|
||||
.withLocale(Locale.getDefault())
|
||||
.format(dateTime)
|
||||
}
|
||||
|
||||
fun formattedDate(dateTime: LocalDateTime): String {
|
||||
val pattern = if (dateTime.year != LocalDateTime.now().year) {
|
||||
"dd MMMM yyyy"
|
||||
} else {
|
||||
"dd MMMM"
|
||||
}
|
||||
|
||||
return DateTimeFormatter.ofPattern(pattern)
|
||||
.format(dateTime)
|
||||
}
|
||||
}
|
|
@ -82,11 +82,10 @@ aboutlibraries-composem3 = { module = "com.mikepenz:aboutlibraries-compose-m3",
|
|||
konsumexml = "com.gitlab.mvysny.konsume-xml:konsume-xml:1.1"
|
||||
kotlinxmlbuilder = "org.redundent:kotlin-xml-builder:1.7.3" #TODO update this
|
||||
|
||||
jdk-desugar = "com.android.tools:desugar_jdk_libs:2.0.4"
|
||||
jdk-desugar = "com.android.tools:desugar_jdk_libs_nio:2.0.4"
|
||||
|
||||
jsoup = "org.jsoup:jsoup:1.16.1"
|
||||
moshi = "com.squareup.moshi:moshi:1.15.1"
|
||||
jodatime = "joda-time:joda-time:2.10.10" #TODO replace by java.time
|
||||
|
||||
# androidx
|
||||
corektx = "androidx.core:core-ktx:1.13.1"
|
||||
|
|
Loading…
Reference in New Issue