Skip to content

Commit

Permalink
fix timestamp format (#204)
Browse files Browse the repository at this point in the history
* fix date format issue

* fix unit tests
  • Loading branch information
wenxi-zeng authored Nov 30, 2023
1 parent 2be4602 commit fb1cde4
Show file tree
Hide file tree
Showing 8 changed files with 57 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import com.segment.analytics.kotlin.core.TrackEvent
import com.segment.analytics.kotlin.core.emptyJsonObject
import com.segment.analytics.kotlin.core.utilities.EncodeDefaultsJson
import com.segment.analytics.kotlin.core.utilities.EventsFileManager
import com.segment.analytics.kotlin.core.utilities.dateTimeNowString
import com.segment.analytics.kotlin.core.utilities.SegmentInstant
import io.mockk.every
import io.mockk.mockkStatic
import io.mockk.mockkObject
import kotlinx.coroutines.test.runTest
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.buildJsonObject
Expand All @@ -32,10 +32,8 @@ class EventsFileTests {
private val directory = File("/tmp/analytics-android-test/")

init {
mockkStatic(Instant::class)
mockkStatic(::dateTimeNowString)
every { dateTimeNowString() } returns Date(0).toInstant().toString()
every { Instant.now() } returns Date(0).toInstant()
mockkObject(SegmentInstant)
every { SegmentInstant.now() } returns Date(0).toInstant().toString()
}

@BeforeEach
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.segment.analytics.kotlin.core

import com.segment.analytics.kotlin.core.utilities.dateTimeNowString
import com.segment.analytics.kotlin.core.utilities.SegmentInstant
import kotlinx.serialization.DeserializationStrategy
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
Expand Down Expand Up @@ -80,7 +80,7 @@ sealed class BaseEvent {
}

internal fun applyBaseData() {
this.timestamp = dateTimeNowString()
this.timestamp = SegmentInstant.now()
this.context = emptyJsonObject
this.messageId = UUID.randomUUID().toString()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,34 @@ package com.segment.analytics.kotlin.core.utilities
import java.text.SimpleDateFormat
import java.util.*

/**
* This function is a replacement for Instant.now().toString(). It produces strings in a
* compatible format.
*
* Ex:
* Instant.now(): 2023-04-19T04:03:46.880969Z
* dateTimeNowString(): 2023-04-19T04:03:46.880Z
*/
fun dateTimeNowString(): String {
object SegmentInstant {

// Note, we should specify locale = Locale.ROOT, otherwise the timestamp returned will use
// the default locale, which may not be what we want.
val sdf = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'.'Szzz", Locale.ROOT)
val utc = TimeZone.getTimeZone("UTC");
sdf.timeZone = utc;
return sdf.format(Date()).replace("UTC", "Z")
private val formatter: SimpleDateFormat =
SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'.'SSSzzz", Locale.ROOT).apply {
timeZone = TimeZone.getTimeZone("UTC")
}

/**
* This function is a replacement for Instant.now().toString(). It produces strings in a
* compatible format.
*
* Ex:
* Instant.now(): 2023-04-19T04:03:46.880969Z
* dateTimeNowString(): 2023-04-19T04:03:46.880Z
*/
fun now(): String {
return from(Date())
}

internal fun from(date: Date): String {
// internal use only. for testing purpose.
return formatter.format(date).replace("UTC", "Z")
}
}

@Deprecated("Please use SegmentInstant.now() instead", ReplaceWith("SegmentInstant.now()"))
fun dateTimeNowString(): String {
return SegmentInstant.now()
}
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ class EventsFileManager(
// close events array and batch object


val contents = """],"sentAt":"${dateTimeNowString()}","writeKey":"$writeKey"}"""
val contents = """],"sentAt":"${SegmentInstant.now()}","writeKey":"$writeKey"}"""
writeToFile(contents.toByteArray(), file)
file.renameTo(File(directory, file.nameWithoutExtension))
os?.close()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import com.segment.analytics.kotlin.core.platform.DestinationPlugin
import com.segment.analytics.kotlin.core.platform.Plugin
import com.segment.analytics.kotlin.core.platform.plugins.ContextPlugin
import com.segment.analytics.kotlin.core.platform.plugins.SegmentDestination
import com.segment.analytics.kotlin.core.utilities.dateTimeNowString
import com.segment.analytics.kotlin.core.utilities.SegmentInstant
import com.segment.analytics.kotlin.core.utils.StubPlugin
import com.segment.analytics.kotlin.core.utils.TestRunPlugin
import com.segment.analytics.kotlin.core.utils.clearPersistentStorage
Expand All @@ -28,7 +28,6 @@ import org.junit.jupiter.api.TestInstance
import org.junit.jupiter.api.assertThrows
import java.io.ByteArrayInputStream
import java.net.HttpURLConnection
import java.time.Instant
import java.util.Date
import java.util.UUID

Expand All @@ -50,10 +49,8 @@ class AnalyticsTests {
private val testScope = TestScope(testDispatcher)

init {
mockkStatic(Instant::class)
every { Instant.now() } returns Date(0).toInstant()
mockkStatic(::dateTimeNowString)
every { dateTimeNowString() } returns Date(0).toInstant().toString()
mockkObject(SegmentInstant)
every { SegmentInstant.now() } returns Date(0).toInstant().toString()
mockkStatic(UUID::class)
every { UUID.randomUUID().toString() } returns "qwerty-qwerty-123"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import com.segment.analytics.kotlin.core.platform.DestinationPlugin
import com.segment.analytics.kotlin.core.platform.Plugin
import com.segment.analytics.kotlin.core.platform.plugins.ContextPlugin
import com.segment.analytics.kotlin.core.platform.plugins.SegmentDestination
import com.segment.analytics.kotlin.core.utilities.dateTimeNowString
import com.segment.analytics.kotlin.core.utilities.SegmentInstant
import com.segment.analytics.kotlin.core.utils.StubPlugin
import com.segment.analytics.kotlin.core.utils.TestRunPlugin
import com.segment.analytics.kotlin.core.utils.mockHTTPClient
Expand All @@ -21,7 +21,6 @@ import org.junit.jupiter.api.Assertions.*
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Nested
import org.junit.jupiter.api.Test
import java.time.Instant
import java.util.*
import java.util.function.Consumer

Expand All @@ -43,10 +42,8 @@ internal class JavaAnalyticsTest {
private val testScope = TestScope(testDispatcher)

init {
mockkStatic(Instant::class)
every { Instant.now() } returns Date(0).toInstant()
mockkStatic(::dateTimeNowString)
every { dateTimeNowString() } returns Date(0).toInstant().toString()
mockkObject(SegmentInstant)
every { SegmentInstant.now() } returns Date(0).toInstant().toString()
mockkStatic(UUID::class)
every { UUID.randomUUID().toString() } returns "qwerty-qwerty-123"
mockHTTPClient()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,27 @@
package com.segment.analytics.kotlin.core.utilities

import io.mockk.every
import io.mockk.mockkConstructor
import io.mockk.mockkObject
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.assertNotNull
import org.junit.jupiter.api.Test
import java.time.format.DateTimeFormatter.ISO_DATE_TIME
import java.util.*

class DateTimeUtilsTest {

@Test
fun `dateTimeNowString() produces a string in the correct ISO8601 format`() {
val dateTimeNowString = dateTimeNowString()
val dateTimeNowString = SegmentInstant.now()
val date = ISO_DATE_TIME.parse(dateTimeNowString)
assertNotNull(date)
}

@Test
fun `dateTimeNowString() returns three digit seconds`() {
val date = Date(1700617928023L)
val dateTimeNowString = SegmentInstant.from(date)
assertEquals("2023-11-22T01:52:08.023Z", dateTimeNowString)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.segment.analytics.kotlin.core.utilities
import com.segment.analytics.kotlin.core.TrackEvent
import com.segment.analytics.kotlin.core.emptyJsonObject
import io.mockk.every
import io.mockk.mockkObject
import io.mockk.mockkStatic
import kotlinx.coroutines.test.runTest
import kotlinx.serialization.encodeToString
Expand All @@ -24,11 +25,8 @@ internal class EventsFileManagerTest{
private val kvStore = PropertiesFile(directory.parentFile, "123")

init {
mockkStatic(Instant::class)
every { Instant.now() } returns Date(0).toInstant()

mockkStatic(::dateTimeNowString)
every { dateTimeNowString() } returns Date(0).toInstant().toString()
mockkObject(SegmentInstant)
every { SegmentInstant.now() } returns Date(0).toInstant().toString()
}

@BeforeEach
Expand Down

0 comments on commit fb1cde4

Please sign in to comment.