Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Get time difference in milliseconds between JVM and UTC

I am having an exceedingly hard time trying to figure out what seems to be a simple problem.

I would like to calculate the difference (offset?) in milliseconds between the UTC instant and the JVM instant (i.e. specific to the machine running the code).

I have tried the following initializations (sorry, this is in Kotlin, not Java):

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

// 1
val difference = TimeZone.getDefault().getOffset(System.currentTimeMillis())

// 2
val difference = ZoneId.systemDefault().rules.getOffset(Instant.EPOCH).totalSeconds * 1000

// 3
val difference = ZonedDateTime.now(ZoneId.systemDefault()).offset.totalSeconds * 1000

To be more specific: I am running this on my Mac on the US west coast today (Feb 22, 2024 — i.e. during Daylight Savings). All 3 initializations produce -28800000 (i.e. timezone-based) when I am looking for an initialization that will produce -25200000 (i.e. DST-sensitive / instant-based).

What am I doing wrong here?

I would like the solution to be timezone/machine agnostic (i.e. I could run this code on any machine around the world without any specific input like a string timezone).

EDIT:

As @Louis Wasserman pointed out, my expectation that the initializations would produce -25200000 is incorrect as the current time difference is in fact -28800000.

My incorrect expectation is due to the fact I had written the following test:

@Test
fun timeStrToEpochMillis_invariantValidation_happyPaths() {
    // Arrange
    val testTimeStr = "2023-06-13 20:21:46"

    // Act
    val result = timeStrToEpochMillis(testTimeStr)

    // Assert
    assertEquals(1686687706000, result)
}

For the below function:

fun timeStrToEpochMillis(timeStr: String): Long {
    val df = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
    return df.parse(timeStr).time
}

When I ran the above test in a container, whose default time zone is UTC, the test would pass. However, when running the above test on my local machine, whose default time zone is Pacific, the test would fail.

I overlooked that the difference ought to be based on the test string, like so:

@Test
fun timeStrToEpochMillis_invariantValidation_happyPaths() {
    // Arrange
    val testTimeStr = "2023-06-13 20:21:46"

    // Act
    val result = timeStrToEpochMillis(testTimeStr)
    val diff = TimeZone.getDefault().getOffset(result)

    // Assert
    assertEquals(1686687706000 + diff, result)
}

Thanks again to @Louis Wasserman for pointing out the obvious.

>Solution :

It is not currently Daylight Savings Time on the US West Coast. The time zone America/Los_Angeles, used by the US West Coast, is currently 28800000 milliseconds from UTC.

The JVM is correct here.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading