Skip to content

Commit 8c4727e

Browse files
authored
Add implicit conversions from java.time classes to plotly LocalDateTime (#178)
1 parent edccb20 commit 8c4727e

File tree

4 files changed

+90
-1
lines changed

4 files changed

+90
-1
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package plotly.element
2+
3+
trait PlotlyJavaTimeConversions {
4+
// Empty since the java.time classes are not available in ScalaJS
5+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package plotly.element
2+
3+
import java.time._
4+
import plotly.element.{LocalDateTime => PlotlyLocalDateTime}
5+
6+
trait PlotlyJavaTimeConversions {
7+
8+
implicit def fromJavaLocalDateTime(javaLocalDateTime: java.time.LocalDateTime): PlotlyLocalDateTime =
9+
PlotlyLocalDateTime(
10+
javaLocalDateTime.getYear,
11+
javaLocalDateTime.getMonthValue,
12+
javaLocalDateTime.getDayOfMonth,
13+
javaLocalDateTime.getHour,
14+
javaLocalDateTime.getMinute,
15+
javaLocalDateTime.getSecond,
16+
)
17+
18+
implicit def fromJavaInstant(javaInstant: Instant): PlotlyLocalDateTime =
19+
fromJavaLocalDateTime(javaInstant.atOffset(ZoneOffset.UTC).toLocalDateTime)
20+
21+
implicit def fromJavaLocalDate(javaLocalDate: LocalDate): PlotlyLocalDateTime =
22+
fromJavaLocalDateTime(javaLocalDate.atStartOfDay)
23+
24+
/**
25+
* Implicit conversions in this object convert to `plotly.element.LocalDateTime` by simply dropping timezone/offset
26+
* information. This can lead to unexpected behaviour, particularly for datasets with varying offsets and timezones.
27+
* It will generally be safer to convert your data to `java.time.LocalDateTime` in the appropriate timezone/offset,
28+
* and then use the `PlotlyJavaTimeConversions.fromJavaLocalDateTime` implicit conversion.
29+
*/
30+
object UnsafeImplicitConversions {
31+
32+
implicit def fromJavaOffsetDateTime(javaOffsetDateTime: OffsetDateTime): PlotlyLocalDateTime =
33+
fromJavaLocalDateTime(javaOffsetDateTime.toLocalDateTime)
34+
35+
implicit def fromJavaZonedDateTime(javaZonedDateTime: ZonedDateTime): PlotlyLocalDateTime =
36+
fromJavaLocalDateTime(javaZonedDateTime.toLocalDateTime)
37+
38+
}
39+
40+
}

core/shared/src/main/scala/plotly/element/LocalDateTime.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import scala.util.Try
1616
f"$year-$month%02d-$dayOfMonth%02d $hour%02d:$minute%02d:$second%02d"
1717
}
1818

19-
object LocalDateTime {
19+
object LocalDateTime extends PlotlyJavaTimeConversions {
2020

2121
private object IntStr {
2222
def unapply(s: String): Option[Int] =
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package plotly.element
2+
3+
import org.scalatest.FlatSpec
4+
import plotly.element.LocalDateTime.UnsafeImplicitConversions._
5+
import plotly.element.{LocalDateTime => PlotlyLocalDateTime}
6+
7+
class LocalDateTimeTests extends FlatSpec {
8+
9+
"JavaTime conversions" should "convert java.time.LocalDateTime to Plotly LocalDateTime" in {
10+
val javaLocalDateTime = java.time.LocalDateTime.parse("2020-04-18T14:52:52")
11+
val plotlyLocalDateTime = PlotlyLocalDateTime(2020, 4, 18, 14, 52, 52)
12+
13+
assert((javaLocalDateTime: PlotlyLocalDateTime) === plotlyLocalDateTime)
14+
}
15+
16+
it should "convert java.time.Instant to Plotly LocalDateTime using UTC" in {
17+
val javaInstant = java.time.Instant.parse("2020-04-18T14:52:52Z")
18+
val plotlyLocalDateTime = PlotlyLocalDateTime(2020, 4, 18, 14, 52, 52)
19+
20+
assert((javaInstant: PlotlyLocalDateTime) === plotlyLocalDateTime)
21+
}
22+
23+
it should "convert java.time.OffsetDateTime to Plotly LocalDateTime" in {
24+
val javaOffsetDateTime = java.time.OffsetDateTime.parse("2020-04-18T14:52:52+10:00")
25+
val plotlyLocalDateTime = PlotlyLocalDateTime(2020, 4, 18, 14, 52, 52)
26+
27+
assert((javaOffsetDateTime: PlotlyLocalDateTime) === plotlyLocalDateTime)
28+
}
29+
30+
it should "convert java.time.ZonedDateTime to Plotly LocalDateTime" in {
31+
val javaOffsetDateTime = java.time.ZonedDateTime.parse("2020-04-18T14:52:52+10:00[Australia/Melbourne]")
32+
val plotlyLocalDateTime = PlotlyLocalDateTime(2020, 4, 18, 14, 52, 52)
33+
34+
assert((javaOffsetDateTime: PlotlyLocalDateTime) === plotlyLocalDateTime)
35+
}
36+
37+
it should "convert java.time.LocalDate to Plotly LocalDateTime" in {
38+
val javaLocalDate = java.time.LocalDate.parse("2020-04-18")
39+
val plotlyLocalDateTime = PlotlyLocalDateTime(2020, 4, 18, 0, 0, 0)
40+
41+
assert((javaLocalDate: PlotlyLocalDateTime) === plotlyLocalDateTime)
42+
}
43+
44+
}

0 commit comments

Comments
 (0)