Skip to content

Instantly share code, notes, and snippets.

@nimatrueway
Last active August 4, 2020 14:50
Show Gist options
  • Save nimatrueway/ac74e0f6efd2b25396a872633e859121 to your computer and use it in GitHub Desktop.
Save nimatrueway/ac74e0f6efd2b25396a872633e859121 to your computer and use it in GitHub Desktop.
Runtime's session timezone possible problem
package classloaders
import java.time._
import java.util.TimeZone
import java.util.concurrent.TimeUnit
import scala.concurrent.duration.Duration
object Main {
private val dt = LocalDateTime.of(1900, 1, 2, 3, 4, 5)
def main(args: Array[String]): Unit = {
pprint(dt.atZone(ZoneOffset.UTC))
pprint(dt.atZone(ZoneId.systemDefault()))
pprint(dt.atZone(ZoneId.of("GMT+02:00")))
pprint(dt.atZone(simulateRuntime("GMT+02:00"))) // this is expected to yield the same result as the former
}
private def pprint(time: Any): Unit = {
def diff(instant: Instant): String = {
((instant.toEpochMilli / 1000) - (dt.atZone(ZoneOffset.UTC).toInstant.toEpochMilli / 1000)).toString
}
println(time match {
case zdt: ZonedDateTime => s"[${diff(zdt.toInstant)}] $zdt"
case instant: Instant => s"[${diff(instant)}] $instant"
})
}
private def simulateRuntime(zoneId: String): ZoneId = {
val originalTimeZone = TimeZone.getTimeZone(zoneId)
val session = new RuntimeSession()
session.setTimeZone(getJavascriptDatetimeOffset(originalTimeZone))
session.getTimeZone.toZoneId
}
class RuntimeSession { // What we do in runtime
var timeZone: TimeZone = _
def getTimeZone: TimeZone = timeZone
def setTimeZone(offset: Int): Unit = timeZone = calculateTimeZone(offset)
def calculateTimeZone(timezoneOffset: Int): TimeZone = {
val zone = TimeZone.getTimeZone("UTC")
zone.setRawOffset(timezoneOffset * -1 * 60 * 1000) //Javascript returns timezone offset in negative minutes (so -120 for UTC+2)
val roundedOffsetInHours = Math.round(timezoneOffset / 60f * -1)
zone.setID("Etc/GMT" + (if (roundedOffsetInHours < 0) roundedOffsetInHours else "+" + roundedOffsetInHours))
// the problem gets solved if we change "Etc/GMT" to "GMT"
zone
}
}
def getJavascriptDatetimeOffset(timeZone: TimeZone): Int = {
// scale it to javascript's timezone offset (see javascript's )
// (e.g. javascript "new Date().getTimezoneOffset()" returns -120 for CET)
timeZone.getRawOffset / (-1 * 60 * 1000)
}
}
[0] 1900-01-02T03:04:05Z
[-1172] 1900-01-02T03:04:05+00:19:32[Europe/Amsterdam]
[-7200] 1900-01-02T03:04:05+02:00[GMT+02:00]
[7200] 1900-01-02T03:04:05-02:00[Etc/GMT+2] // why the zone offset here is -02:00 ?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment