1+ package frontendContextDemo.scripts
2+
3+ import frontendContextDemo.ScriptInBatikContext
4+ import org.jetbrains.letsPlot.geom.geomLine
5+ import org.jetbrains.letsPlot.letsPlot
6+ import org.jetbrains.letsPlot.scale.xlim
7+ import java.time.Instant
8+ import java.time.ZoneId
9+ import java.time.ZonedDateTime
10+ import kotlin.math.cos
11+ import kotlin.math.sin
12+
13+ @Suppress(" ClassName" )
14+ object Issue_xlim_breaks_datetime_LP1348 {
15+ @JvmStatic
16+ fun main (args : Array <String >) {
17+ ScriptInBatikContext .eval(" Issue: xlim breaks datetime LP-1348" ) {
18+
19+ fun squiggle (x : Double ): Double {
20+ return sin(3 * x) / (x * (cos(x) + 2 ))
21+ }
22+
23+ val N = 50
24+ val xs = (0 until N ).map { i -> 1.0 + (25.0 - 1.0 ) * i / (N - 1 ) }
25+ val ys = xs.map { squiggle(it) }
26+
27+ // Berlin DST transition: March 30, 2025 at 2:00 AM
28+ // Cover ±3 days: March 27 - April 2, 2025 (6 days total)
29+
30+ // Generate equally spaced UNIX timestamps (in seconds)
31+
32+ val startTimestamp = ZonedDateTime .of(2025 , 3 , 27 , 0 , 0 , 0 , 0 , ZoneId .of(" UTC" )).toEpochSecond()
33+ val endTimestamp = ZonedDateTime .of(2025 , 4 , 2 , 23 , 59 , 0 , 0 , ZoneId .of(" UTC" )).toEpochSecond()
34+ val unixTimestamps = (0 until N ).map { i ->
35+ startTimestamp + (endTimestamp - startTimestamp) * i / (N - 1 )
36+ }
37+
38+ // Convert to ZonedDateTime with Berlin timezone
39+ val xsDatetime = unixTimestamps.map { timestamp ->
40+ Instant .ofEpochSecond(timestamp).atZone(ZoneId .of(" Europe/Berlin" ))
41+ }
42+
43+ val data = mapOf (
44+ " xs" to xsDatetime,
45+ " ys" to ys
46+ )
47+
48+ val p = letsPlot(data = data) { x = " xs" ; y = " ys" } +
49+ geomLine(
50+ color = " #1380A1" ,
51+ size = 2
52+ // )
53+ ) +
54+ xlim(
55+ ZonedDateTime .of(2025 , 3 , 29 , 23 , 0 , 0 , 0 , ZoneId .of(" Europe/Berlin" )) to
56+ ZonedDateTime .of(2025 , 3 , 30 , 8 , 0 , 0 , 0 , ZoneId .of(" Europe/Berlin" )),
57+ )
58+
59+ p.show()
60+
61+ }
62+ }
63+ }
0 commit comments